summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 16:07:07 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 16:07:07 +0000
commit8ab086b6cc054501bfbf7ef6fa509c393691e860 (patch)
tree324d51845d7f1a2f4e02a14db22fb5947137c822 /vcl
parent411e68cc54ae97eebd79ae3a9cb2971b74cb2a9e (diff)
initial import
Diffstat (limited to 'vcl')
-rw-r--r--vcl/aqua/inc/saldata.hxx362
-rw-r--r--vcl/aqua/inc/salframe.h118
-rw-r--r--vcl/aqua/inc/salgdi.h138
-rw-r--r--vcl/aqua/inc/salinst.h108
-rw-r--r--vcl/aqua/inc/salobj.h94
-rw-r--r--vcl/aqua/inc/salprn.h144
-rw-r--r--vcl/aqua/inc/salsys.h79
-rw-r--r--vcl/aqua/inc/salvd.h88
-rw-r--r--vcl/aqua/inc/svsys.h69
-rw-r--r--vcl/aqua/source/app/makefile.mk113
-rw-r--r--vcl/aqua/source/app/saldata.cxx262
-rw-r--r--vcl/aqua/source/app/salinst.cxx918
-rw-r--r--vcl/aqua/source/app/salsys.cxx202
-rw-r--r--vcl/aqua/source/app/saltimer.cxx156
-rw-r--r--vcl/aqua/source/gdi/makefile.mk113
-rw-r--r--vcl/aqua/source/gdi/salbmp.cxx686
-rw-r--r--vcl/aqua/source/gdi/salgdi.cxx1536
-rw-r--r--vcl/aqua/source/gdi/salogl.cxx351
-rw-r--r--vcl/aqua/source/gdi/salprn.cxx1487
-rw-r--r--vcl/aqua/source/gdi/salvd.cxx234
-rw-r--r--vcl/aqua/source/window/makefile.mk104
-rw-r--r--vcl/aqua/source/window/salframe.cxx3991
-rw-r--r--vcl/aqua/source/window/salobj.cxx858
-rw-r--r--vcl/os2/inc/saldata.hxx278
-rw-r--r--vcl/os2/inc/salframe.h113
-rw-r--r--vcl/os2/inc/salgdi.h108
-rw-r--r--vcl/os2/inc/salids.hrc134
-rw-r--r--vcl/os2/inc/salinst.h109
-rw-r--r--vcl/os2/inc/sallang.hxx103
-rw-r--r--vcl/os2/inc/salobj.h91
-rw-r--r--vcl/os2/inc/salprn.h119
-rw-r--r--vcl/os2/inc/salsound.hxx125
-rw-r--r--vcl/os2/inc/salsys.h79
-rw-r--r--vcl/os2/inc/salvd.h91
-rw-r--r--vcl/os2/inc/svsys.h69
-rw-r--r--vcl/os2/source/app/makefile.mk96
-rw-r--r--vcl/os2/source/app/salinst.cxx754
-rw-r--r--vcl/os2/source/app/sallang.cxx406
-rw-r--r--vcl/os2/source/app/salshl.cxx84
-rw-r--r--vcl/os2/source/app/salsound.cxx421
-rw-r--r--vcl/os2/source/app/salsys.cxx287
-rw-r--r--vcl/os2/source/app/saltimer.cxx122
-rw-r--r--vcl/os2/source/gdi/makefile.mk94
-rw-r--r--vcl/os2/source/gdi/salbmp.cxx760
-rw-r--r--vcl/os2/source/gdi/salgdi.cxx852
-rw-r--r--vcl/os2/source/gdi/salgdi2.cxx786
-rw-r--r--vcl/os2/source/gdi/salgdi3.cxx780
-rw-r--r--vcl/os2/source/gdi/salogl.cxx263
-rw-r--r--vcl/os2/source/gdi/salprn.cxx1878
-rw-r--r--vcl/os2/source/gdi/salvd.cxx230
-rw-r--r--vcl/os2/source/src/makefile.mk147
-rw-r--r--vcl/os2/source/src/salsrc.rc134
-rw-r--r--vcl/os2/source/window/makefile40
-rw-r--r--vcl/os2/source/window/makefile.mk84
-rw-r--r--vcl/os2/source/window/salframe.cxx2762
-rw-r--r--vcl/os2/source/window/salobj.cxx605
-rw-r--r--vcl/prj/d.lst186
-rw-r--r--vcl/source/app/dbggui.cxx1884
-rw-r--r--vcl/source/app/help.cxx686
-rw-r--r--vcl/source/app/idlemgr.cxx191
-rw-r--r--vcl/source/app/makefile.mk123
-rw-r--r--vcl/source/app/settings.cxx1857
-rw-r--r--vcl/source/app/sound.cxx361
-rw-r--r--vcl/source/app/stdtext.cxx104
-rw-r--r--vcl/source/app/svapp.cxx1770
-rw-r--r--vcl/source/app/svdata.cxx237
-rw-r--r--vcl/source/app/svmain.cxx714
-rw-r--r--vcl/source/app/timer.cxx490
-rw-r--r--vcl/source/app/unohelp.cxx275
-rw-r--r--vcl/source/control/button.cxx3010
-rw-r--r--vcl/source/control/combobox.cxx1242
-rw-r--r--vcl/source/control/ctrl.cxx155
-rw-r--r--vcl/source/control/edit.cxx2200
-rw-r--r--vcl/source/control/field.cxx2330
-rw-r--r--vcl/source/control/field2.cxx3245
-rw-r--r--vcl/source/control/fixbrd.cxx255
-rw-r--r--vcl/source/control/fixed.cxx1051
-rw-r--r--vcl/source/control/group.cxx349
-rw-r--r--vcl/source/control/ilstbox.cxx2387
-rw-r--r--vcl/source/control/imgctrl.cxx95
-rw-r--r--vcl/source/control/longcurr.cxx873
-rw-r--r--vcl/source/control/lstbox.cxx1242
-rw-r--r--vcl/source/control/makefile.mk119
-rw-r--r--vcl/source/control/menubtn.cxx285
-rw-r--r--vcl/source/control/morebtn.cxx266
-rw-r--r--vcl/source/control/scrbar.cxx1245
-rw-r--r--vcl/source/control/slider.cxx1024
-rw-r--r--vcl/source/control/spinbtn.cxx313
-rw-r--r--vcl/source/control/spinfld.cxx791
-rw-r--r--vcl/source/control/tabctrl.cxx1772
-rw-r--r--vcl/source/gdi/alpha.cxx353
-rw-r--r--vcl/source/gdi/animate.cxx992
-rw-r--r--vcl/source/gdi/bitmap.cxx1980
-rw-r--r--vcl/source/gdi/bitmap2.cxx1269
-rw-r--r--vcl/source/gdi/bitmap3.cxx2248
-rw-r--r--vcl/source/gdi/bitmap4.cxx953
-rw-r--r--vcl/source/gdi/bitmapex.cxx690
-rw-r--r--vcl/source/gdi/bmpacc.cxx448
-rw-r--r--vcl/source/gdi/bmpacc2.cxx353
-rw-r--r--vcl/source/gdi/bmpacc3.cxx351
-rw-r--r--vcl/source/gdi/cvtgrf.cxx232
-rw-r--r--vcl/source/gdi/cvtsvm.cxx2106
-rw-r--r--vcl/source/gdi/font.cxx625
-rw-r--r--vcl/source/gdi/gdimtf.cxx1724
-rw-r--r--vcl/source/gdi/gfxlink.cxx450
-rw-r--r--vcl/source/gdi/gradient.cxx386
-rw-r--r--vcl/source/gdi/graph.cxx832
-rw-r--r--vcl/source/gdi/hatch.cxx262
-rw-r--r--vcl/source/gdi/image.cxx1521
-rw-r--r--vcl/source/gdi/imgcons.cxx593
-rw-r--r--vcl/source/gdi/impanmvw.cxx392
-rw-r--r--vcl/source/gdi/impanmvw.hxx130
-rw-r--r--vcl/source/gdi/impbmp.cxx309
-rw-r--r--vcl/source/gdi/impgraph.cxx1571
-rw-r--r--vcl/source/gdi/impimage.cxx744
-rw-r--r--vcl/source/gdi/implncvt.cxx605
-rw-r--r--vcl/source/gdi/implncvt.hxx113
-rw-r--r--vcl/source/gdi/impprn.cxx256
-rw-r--r--vcl/source/gdi/impvect.cxx1267
-rw-r--r--vcl/source/gdi/impvect.hxx101
-rw-r--r--vcl/source/gdi/jobset.cxx415
-rw-r--r--vcl/source/gdi/lineinfo.cxx300
-rw-r--r--vcl/source/gdi/makefile.mk156
-rw-r--r--vcl/source/gdi/mapmod.cxx356
-rw-r--r--vcl/source/gdi/metaact.cxx3434
-rw-r--r--vcl/source/gdi/metric.cxx142
-rw-r--r--vcl/source/gdi/octree.cxx419
-rw-r--r--vcl/source/gdi/opengl.cxx1714
-rw-r--r--vcl/source/gdi/outdev.cxx1927
-rw-r--r--vcl/source/gdi/outdev2.cxx1928
-rw-r--r--vcl/source/gdi/outdev3.cxx6326
-rw-r--r--vcl/source/gdi/outdev4.cxx1634
-rw-r--r--vcl/source/gdi/outdev5.cxx430
-rw-r--r--vcl/source/gdi/outdev6.cxx1043
-rw-r--r--vcl/source/gdi/outmap.cxx2106
-rw-r--r--vcl/source/gdi/polyscan.cxx389
-rw-r--r--vcl/source/gdi/print.cxx1979
-rw-r--r--vcl/source/gdi/print2.cxx543
-rw-r--r--vcl/source/gdi/regband.cxx785
-rw-r--r--vcl/source/gdi/region.cxx2458
-rw-r--r--vcl/source/gdi/salmisc.cxx497
-rw-r--r--vcl/source/gdi/svcompat.cxx117
-rw-r--r--vcl/source/gdi/virdev.cxx442
-rw-r--r--vcl/source/gdi/wall.cxx616
-rw-r--r--vcl/source/helper/evntpost.cxx96
-rw-r--r--vcl/source/helper/makefile.mk100
-rw-r--r--vcl/source/helper/threadex.cxx130
-rw-r--r--vcl/source/src/btntext.src290
-rw-r--r--vcl/source/src/helptext.src367
-rw-r--r--vcl/source/src/images.src167
-rw-r--r--vcl/source/src/makefile.mk106
-rw-r--r--vcl/source/src/menu.src284
-rw-r--r--vcl/source/src/stdtext.src91
-rw-r--r--vcl/source/window/accel.cxx775
-rw-r--r--vcl/source/window/accmgr.cxx318
-rw-r--r--vcl/source/window/brdwin.cxx3808
-rw-r--r--vcl/source/window/btndlg.cxx584
-rw-r--r--vcl/source/window/cursor.cxx449
-rw-r--r--vcl/source/window/decoview.cxx1297
-rw-r--r--vcl/source/window/dialog.cxx847
-rw-r--r--vcl/source/window/dlgctrl.cxx968
-rw-r--r--vcl/source/window/dockwin.cxx857
-rw-r--r--vcl/source/window/floatwin.cxx748
-rw-r--r--vcl/source/window/keycod.cxx276
-rw-r--r--vcl/source/window/makefile.mk139
-rw-r--r--vcl/source/window/menu.cxx3444
-rw-r--r--vcl/source/window/mnemonic.cxx260
-rw-r--r--vcl/source/window/msgbox.cxx548
-rw-r--r--vcl/source/window/scrwnd.cxx420
-rw-r--r--vcl/source/window/scrwnd.hxx124
-rw-r--r--vcl/source/window/seleng.cxx506
-rw-r--r--vcl/source/window/split.cxx365
-rw-r--r--vcl/source/window/splitwin.cxx3647
-rw-r--r--vcl/source/window/status.cxx1411
-rw-r--r--vcl/source/window/syschild.cxx221
-rw-r--r--vcl/source/window/syswin.cxx389
-rw-r--r--vcl/source/window/tabdlg.cxx315
-rw-r--r--vcl/source/window/tabpage.cxx182
-rw-r--r--vcl/source/window/toolbox.cxx4176
-rw-r--r--vcl/source/window/toolbox2.cxx1401
-rw-r--r--vcl/source/window/window.cxx6539
-rw-r--r--vcl/source/window/window2.cxx1384
-rw-r--r--vcl/source/window/winproc.cxx2151
-rw-r--r--vcl/source/window/wrkwin.cxx424
-rw-r--r--vcl/unx/inc/XIM.h171
-rw-r--r--vcl/unx/inc/cdeint.hxx166
-rw-r--r--vcl/unx/inc/dtint.hxx397
-rw-r--r--vcl/unx/inc/i18n_cb.hxx111
-rw-r--r--vcl/unx/inc/i18n_ic.hxx129
-rw-r--r--vcl/unx/inc/i18n_im.hxx99
-rw-r--r--vcl/unx/inc/i18n_xkb.hxx150
-rw-r--r--vcl/unx/inc/postx.h121
-rw-r--r--vcl/unx/inc/prex.h141
-rw-r--r--vcl/unx/inc/saldata.hxx180
-rw-r--r--vcl/unx/inc/saldisp.hxx589
-rw-r--r--vcl/unx/inc/salfont.h228
-rw-r--r--vcl/unx/inc/salframe.h247
-rw-r--r--vcl/unx/inc/salgdi.h320
-rw-r--r--vcl/unx/inc/salinst.h115
-rw-r--r--vcl/unx/inc/salobj.h135
-rw-r--r--vcl/unx/inc/salprn.h133
-rw-r--r--vcl/unx/inc/salstd.hxx127
-rw-r--r--vcl/unx/inc/salsys.h89
-rw-r--r--vcl/unx/inc/salunx.h190
-rw-r--r--vcl/unx/inc/salvd.h135
-rw-r--r--vcl/unx/inc/sm.hxx112
-rw-r--r--vcl/unx/inc/soicon.hxx74
-rw-r--r--vcl/unx/inc/strhelper.hxx77
-rw-r--r--vcl/unx/inc/svsys.h68
-rw-r--r--vcl/unx/inc/svunx.h83
-rw-r--r--vcl/unx/inc/xfont.hxx133
-rw-r--r--vcl/unx/inc/xsalprn.h223
-rw-r--r--vcl/unx/source/app/i18n_cb.cxx547
-rw-r--r--vcl/unx/source/app/i18n_ic.cxx686
-rw-r--r--vcl/unx/source/app/i18n_im.cxx332
-rw-r--r--vcl/unx/source/app/i18n_wrp.cxx293
-rw-r--r--vcl/unx/source/app/i18n_xkb.cxx195
-rw-r--r--vcl/unx/source/app/keysymnames.cxx545
-rw-r--r--vcl/unx/source/app/makefile.mk142
-rw-r--r--vcl/unx/source/app/saldata.cxx854
-rw-r--r--vcl/unx/source/app/saldisp.cxx3653
-rw-r--r--vcl/unx/source/app/salinst.cxx346
-rw-r--r--vcl/unx/source/app/salsys.cxx200
-rw-r--r--vcl/unx/source/app/saltimer.cxx129
-rw-r--r--vcl/unx/source/app/sm.cxx347
-rw-r--r--vcl/unx/source/app/soicon.cxx502
-rw-r--r--vcl/unx/source/gdi/cdeint.cxx572
-rw-r--r--vcl/unx/source/gdi/dtint.cxx1169
-rw-r--r--vcl/unx/source/gdi/makefile.mk124
-rw-r--r--vcl/unx/source/gdi/salbmp.cxx885
-rw-r--r--vcl/unx/source/gdi/salcvt.cxx434
-rw-r--r--vcl/unx/source/gdi/salcvt.hxx116
-rw-r--r--vcl/unx/source/gdi/salgdi.cxx975
-rw-r--r--vcl/unx/source/gdi/salgdi2.cxx810
-rw-r--r--vcl/unx/source/gdi/salgdi3.cxx1074
-rw-r--r--vcl/unx/source/gdi/salogl.cxx393
-rw-r--r--vcl/unx/source/gdi/salvd.cxx239
-rw-r--r--vcl/unx/source/gdi/xfont.cxx559
-rw-r--r--vcl/unx/source/gdi/xlfd_attr.cxx655
-rw-r--r--vcl/unx/source/gdi/xlfd_attr.hxx266
-rw-r--r--vcl/unx/source/gdi/xlfd_extd.cxx699
-rw-r--r--vcl/unx/source/gdi/xlfd_extd.hxx251
-rw-r--r--vcl/unx/source/gdi/xlfd_smpl.cxx285
-rw-r--r--vcl/unx/source/gdi/xlfd_smpl.hxx132
-rw-r--r--vcl/unx/source/inc/airbrush_curs.h74
-rw-r--r--vcl/unx/source/inc/airbrush_mask.h74
-rw-r--r--vcl/unx/source/inc/ase_curs.h74
-rw-r--r--vcl/unx/source/inc/ase_mask.h74
-rw-r--r--vcl/unx/source/inc/asn_curs.h74
-rw-r--r--vcl/unx/source/inc/asn_mask.h74
-rw-r--r--vcl/unx/source/inc/asne_curs.h74
-rw-r--r--vcl/unx/source/inc/asne_mask.h74
-rw-r--r--vcl/unx/source/inc/asns_curs.h74
-rw-r--r--vcl/unx/source/inc/asns_mask.h74
-rw-r--r--vcl/unx/source/inc/asnswe_curs.h74
-rw-r--r--vcl/unx/source/inc/asnswe_mask.h74
-rw-r--r--vcl/unx/source/inc/asnw_curs.h74
-rw-r--r--vcl/unx/source/inc/asnw_mask.h74
-rw-r--r--vcl/unx/source/inc/ass_curs.h74
-rw-r--r--vcl/unx/source/inc/ass_mask.h74
-rw-r--r--vcl/unx/source/inc/asse_curs.h74
-rw-r--r--vcl/unx/source/inc/asse_mask.h74
-rw-r--r--vcl/unx/source/inc/assw_curs.h74
-rw-r--r--vcl/unx/source/inc/assw_mask.h74
-rw-r--r--vcl/unx/source/inc/asw_curs.h74
-rw-r--r--vcl/unx/source/inc/asw_mask.h74
-rw-r--r--vcl/unx/source/inc/aswe_curs.h74
-rw-r--r--vcl/unx/source/inc/aswe_mask.h74
-rw-r--r--vcl/unx/source/inc/chain_curs.h74
-rw-r--r--vcl/unx/source/inc/chain_mask.h72
-rw-r--r--vcl/unx/source/inc/chainnot_curs.h74
-rw-r--r--vcl/unx/source/inc/chainnot_mask.h72
-rw-r--r--vcl/unx/source/inc/chart_curs.h74
-rw-r--r--vcl/unx/source/inc/chart_mask.h74
-rw-r--r--vcl/unx/source/inc/copydata_curs.h76
-rw-r--r--vcl/unx/source/inc/copydata_mask.h76
-rw-r--r--vcl/unx/source/inc/copydlnk_curs.h76
-rw-r--r--vcl/unx/source/inc/copydlnk_mask.h76
-rw-r--r--vcl/unx/source/inc/copyfile_curs.h76
-rw-r--r--vcl/unx/source/inc/copyfile_mask.h76
-rw-r--r--vcl/unx/source/inc/copyfiles_curs.h76
-rw-r--r--vcl/unx/source/inc/copyfiles_mask.h76
-rw-r--r--vcl/unx/source/inc/copyflnk_curs.h76
-rw-r--r--vcl/unx/source/inc/copyflnk_mask.h76
-rw-r--r--vcl/unx/source/inc/crook_curs.h76
-rw-r--r--vcl/unx/source/inc/crook_mask.h74
-rw-r--r--vcl/unx/source/inc/crop_curs.h76
-rw-r--r--vcl/unx/source/inc/crop_mask.h74
-rw-r--r--vcl/unx/source/inc/detective_curs.h74
-rw-r--r--vcl/unx/source/inc/detective_mask.h74
-rw-r--r--vcl/unx/source/inc/drawarc_curs.h76
-rw-r--r--vcl/unx/source/inc/drawarc_mask.h74
-rw-r--r--vcl/unx/source/inc/drawbezier_curs.h76
-rw-r--r--vcl/unx/source/inc/drawbezier_mask.h74
-rw-r--r--vcl/unx/source/inc/drawcaption_curs.h76
-rw-r--r--vcl/unx/source/inc/drawcaption_mask.h74
-rw-r--r--vcl/unx/source/inc/drawcirclecut_curs.h76
-rw-r--r--vcl/unx/source/inc/drawcirclecut_mask.h74
-rw-r--r--vcl/unx/source/inc/drawconnect_curs.h76
-rw-r--r--vcl/unx/source/inc/drawconnect_mask.h74
-rw-r--r--vcl/unx/source/inc/drawcrook_curs.h76
-rw-r--r--vcl/unx/source/inc/drawcrook_mask.h74
-rw-r--r--vcl/unx/source/inc/drawcrop_curs.h76
-rw-r--r--vcl/unx/source/inc/drawcrop_mask.h74
-rw-r--r--vcl/unx/source/inc/drawellipse_curs.h76
-rw-r--r--vcl/unx/source/inc/drawellipse_mask.h74
-rw-r--r--vcl/unx/source/inc/drawfreehand_curs.h76
-rw-r--r--vcl/unx/source/inc/drawfreehand_mask.h74
-rw-r--r--vcl/unx/source/inc/drawline_curs.h76
-rw-r--r--vcl/unx/source/inc/drawline_mask.h74
-rw-r--r--vcl/unx/source/inc/drawmirror_curs.h76
-rw-r--r--vcl/unx/source/inc/drawmirror_mask.h74
-rw-r--r--vcl/unx/source/inc/drawpie_curs.h76
-rw-r--r--vcl/unx/source/inc/drawpie_mask.h74
-rw-r--r--vcl/unx/source/inc/drawpolygon_curs.h76
-rw-r--r--vcl/unx/source/inc/drawpolygon_mask.h74
-rw-r--r--vcl/unx/source/inc/drawrect_curs.h76
-rw-r--r--vcl/unx/source/inc/drawrect_mask.h74
-rw-r--r--vcl/unx/source/inc/drawtext_curs.h76
-rw-r--r--vcl/unx/source/inc/drawtext_mask.h74
-rw-r--r--vcl/unx/source/inc/fill_curs.h74
-rw-r--r--vcl/unx/source/inc/fill_mask.h74
-rw-r--r--vcl/unx/source/inc/hshear_curs.h76
-rw-r--r--vcl/unx/source/inc/hshear_mask.h74
-rw-r--r--vcl/unx/source/inc/invert50.h99
-rw-r--r--vcl/unx/source/inc/linkdata_curs.h76
-rw-r--r--vcl/unx/source/inc/linkdata_mask.h76
-rw-r--r--vcl/unx/source/inc/linkfile_curs.h76
-rw-r--r--vcl/unx/source/inc/linkfile_mask.h76
-rw-r--r--vcl/unx/source/inc/magnify_curs.h68
-rw-r--r--vcl/unx/source/inc/magnify_mask.h66
-rw-r--r--vcl/unx/source/inc/mirror_curs.h76
-rw-r--r--vcl/unx/source/inc/mirror_mask.h74
-rw-r--r--vcl/unx/source/inc/movebezierweight_curs.h76
-rw-r--r--vcl/unx/source/inc/movebezierweight_mask.h74
-rw-r--r--vcl/unx/source/inc/movedata_curs.h76
-rw-r--r--vcl/unx/source/inc/movedata_mask.h76
-rw-r--r--vcl/unx/source/inc/movedlnk_curs.h76
-rw-r--r--vcl/unx/source/inc/movedlnk_mask.h76
-rw-r--r--vcl/unx/source/inc/movefile_curs.h76
-rw-r--r--vcl/unx/source/inc/movefile_mask.h76
-rw-r--r--vcl/unx/source/inc/movefiles_curs.h76
-rw-r--r--vcl/unx/source/inc/movefiles_mask.h76
-rw-r--r--vcl/unx/source/inc/moveflnk_curs.h76
-rw-r--r--vcl/unx/source/inc/moveflnk_mask.h76
-rw-r--r--vcl/unx/source/inc/movepoint_curs.h76
-rw-r--r--vcl/unx/source/inc/movepoint_mask.h74
-rw-r--r--vcl/unx/source/inc/nodrop_curs.h76
-rw-r--r--vcl/unx/source/inc/nodrop_mask.h76
-rw-r--r--vcl/unx/source/inc/null_curs.h65
-rw-r--r--vcl/unx/source/inc/null_mask.h63
-rw-r--r--vcl/unx/source/inc/pivotcol_curs.h74
-rw-r--r--vcl/unx/source/inc/pivotcol_mask.h74
-rw-r--r--vcl/unx/source/inc/pivotfld_curs.h74
-rw-r--r--vcl/unx/source/inc/pivotfld_mask.h74
-rw-r--r--vcl/unx/source/inc/pivotrow_curs.h74
-rw-r--r--vcl/unx/source/inc/pivotrow_mask.h74
-rw-r--r--vcl/unx/source/inc/rotate_curs.h76
-rw-r--r--vcl/unx/source/inc/rotate_mask.h74
-rw-r--r--vcl/unx/source/inc/timemove_curs.h74
-rw-r--r--vcl/unx/source/inc/timemove_mask.h74
-rw-r--r--vcl/unx/source/inc/timesize_curs.h74
-rw-r--r--vcl/unx/source/inc/timesize_mask.h74
-rw-r--r--vcl/unx/source/inc/vshear_curs.h76
-rw-r--r--vcl/unx/source/inc/vshear_mask.h74
-rw-r--r--vcl/unx/source/window/FWS.cxx314
-rw-r--r--vcl/unx/source/window/FWS.hxx98
-rw-r--r--vcl/unx/source/window/makefile.mk97
-rw-r--r--vcl/unx/source/window/salframe.cxx2614
-rw-r--r--vcl/unx/source/window/salobj.cxx447
-rw-r--r--vcl/util/makefile.mk609
-rw-r--r--vcl/util/makefile.pmk68
-rw-r--r--vcl/util/target.pmk74
-rw-r--r--vcl/win/inc/saldata.hxx358
-rw-r--r--vcl/win/inc/salframe.h118
-rw-r--r--vcl/win/inc/salgdi.h136
-rw-r--r--vcl/win/inc/salids.hrc146
-rw-r--r--vcl/win/inc/salinst.h108
-rw-r--r--vcl/win/inc/salobj.h92
-rw-r--r--vcl/win/inc/salogl.hxx122
-rw-r--r--vcl/win/inc/salprn.h144
-rw-r--r--vcl/win/inc/salsys.h79
-rw-r--r--vcl/win/inc/salvd.h88
-rw-r--r--vcl/win/inc/svsys.h69
-rw-r--r--vcl/win/inc/wincomp.hxx453
-rw-r--r--vcl/win/source/app/MAKEFILE.MK40
-rw-r--r--vcl/win/source/app/saldata.cxx267
-rw-r--r--vcl/win/source/app/salinfo.cxx884
-rw-r--r--vcl/win/source/app/salinst.cxx897
-rw-r--r--vcl/win/source/app/salshl.cxx198
-rw-r--r--vcl/win/source/app/saltimer.cxx152
-rw-r--r--vcl/win/source/gdi/MAKEFILE.MK52
-rw-r--r--vcl/win/source/gdi/salbmp.cxx668
-rw-r--r--vcl/win/source/gdi/salgdi.cxx1449
-rw-r--r--vcl/win/source/gdi/salgdi2.cxx782
-rw-r--r--vcl/win/source/gdi/salgdi3.cxx1531
-rw-r--r--vcl/win/source/gdi/salogl.cxx329
-rw-r--r--vcl/win/source/gdi/salprn.cxx1424
-rw-r--r--vcl/win/source/gdi/salvd.cxx226
-rw-r--r--vcl/win/source/gdi/wntgdi.cxx92
-rw-r--r--vcl/win/source/src/50.bmpbin0 -> 94 bytes
-rw-r--r--vcl/win/source/src/MAKEFILE.MK106
-rw-r--r--vcl/win/source/src/airbrush.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/ase.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asn.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asne.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asns.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asnswe.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asnw.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/ass.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asse.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/assw.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asw.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/aswe.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/chain.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/chainnot.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/chart.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copydata.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copydlnk.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copyf.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copyf2.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copyflnk.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/crook.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/crop.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/cross.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/darc.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dbezier.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dcapt.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dcirccut.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dconnect.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dellipse.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/detectiv.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dfree.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dline.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dpie.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dpolygon.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/drect.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dtext.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/fill.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hand.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/help.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hshear.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hsize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hsizebar.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hsplit.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/linkdata.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/linkf.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/mirror.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/move.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movebw.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movedata.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movedlnk.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movef.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movef2.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/moveflnk.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movept.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/neswsize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/notallow.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/nullptr.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/nwsesize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/pen.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/refhand.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/rotate.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/salsrc.rc148
-rw-r--r--vcl/win/source/src/sd.icobin0 -> 3310 bytes
-rwxr-xr-xvcl/win/source/src/timemove.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/timesize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/vshear.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/vsize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/vsizebar.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/vsplit.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/window/MAKEFILE.MK38
-rw-r--r--vcl/win/source/window/salframe.cxx3901
-rw-r--r--vcl/win/source/window/salobj.cxx873
-rw-r--r--vcl/workben/makefile.mk151
-rw-r--r--vcl/workben/svdem.cxx157
476 files changed, 205748 insertions, 0 deletions
diff --git a/vcl/aqua/inc/saldata.hxx b/vcl/aqua/inc/saldata.hxx
new file mode 100644
index 000000000000..8ccec7410fcf
--- /dev/null
+++ b/vcl/aqua/inc/saldata.hxx
@@ -0,0 +1,362 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldata.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALDATA_HXX
+#define _SV_SALDATA_HXX
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SALWTYPE_HXX
+#include <salwtype.hxx>
+#endif
+#ifndef _SV_SALAQUA_HXX
+#include <salaqua.hxx>
+#endif
+
+class AutoTimer;
+class SalInstance;
+class SalObject;
+class SalFrame;
+class SalVirtualDevice;
+class SalPrinter;
+class Font;
+struct HDCCache;
+
+// --------------------
+// - Standard-Defines -
+// --------------------
+
+#define MAX_STOCKPEN 4
+#define MAX_STOCKBRUSH 4
+#define SAL_CLIPRECT_COUNT 16
+
+// -----------
+// - SalData -
+// -----------
+
+struct SalData
+{
+ HINSTANCE mhInst; // default instance handle
+ HINSTANCE mhPrevInst; // previous instance handle
+ int mnCmdShow; // default frame show style
+ // Erst hier koennen Daten kompatible eingefuegt werden, da die
+ // oberen Daten in salmain.cxx modifiziert werden
+ HPALETTE mhDitherPal; // dither palette
+ HGLOBAL mhDitherDIB; // dither memory handle
+ BYTE* mpDitherDIB; // dither memory
+ BYTE* mpDitherDIBData; // beginning of DIB data
+ long* mpDitherDiff; // Dither mapping table
+ BYTE* mpDitherLow; // Dither mapping table
+ BYTE* mpDitherHigh; // Dither mapping table
+ ULONG mnTimerMS; // Current Time (in MS) of the Timer
+ ULONG mnTimerOrgMS; // Current Original Time (in MS)
+ UINT mnTimerId; // windows timer id
+ SALTIMERPROC mpTimerProc; // timer callback proc
+ HHOOK mhSalObjMsgHook; // hook um SalObject relevante Message mitzubekommen
+ HWND mhWantLeaveMsg; // window handle, that want a MOUSELEAVE message
+ AutoTimer* mpMouseLeaveTimer; // Timer for MouseLeave Test
+ SalInstance* mpFirstInstance; // pointer of first instance
+ SalFrame* mpFirstFrame; // pointer of first frame
+ SalObject* mpFirstObject; // pointer of first object window
+ SalVirtualDevice* mpFirstVD; // first VirDev
+ SalPrinter* mpFirstPrinter; // first printing printer
+ HDCCache* mpHDCCache; // Cache for three DC's
+ HBITMAP mh50Bmp; // 50% Bitmap
+ HBRUSH mh50Brush; // 50% Brush
+ COLORREF maStockPenColorAry[MAX_STOCKPEN];
+ COLORREF maStockBrushColorAry[MAX_STOCKBRUSH];
+ HPEN mhStockPenAry[MAX_STOCKPEN];
+ HBRUSH mhStockBrushAry[MAX_STOCKBRUSH];
+ USHORT mnStockPenCount; // Anzahl statischer Pens
+ USHORT mnStockBrushCount; // Anzahl statischer Brushes
+ WPARAM mnSalObjWantKeyEvt; // KeyEvent, welcher vom SalObj-Hook verarbeitet werden soll
+ BOOL mbObjClassInit; // Ist SALOBJECTCLASS initialised
+ BOOL mbInPalChange; // is in WM_QUERYNEWPALETTE
+ DWORD mnAppThreadId; // Id from Applikation-Thread
+ WIN_BOOL mbScrSvrEnabled; // ScreenSaver enabled
+ int mnSageStatus; // Status der Sage-DLL (DISABLE_AGENT == nicht vorhanden)
+ HINSTANCE mhSageInst; // Instance-Handle zur Sage-DLL
+ SysAgt_Enable_PROC mpSageEnableProc; // Funktion zum deaktivieren des Systemagenten
+};
+
+inline void SetSalData( SalData* pData ) { ImplGetSVData()->mpSalData = (void*)pData; }
+inline SalData* GetSalData() { return (SalData*)ImplGetSVData()->mpSalData; }
+inline SalData* GetAppSalData() { return (SalData*)ImplGetAppSVData()->mpSalData; }
+
+// --------------
+// - SalShlData -
+// --------------
+
+struct SalShlData
+{
+ HINSTANCE mhInst; // Instance of SAL-DLL
+ UINT mnVKAdd; // VK-Code von KEY_ADD
+ UINT mnVKSubtract; // VK-Code von KEY_SUBTRACT
+ UINT mnVKMultiply; // VK-Code von KEY_MULTIPLY
+ UINT mnVKDivide; // VK-Code von KEY_DIVIDE
+ UINT mnVKPoint; // VK-Code von KEY_POINT
+ UINT mnVKComma; // VK-Code von KEY_KOMMA
+ UINT mnVKLess; // VK-Code von KEY_LESS
+ UINT mnVKGreater; // VK-Code von KEY_GREATER
+ UINT mnVKEqual; // VK-Code von KEY_EQUAL
+ UINT mnWheelScrollLines; // WheelScrollLines
+ UINT mnWheelMsgId; // Wheel-Message-Id fuer W95
+};
+
+extern SalShlData aSalShlData;
+
+// ------------
+// - GDICache -
+// ------------
+
+#define CACHESIZE_HDC 3
+#define CACHED_HDC_1 0
+#define CACHED_HDC_2 1
+#define CACHED_HDC_DRAW 2
+#define CACHED_HDC_DEFEXT 64
+
+struct HDCCache
+{
+ HDC mhDC;
+ HPALETTE mhDefPal;
+ HBITMAP mhDefBmp;
+ HBITMAP mhSelBmp;
+ HBITMAP mhActBmp;
+};
+
+void ImplClearHDCCache( SalData* pData );
+HDC ImplGetCachedDC( ULONG nID, HBITMAP hBmp = 0 );
+void ImplReleaseCachedDC( ULONG nID );
+
+// ------------------------------------------------------
+// - salshl.cxx - Funktionen fuer DLL-Resource-Zugriffe -
+// ------------------------------------------------------
+
+HCURSOR ImplLoadSalCursor( int nId );
+HBITMAP ImplLoadSalBitmap( int nId );
+BOOL ImplLoadSalIcon( int nId, HICON& rIcon, HICON& rSmallIcon );
+
+void ImplInitSalGDI();
+void ImplFreeSalGDI();
+
+// --------------
+// - Prototypes -
+// --------------
+
+void ImplSalYieldMutexAcquireWithWait();
+BOOL ImplSalYieldMutexTryToAcquire();
+void ImplSalYieldMutexAcquire();
+void ImplSalYieldMutexRelease();
+ULONG ImplSalReleaseYieldMutex();
+void ImplSalAcquireYieldMutex( ULONG nCount );
+
+LRESULT CALLBACK SalFrameWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+LRESULT CALLBACK SalFrameWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+void CALLBACK SalTimerProc( HWND hWnd, UINT nMsg, UINT nId, DWORD nTime );
+
+void SalTestMouseLeave();
+
+long ImplHandleSalObjKeyMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+long ImplHandleSalObjSysCharMsg( HWND hWnd, WPARAM wParam, LPARAM lParam );
+BOOL ImplHandleGlobalMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT& rlResult );
+
+SalObject* ImplFindSalObject( HWND hWndChild );
+#ifdef WIN
+BOOL ImplSalPreDispatchMsg( MSG* pMsg );
+void ImplSalPostDispatchMsg( MSG* pMsg, LRESULT nDispatchResult );
+
+void ImplSalLogFontToFontA( const LOGFONTA& rLogFont, Font& rFont );
+void ImplSalLogFontToFontW( const LOGFONTW& rLogFont, Font& rFont );
+#endif
+
+rtl_TextEncoding ImplSalGetSystemEncoding();
+ByteString ImplSalGetWinAnsiString( const UniString& rStr, BOOL bFileName = FALSE );
+UniString ImplSalGetUniString( const sal_Char* pStr, xub_StrLen nLen = STRING_LEN );
+int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 );
+
+// -----------
+// - Defines -
+// -----------
+
+#define SAL_FRAME_WNDEXTRA sizeof( DWORD )
+#define SAL_FRAME_THIS 0
+#define SAL_FRAME_CLASSNAMEA "SALFRAME"
+#define SAL_FRAME_CLASSNAMEW L"SALFRAME"
+#define SAL_FRAME_CLASSNAME_SBA "SALFRAMESB"
+#define SAL_FRAME_CLASSNAME_SBW L"SALFRAMESB"
+#define SAL_OBJECT_WNDEXTRA sizeof( DWORD )
+#define SAL_OBJECT_THIS 0
+#define SAL_OBJECT_CLASSNAMEA "SALOBJECT"
+#define SAL_OBJECT_CLASSNAMEW L"SALOBJECT"
+#define SAL_OBJECT_CHILDCLASSNAMEA "SALOBJECTCHILD"
+#define SAL_OBJECT_CHILDCLASSNAMEW L"SALOBJECTCHILD"
+#define SAL_COM_CLASSNAMEA "SALCOMWND"
+#define SAL_COM_CLASSNAMEW L"SALCOMWND"
+
+#define SAL_MOUSELEAVE_TIMEOUT 300
+
+// wParam == hDC; lParam == 0
+#define SAL_MSG_PRINTABORTJOB (WM_USER+110)
+// wParam == bWait; lParam == 0
+#define SAL_MSG_THREADYIELD (WM_USER+111)
+// wParam == 0; lParam == 0
+#define SAL_MSG_RELEASEWAITYIELD (WM_USER+112)
+// wParam == 0; lParam == nMS
+#define SAL_MSG_STARTTIMER (WM_USER+113)
+// wParam == nFrameStyle; lParam == pParent; lResult == pFrame
+#define SAL_MSG_CREATEFRAME (WM_USER+114)
+// wParam == 0; lParam == 0
+#define SAL_MSG_DESTROYFRAME (WM_USER+115)
+// wParam == 0; lParam == pParent; lResult == pObject
+#define SAL_MSG_CREATEOBJECT (WM_USER+116)
+// wParam == 0; lParam == pObject;
+#define SAL_MSG_DESTROYOBJECT (WM_USER+117)
+// wParam == 0; lParam == this; lResult == bRet
+#define SAL_MSG_CREATESOUND (WM_USER+118)
+// wParam == 0; lParam == this
+#define SAL_MSG_DESTROYSOUND (WM_USER+119)
+
+// wParam == 0; lParam == pData
+#define SAL_MSG_USEREVENT (WM_USER+130)
+// wParam == 0; lParam == MousePosition relativ to upper left of screen
+#define SAL_MSG_MOUSELEAVE (WM_USER+131)
+// NULL-Message, soll nicht verarbeitet werden
+#define SAL_MSG_DUMMY (WM_USER+132)
+// wParam == 0; lParam == 0
+#define SAL_MSG_POSTFOCUS (WM_USER+133)
+// wParam == wParam; lParam == lParam
+#define SAL_MSG_POSTQUERYNEWPAL (WM_USER+134)
+// wParam == wParam; lParam == lParam
+#define SAL_MSG_POSTPALCHANGED (WM_USER+135)
+// wParam == wParam; lParam == lParam
+#define SAL_MSG_POSTMOVE (WM_USER+136)
+// wParam == wParam; lParam == lParam
+#define SAL_MSG_POSTCALLSIZE (WM_USER+137)
+// wParam == pRECT
+#define SAL_MSG_POSTPAINT (WM_USER+138)
+// wParam == 0; lParam == pFrame; lResult 0
+#define SAL_MSG_FORCEPALETTE (WM_USER+139)
+// wParam == 0; lParam == 0;
+#define SAL_MSG_CAPTUREMOUSE (WM_USER+140)
+// wParam == 0; lParam == 0
+#define SAL_MSG_RELEASEMOUSE (WM_USER+141)
+// wParam == nFlags; lParam == 0
+#define SAL_MSG_TOTOP (WM_USER+142)
+// wParam == bVisible; lParam == 0
+#define SAL_MSG_SHOW (WM_USER+143)
+
+// SysChild-ToTop; wParam = 0; lParam = 0
+#define SALOBJ_MSG_TOTOP (WM_USER+160)
+// POSTFOCUS-Message; wParam == bFocus; lParam == 0
+#define SALOBJ_MSG_POSTFOCUS (WM_USER+161)
+
+// -----------------
+// - Helpfunctions -
+// -----------------
+
+// A/W-Wrapper
+#ifdef WIN
+LONG ImplSetWindowLong( HWND hWnd, int nIndex, DWORD dwNewLong );
+LONG ImplGetWindowLong( HWND hWnd, int nIndex );
+WIN_BOOL ImplPostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
+WIN_BOOL ImplSendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
+WIN_BOOL ImplGetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax );
+WIN_BOOL ImplPeekMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg );
+LONG ImplDispatchMessage( const MSG *lpMsg );
+#endif
+
+inline void SetWindowPtr( HWND hWnd, SalFrame* pThis )
+{
+#ifdef WIN
+ ImplSetWindowLong( hWnd, SAL_FRAME_THIS, (LONG)pThis );
+#endif
+}
+
+inline SalFrame* GetWindowPtr( HWND hWnd )
+{
+#ifdef WIN
+ return (SalFrame*)ImplGetWindowLong( hWnd, SAL_FRAME_THIS );
+#else
+ return NULL;
+#endif
+}
+
+inline void SetSalObjWindowPtr( HWND hWnd, SalObject* pThis )
+{
+#ifdef WIN
+ ImplSetWindowLong( hWnd, SAL_OBJECT_THIS, (LONG)pThis );
+#endif
+}
+
+inline SalObject* GetSalObjWindowPtr( HWND hWnd )
+{
+#ifdef WIN
+ return (SalObject*)ImplGetWindowLong( hWnd, SAL_OBJECT_THIS );
+#else
+ return NULL;
+#endif
+}
+
+#endif // _SV_SALDATA_HXX
diff --git a/vcl/aqua/inc/salframe.h b/vcl/aqua/inc/salframe.h
new file mode 100644
index 000000000000..48afb6522265
--- /dev/null
+++ b/vcl/aqua/inc/salframe.h
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * $RCSfile: salframe.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALFRAME_H
+#define _SV_SALFRAME_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+// ----------------
+// - SalFrameData -
+// ----------------
+
+class SalFrameData
+{
+public:
+ HWND mhWnd; // Window handle
+ HCURSOR mhCursor; // cursor handle
+ HIMC mhDefIMEContext; // default IME-Context
+ SalGraphics* mpGraphics; // current frame graphics
+ SalFrame* mpNextFrame; // pointer to next frame
+ void* mpInst; // instance handle for callback
+ SALFRAMEPROC mpProc; // callback proc
+ SystemEnvData maSysData; // system data
+ SalFrameState maState; // frame state
+ int mnShowState; // show state
+ long mnWidth; // client width in pixeln
+ long mnHeight; // client height in pixeln
+ RECT maFullScreenRect; // fullscreen rect
+ int mnFullScreenShowState; // fullscreen restore show state
+ UINT mnInputLang; // current Input Language
+ UINT mnInputCodePage; // current Input CodePage
+ USHORT mnStyle; // style
+ BOOL mbGraphics; // is Graphics used
+ BOOL mbCaption; // has window a caption
+ BOOL mbBorder; // has window a border
+ BOOL mbSizeBorder; // has window a sizeable border
+ BOOL mbFullScreen; // TRUE: in full screen mode
+ BOOL mbPresentation; // TRUE: Presentation Mode running
+ BOOL mbInShow; // innerhalb eines Show-Aufrufs
+ BOOL mbRestoreMaximize; // Restore-Maximize
+ BOOL mbInMoveMsg; // Move-Message wird verarbeitet
+ BOOL mbInSizeMsg; // Size-Message wird verarbeitet
+ BOOL mbFullScreenToolWin; // WS_EX_TOOLWINDOW reset in FullScreenMode
+ BOOL mbDefPos; // default-position
+ BOOL mbOverwriteState; // TRUE: WindowState darf umgesetzt werden
+ BOOL mbIME; // TRUE: We are in IME Mode
+ BOOL mbHandleIME; // TRUE: Wir handeln die IME-Messages
+ BOOL mbSpezIME; // TRUE: Spez IME
+ BOOL mbAtCursorIME; // TRUE: Wir behandeln nur einige IME-Messages
+ BOOL mbCompositionMode; // TRUE: Wir befinden uns im Composition-Modus
+ BOOL mbCandidateMode; // TRUE: Wir befinden uns im Candidate-Modus
+};
+
+#endif // _SV_SALFRAME_H
diff --git a/vcl/aqua/inc/salgdi.h b/vcl/aqua/inc/salgdi.h
new file mode 100644
index 000000000000..0ce9eb842cb5
--- /dev/null
+++ b/vcl/aqua/inc/salgdi.h
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALGDI_H
+#define _SV_SALGDI_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define RGB_TO_PALRGB(nRGB) ((nRGB)|0x02000000)
+#define PALRGB_TO_RGB(nPalRGB) ((nPalRGB)&0x00ffffff)
+
+// -------------------
+// - SalGraphicsData -
+// -------------------
+
+class SalGraphicsData
+{
+public:
+ HDC mhDC; // HDC
+ HWND mhWnd; // Window-Handle, when Window-Graphics
+ HPEN mhPen; // Pen
+ HBRUSH mhBrush; // Brush
+ HFONT mhFont; // Font
+ HRGN mhRegion; // Region Handle
+ HPEN mhDefPen; // DefaultPen
+ HBRUSH mhDefBrush; // DefaultBrush
+ HFONT mhDefFont; // DefaultFont
+ HPALETTE mhDefPal; // DefaultPalette
+ COLORREF mnPenColor; // PenColor
+ COLORREF mnBrushColor; // BrushColor
+ COLORREF mnTextColor; // TextColor
+#ifdef WIN
+ RGNDATA* mpClipRgnData; // ClipRegion-Data
+ RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data
+#endif
+ RECT* mpNextClipRect; // Naechstes ClipRegion-Rect
+ BOOL mbFirstClipRect; // Flag for first cliprect to insert
+#ifdef WIN
+ LOGFONTA* mpLogFont; // LOG-Font which is currently selected (only W9x)
+#endif
+ BYTE* mpFontCharSets; // All Charsets for the current font
+ BYTE mnFontCharSetCount; // Number of Charsets of the current font; 0 - if not queried
+#ifdef WIN
+ KERNINGPAIR* mpFontKernPairs; // Kerning Pairs of the current Font
+#endif
+ ULONG mnFontKernPairCount;// Number of Kerning Pairs of the current Font
+ BOOL mbFontKernInit; // FALSE: FontKerns must be queried
+ int mnFontOverhang; // Font-Overhang
+ int mnPenWidth; // Linienbreite
+ BOOL mbStockPen; // is Pen a stockpen
+ BOOL mbStockBrush; // is Brush a stcokbrush
+ BOOL mbPen; // is Pen (FALSE == NULL_PEN)
+ BOOL mbBrush; // is Brush (FALSE == NULL_BRUSH)
+ BOOL mbPrinter; // is Printer
+ BOOL mbVirDev; // is VirDev
+ BOOL mbWindow; // is Window
+ BOOL mbScreen; // is Screen compatible
+ BOOL mbXORMode; // _every_ output with RasterOp XOR
+ BOOL mbCalcOverhang; // calc overhang
+};
+
+// Init/Deinit Graphics
+void ImplSalInitGraphics( SalGraphicsData* mpData );
+void ImplSalDeInitGraphics( SalGraphicsData* mpData );
+void ImplUpdateSysColorEntries();
+int ImplIsSysColorEntry( SalColor nSalColor );
+
+// -----------
+// - Defines -
+// -----------
+
+#define MAX_64KSALPOINTS ((((USHORT)0xFFFF)-4)/sizeof(POINT))
+
+#endif // _SV_SALGDI_H
diff --git a/vcl/aqua/inc/salinst.h b/vcl/aqua/inc/salinst.h
new file mode 100644
index 000000000000..77ce94a3461b
--- /dev/null
+++ b/vcl/aqua/inc/salinst.h
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALINST_H
+#define _SV_SALINST_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+#ifdef _VOS_NO_NAMESPACE
+class OMutex;
+#else
+namespace vos { class OMutex; }
+#endif
+class SalYieldMutex;
+class SalInstance;
+class SalFrame;
+class SalObject;
+
+// -------------------
+// - SalInstanceData -
+// -------------------
+
+class SalInstanceData
+{
+public:
+ HINSTANCE mhInst; // Instance Handle
+ HWND mhComWnd; // window, for communication (between threads and the main thread)
+ void* mpFilterInst;
+ void* mpFilterCallback;
+ SalYieldMutex* mpSalYieldMutex; // Sal-Yield-Mutex
+#ifdef _VOS_NO_NAMESPACE
+ OMutex* mpSalWaitMutex; // Sal-Wait-Mutex
+#else
+ vos::OMutex* mpSalWaitMutex; // Sal-Wait-Mutex
+#endif
+ USHORT mnYieldWaitCount; // Wait-Count
+};
+
+// --------------
+// - Prototypen -
+// --------------
+
+SalFrame* ImplSalCreateFrame( SalInstance* pInst, HWND hWndParent, ULONG nSalFrameStyle );
+SalObject* ImplSalCreateObject( SalInstance* pInst, SalFrame* pParent );
+void ImplSalStartTimer( ULONG nMS, BOOL bMutex = FALSE );
+void ImplSalPrinterAbortJobAsync( HDC hPrnDC );
+
+#endif // _SV_SALINST_H
diff --git a/vcl/aqua/inc/salobj.h b/vcl/aqua/inc/salobj.h
new file mode 100644
index 000000000000..07cba9defb49
--- /dev/null
+++ b/vcl/aqua/inc/salobj.h
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * $RCSfile: salobj.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALOBJ_H
+#define _SV_SALOBJ_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+// -----------------
+// - SalObjectData -
+// -----------------
+
+class SalObjectData
+{
+public:
+ HWND mhWnd; // Window handle
+ HWND mhWndChild; // Child Window handle
+ HWND mhLastFocusWnd; // Child-Window, welches als letztes den Focus hatte
+ SystemChildData maSysData; // SystemEnvData
+#ifdef WIN
+ RGNDATA* mpClipRgnData; // ClipRegion-Data
+ RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data
+#endif
+ RECT* mpNextClipRect; // Naechstes ClipRegion-Rect
+ BOOL mbFirstClipRect; // Flag for first cliprect to insert
+ SalObject* mpNextObject; // pointer to next object
+ void* mpInst; // instance handle for callback
+ SALOBJECTPROC mpProc; // callback proc
+};
+
+#endif // _SV_SALOBJ_H
diff --git a/vcl/aqua/inc/salprn.h b/vcl/aqua/inc/salprn.h
new file mode 100644
index 000000000000..483d351fd8fa
--- /dev/null
+++ b/vcl/aqua/inc/salprn.h
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * $RCSfile: salprn.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALPRN_H
+#define _SV_SALPRN_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+class SalGraphics;
+class SalInfoPrinter;
+
+// -----------------
+// - SalDriverData -
+// -----------------
+
+// WNT3
+#define SAL_DRIVERDATA_SYSSIGN ((ULONG)0x574E5433)
+#define SAL_DRIVERDATA_VERSION 1
+#define SAL_DEVMODE( pSetupData ) ((LPDEVMODE)((pSetupData->mpDriverData) + (((SalDriverData*)(pSetupData->mpDriverData))->mnDriverOffset)))
+
+#pragma pack( 1 )
+
+struct SalDriverData
+{
+ ULONG mnSysSignature;
+ USHORT mnVersion;
+ USHORT mnDriverOffset;
+ BYTE maDriverData[1];
+};
+
+#pragma pack()
+
+// -------------------
+// - SalSysQueueData -
+// -------------------
+
+struct SalSysQueueData
+{
+ XubString maDriverName; // printer driver name
+ XubString maDeviceName; // printer device name
+ XubString maPortName; // printer port name
+ ByteString maDriverNameA; // printer driver name
+ ByteString maDeviceNameA; // printer device name
+ ByteString maPortNameA; // printer port name
+ BOOL mbAnsi; // TRUE - use A functions
+};
+
+// ----------------------
+// - SalInfoPrinterData -
+// ----------------------
+
+class SalInfoPrinterData
+{
+public:
+ SalGraphics* mpGraphics; // current Printer graphics
+ XubString maDriverName; // printer driver name
+ XubString maDeviceName; // printer device name
+ XubString maPortName; // printer port name
+ ByteString maDriverNameA; // printer driver name
+ ByteString maDeviceNameA; // printer device name
+ ByteString maPortNameA; // printer port name
+ HDC mhDC; // printer hdc
+ BOOL mbGraphics; // is Graphics used
+ BOOL mbAnsi;
+};
+
+// ------------------
+// - SalPrinterData -
+// ------------------
+
+class SalPrinterData
+{
+public:
+ SalGraphics* mpGraphics; // current Printer graphics
+ SalInfoPrinter* mpInfoPrinter; // pointer to the compatible InfoPrinter
+ SalPrinter* mpNextPrinter; // next printing printer
+ HDC mhDC; // printer hdc
+ ULONG mnError; // Error Code
+ ULONG mnCopies; // Kopien
+ BOOL mbCollate; // Sortierte Kopien
+ BOOL mbAbort; // Job Aborted
+};
+
+#endif // _SV_SALPRN_H
diff --git a/vcl/aqua/inc/salsys.h b/vcl/aqua/inc/salsys.h
new file mode 100644
index 000000000000..3660ee45051f
--- /dev/null
+++ b/vcl/aqua/inc/salsys.h
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * $RCSfile: salsys.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALSYS_H
+#define _SV_SALSYS_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+class SalFrame;
+
+// -----------------
+// - SalSystemData -
+// -----------------
+
+class SalSystemData
+{
+};
+
+#endif // _SV_SALSYS_H
diff --git a/vcl/aqua/inc/salvd.h b/vcl/aqua/inc/salvd.h
new file mode 100644
index 000000000000..e6eea8235698
--- /dev/null
+++ b/vcl/aqua/inc/salvd.h
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * $RCSfile: salvd.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALVD_H
+#define _SV_SALVD_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+class SalGraphics;
+class SalVirtualDevice;
+
+// -----------------
+// - SalVirDevData -
+// -----------------
+
+class SalVirDevData
+{
+public:
+ HDC mhDC; // HDC or 0 for Cache Device
+ HBITMAP mhBmp; // Memory Bitmap
+ HBITMAP mhDefBmp; // Default Bitmap
+ SalGraphics* mpGraphics; // current VirDev graphics
+ SalVirtualDevice* mpNext; // next VirDev
+ USHORT mnBitCount; // BitCount (0 or 1)
+ BOOL mbGraphics; // is Graphics used
+};
+
+#endif // _SV_SALVD_H
diff --git a/vcl/aqua/inc/svsys.h b/vcl/aqua/inc/svsys.h
new file mode 100644
index 000000000000..6391751656c7
--- /dev/null
+++ b/vcl/aqua/inc/svsys.h
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * $RCSfile: svsys.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SVSYS_H
+#define _SV_SVSYS_H
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#endif // _SV_SVSYS_H
diff --git a/vcl/aqua/source/app/makefile.mk b/vcl/aqua/source/app/makefile.mk
new file mode 100644
index 000000000000..abb29cc745bb
--- /dev/null
+++ b/vcl/aqua/source/app/makefile.mk
@@ -0,0 +1,113 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salapp
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(OS)"!="MACOSX"
+
+dummy:
+ @echo "Nothing to build for this platform"
+
+.ELSE # "$(OS)"!="MACOSX"
+
+.IF "$(remote)"==""
+OBJFILES=\
+ $(OBJ)$/salmain.obj
+
+SLOFILES= $(SLO)$/salshl.obj \
+ $(SLO)$/saldata.obj \
+ $(SLO)$/salinst.obj \
+ $(SLO)$/saltimer.obj \
+ $(SLO)$/salsound.obj \
+ $(SLO)$/salinfo.obj \
+ $(SLO)$/salsys.obj
+
+.ELSE
+SLOFILES=\
+ $(SLO)$/salmain.obj
+.ENDIF
+
+.IF "$(remote)"!=""
+EXCEPTIONSFILES=$(SLO)$/salmain.obj \
+ $(OBJ)$/salmain.obj
+.ENDIF
+
+.ENDIF # "$(OS)"!="MACOSX"
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
+
diff --git a/vcl/aqua/source/app/saldata.cxx b/vcl/aqua/source/app/saldata.cxx
new file mode 100644
index 000000000000..39c8b22e342c
--- /dev/null
+++ b/vcl/aqua/source/app/saldata.cxx
@@ -0,0 +1,262 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldata.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALDATA_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+
+// =======================================================================
+
+rtl_TextEncoding ImplSalGetSystemEncoding()
+{
+ static UINT nOldAnsiCodePage = 0;
+ static rtl_TextEncoding eEncoding = RTL_TEXTENCODING_MS_1252;
+
+#ifdef WIN
+ UINT nAnsiCodePage = GetACP();
+ if ( nAnsiCodePage != nOldAnsiCodePage )
+ {
+ switch ( nAnsiCodePage )
+ {
+ case 1252:
+ eEncoding = RTL_TEXTENCODING_MS_1252;
+ break;
+ case 1250:
+ eEncoding = RTL_TEXTENCODING_MS_1250;
+ break;
+ case 1251:
+ eEncoding = RTL_TEXTENCODING_MS_1251;
+ break;
+ case 1253:
+ eEncoding = RTL_TEXTENCODING_MS_1253;
+ break;
+ case 1254:
+ eEncoding = RTL_TEXTENCODING_MS_1254;
+ break;
+ case 1255:
+ eEncoding = RTL_TEXTENCODING_MS_1255;
+ break;
+ case 1256:
+ eEncoding = RTL_TEXTENCODING_MS_1256;
+ break;
+ case 1257:
+ eEncoding = RTL_TEXTENCODING_MS_1257;
+ break;
+ case 1258:
+ eEncoding = RTL_TEXTENCODING_MS_1258;
+ break;
+ case 874:
+ eEncoding = RTL_TEXTENCODING_MS_874;
+ break;
+ case 932:
+ eEncoding = RTL_TEXTENCODING_MS_932;
+ break;
+ case 936:
+ eEncoding = RTL_TEXTENCODING_MS_936;
+ break;
+ case 949:
+ eEncoding = RTL_TEXTENCODING_MS_949;
+ break;
+ case 950:
+ eEncoding = RTL_TEXTENCODING_MS_950;
+ break;
+// case 1381:
+// eEncoding = RTL_TEXTENCODING_MS_1381;
+// break;
+ }
+ }
+#endif
+
+ return eEncoding;
+}
+
+// -----------------------------------------------------------------------
+
+ByteString ImplSalGetWinAnsiString( const UniString& rStr, BOOL bFileName )
+{
+ rtl_TextEncoding eEncoding = ImplSalGetSystemEncoding();
+ if ( bFileName )
+ {
+ return ByteString( rStr, eEncoding,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 );
+ }
+ else
+ {
+ return ByteString( rStr, eEncoding,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+UniString ImplSalGetUniString( const sal_Char* pStr, xub_StrLen nLen )
+{
+ return UniString( pStr, nLen, ImplSalGetSystemEncoding(),
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT );
+}
+
+// =======================================================================
+
+int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 )
+{
+ int nRet;
+ wchar_t c1;
+ char c2;
+ do
+ {
+ // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
+ c1 = *pStr1;
+ c2 = *pStr2;
+ if ( (c1 >= 65) && (c1 <= 90) )
+ c1 += 32;
+ if ( (c2 >= 65) && (c2 <= 90) )
+ c2 += 32;
+ nRet = ((sal_Int32)c1)-((sal_Int32)((unsigned char)c2));
+ if ( nRet != 0 )
+ break;
+
+ pStr1++;
+ pStr2++;
+ }
+ while ( c2 );
+
+ return nRet;
+}
+
+// =======================================================================
+
+#ifdef WIN
+LONG ImplSetWindowLong( HWND hWnd, int nIndex, DWORD dwNewLong )
+{
+ return SetWindowLongA( hWnd, nIndex, dwNewLong );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+LONG ImplGetWindowLong( HWND hWnd, int nIndex )
+{
+ return GetWindowLongA( hWnd, nIndex );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+WIN_BOOL ImplPostMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ return PostMessageA( hWnd, nMsg, wParam, lParam );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+WIN_BOOL ImplSendMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ return SendMessageA( hWnd, nMsg, wParam, lParam );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+WIN_BOOL ImplGetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax )
+{
+ return GetMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+WIN_BOOL ImplPeekMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg )
+{
+ return PeekMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+LONG ImplDispatchMessage( const MSG *lpMsg )
+{
+ return DispatchMessageA( lpMsg );
+}
+#endif
+
diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx
new file mode 100644
index 000000000000..8dc10e7e565b
--- /dev/null
+++ b/vcl/aqua/source/app/salinst.cxx
@@ -0,0 +1,918 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <tools/svwin.h>
+#ifdef WNT
+#include <process.h>
+#endif
+
+#define _SV_SALINST_CXX
+
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SALAQUA_HXX
+#include <salaqua.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+#ifndef _SV_SALSOUND_HXX
+#include <salsound.hxx>
+#endif
+#ifndef _SV_SALATYPE_HXX
+#include <salatype.hxx>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+
+// =======================================================================
+
+void SalAbort( const XubString& rErrorText )
+{
+ ImplFreeSalGDI();
+
+#ifdef WIN
+ if ( !rErrorText.Len() )
+ FatalAppExit( 0, "Application Error" );
+ else
+ {
+ ByteString aErrorText( ImplSalGetWinAnsiString( rErrorText ) );
+ FatalAppExit( 0, aErrorText.GetBuffer() );
+ }
+#endif
+}
+
+// =======================================================================
+
+LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+
+// =======================================================================
+
+class SalYieldMutex : public NAMESPACE_VOS(OMutex)
+{
+public: // for ImplSalYield()
+ SalInstanceData* mpInstData;
+ ULONG mnCount;
+ DWORD mnThreadId;
+
+public:
+ SalYieldMutex( SalInstanceData* pInstData );
+
+ virtual void SAL_CALL acquire();
+ virtual void SAL_CALL release();
+ virtual sal_Bool SAL_CALL tryToAcquire();
+
+ ULONG GetAcquireCount( ULONG nThreadId );
+};
+
+// -----------------------------------------------------------------------
+
+SalYieldMutex::SalYieldMutex( SalInstanceData* pInstData )
+{
+ mpInstData = pInstData;
+ mnCount = 0;
+ mnThreadId = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SAL_CALL SalYieldMutex::acquire()
+{
+ OMutex::acquire();
+ mnCount++;
+#ifdef WIN
+ mnThreadId = GetCurrentThreadId();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SAL_CALL SalYieldMutex::release()
+{
+#ifdef WIN
+ DWORD nThreadId = GetCurrentThreadId();
+ if ( mnThreadId != nThreadId )
+ OMutex::release();
+ else
+ {
+ // If we don't call these message, the Output from the
+ // Java clients doesn't come in the right order
+ GdiFlush();
+
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mnAppThreadId != nThreadId )
+ {
+ if ( mnCount == 1 )
+ {
+ mpInstData->mpSalWaitMutex->acquire();
+ if ( mpInstData->mnYieldWaitCount )
+ ImplPostMessage( mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
+ mnThreadId = 0;
+ mnCount--;
+ OMutex::release();
+ mpInstData->mpSalWaitMutex->release();
+ }
+ else
+ {
+ mnCount--;
+ OMutex::release();
+ }
+ }
+ else
+ {
+ if ( mnCount == 1 )
+ mnThreadId = 0;
+ mnCount--;
+ OMutex::release();
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SAL_CALL SalYieldMutex::tryToAcquire()
+{
+ if( OMutex::tryToAcquire() )
+ {
+ mnCount++;
+#ifdef WIN
+ mnThreadId = GetCurrentThreadId();
+#endif
+ return True;
+ }
+ else
+ return False;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalYieldMutex::GetAcquireCount( ULONG nThreadId )
+{
+ if ( nThreadId == mnThreadId )
+ return mnCount;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexAcquireWithWait()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( !pInst )
+ return;
+
+ // If we are the main thread, then we must wait with wait, because
+ // in if we don't reschedule, then we create deadlocks if a Windows
+ // Function is called from another thread. If we arn't the main thread,
+ // than we call qcquire directly.
+#ifdef WIN
+ DWORD nThreadId = GetCurrentThreadId();
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mnAppThreadId == nThreadId )
+ {
+ // Wenn wir den Mutex nicht bekommen, muessen wir solange
+ // warten, bis wir Ihn bekommen
+ BOOL bAcquire = FALSE;
+ do
+ {
+ if ( pInst->maInstData.mpSalYieldMutex->tryToAcquire() )
+ bAcquire = TRUE;
+ else
+ {
+ pInst->maInstData.mpSalWaitMutex->acquire();
+ if ( pInst->maInstData.mpSalYieldMutex->tryToAcquire() )
+ {
+ bAcquire = TRUE;
+ pInst->maInstData.mpSalWaitMutex->release();
+ }
+ else
+ {
+ pInst->maInstData.mnYieldWaitCount++;
+ pInst->maInstData.mpSalWaitMutex->release();
+ MSG aTmpMsg;
+ ImplGetMessage( &aTmpMsg, pInst->maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD );
+ pInst->maInstData.mnYieldWaitCount--;
+ if ( pInst->maInstData.mnYieldWaitCount )
+ ImplPostMessage( pInst->maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
+ }
+ }
+ }
+ while ( !bAcquire );
+ }
+ else
+#endif
+ pInst->maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplSalYieldMutexTryToAcquire()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst )
+ return pInst->maInstData.mpSalYieldMutex->tryToAcquire();
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexAcquire()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst )
+ pInst->maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexRelease()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst )
+ pInst->maInstData.mpSalYieldMutex->release();
+}
+
+// -----------------------------------------------------------------------
+
+ULONG ImplSalReleaseYieldMutex()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( !pInst )
+ return 0;
+
+#ifdef WIN
+ SalYieldMutex* pYieldMutex = pInst->maInstData.mpSalYieldMutex;
+ ULONG nCount = pYieldMutex->GetAcquireCount( GetCurrentThreadId() );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+
+ return nCount;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalAcquireYieldMutex( ULONG nCount )
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( !pInst )
+ return;
+
+ SalYieldMutex* pYieldMutex = pInst->maInstData.mpSalYieldMutex;
+ while ( nCount )
+ {
+ pYieldMutex->acquire();
+ nCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+
+void ImplDbgTestSolarMutex()
+{
+#ifdef WIN
+ SalData* pSalData = GetSalData();
+ DWORD nCurThreadId = GetCurrentThreadId();
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" );
+ }
+ }
+ }
+ else
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked in the main thread" );
+ }
+ }
+ }
+#endif
+}
+
+#endif
+
+// =======================================================================
+
+static void InitSalShlData()
+{
+#ifdef WIN
+ aSalShlData.mnVKAdd = LOWORD( VkKeyScan( '+' ) );
+ aSalShlData.mnVKSubtract = LOWORD( VkKeyScan( '-' ) );
+ aSalShlData.mnVKMultiply = LOWORD( VkKeyScan( '*' ) );
+ aSalShlData.mnVKDivide = LOWORD( VkKeyScan( '/' ) );
+ aSalShlData.mnVKPoint = LOWORD( VkKeyScan( '.' ) );
+ aSalShlData.mnVKComma = LOWORD( VkKeyScan( ',' ) );
+ aSalShlData.mnVKLess = LOWORD( VkKeyScan( '<' ) );
+ aSalShlData.mnVKGreater = LOWORD( VkKeyScan( '>' ) );
+ aSalShlData.mnVKEqual = LOWORD( VkKeyScan( '=' ) );
+#endif
+}
+
+// =======================================================================
+
+void InitSalData()
+{
+ SalData* pSalData = new SalData;
+ memset( pSalData, 0, sizeof( SalData ) );
+ SetSalData( pSalData );
+#ifdef WIN
+ CoInitialize(0);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void DeInitSalData()
+{
+#ifdef WIN
+ CoUninitialize();
+#endif
+ SalData* pSalData = GetSalData();
+ delete pSalData;
+ SetSalData( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void SetFilterCallback( void* pCallback, void* pInst )
+{
+ SalData* pSalData = GetSalData();
+
+ pSalData->mpFirstInstance->maInstData.mpFilterCallback = pCallback;
+ pSalData->mpFirstInstance->maInstData.mpFilterInst = pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance* CreateSalInstance()
+{
+ SalData* pSalData = GetSalData();
+
+#ifdef WIN
+ // determine the windows version
+ WORD nVer = (WORD)GetVersion();
+ aSalShlData.mnVersion = (((WORD)LOBYTE(nVer)) * 100) + HIBYTE(nVer);
+ if ( aSalShlData.mnVersion >= W95_VERSION )
+ aSalShlData.mbW40 = 1;
+ WORD nVer = (WORD)GetVersion();
+ OSVERSIONINFO aVerInfo;
+ aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
+ if ( GetVersionEx( &aVerInfo ) )
+ {
+ if ( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
+ aSalShlData.mbWNT = 1;
+ }
+
+ pSalData->mnAppThreadId = GetCurrentThreadId();
+#endif
+
+ // register frame class
+ if ( !pSalData->mhPrevInst )
+ {
+#ifdef WIN
+ WNDCLASSEXA aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = CS_OWNDC;
+ aWndClassEx.lpfnWndProc = SalFrameWndProcA;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hCursor = 0;
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEA;
+ ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm );
+ if ( !RegisterClassExA( &aWndClassEx ) )
+ return NULL;
+ aWndClassEx.style |= CS_SAVEBITS;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAME_SBA;
+ if ( !RegisterClassExA( &aWndClassEx ) )
+ return NULL;
+
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalComWndProcA;
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEA;
+ if ( !RegisterClassExA( &aWndClassEx ) )
+ return NULL;
+#endif
+ }
+
+ HWND hComWnd;
+#ifdef WIN
+ hComWnd = CreateWindowExA( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEA,
+ "", WS_POPUP, 0, 0, 0, 0, 0, 0,
+ pSalData->mhInst, NULL );
+#endif
+ if ( !hComWnd )
+ return NULL;
+
+ SalInstance* pInst = new SalInstance;
+
+ // init shl data
+ InitSalShlData();
+
+ // init instance (only one instance in this version !!!)
+ pSalData->mpFirstInstance = pInst;
+ pInst->maInstData.mhInst = pSalData->mhInst;
+ pInst->maInstData.mhComWnd = hComWnd;
+
+ // init static GDI Data
+ ImplInitSalGDI();
+
+ return pInst;
+}
+
+// -----------------------------------------------------------------------
+
+void DestroySalInstance( SalInstance* pInst )
+{
+ SalData* pSalData = GetSalData();
+
+ // (only one instance in this version !!!)
+
+ ImplFreeSalGDI();
+
+ // reset instance
+ if ( pSalData->mpFirstInstance == pInst )
+ pSalData->mpFirstInstance = NULL;
+
+ delete pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::SalInstance()
+{
+ maInstData.mhComWnd = 0;
+ maInstData.mpFilterCallback = NULL;
+ maInstData.mpFilterInst = NULL;
+ maInstData.mpSalYieldMutex = new SalYieldMutex( &maInstData );
+ maInstData.mpSalWaitMutex = new NAMESPACE_VOS(OMutex);
+ maInstData.mnYieldWaitCount = 0;
+ maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::~SalInstance()
+{
+ maInstData.mpSalYieldMutex->release();
+ delete maInstData.mpSalYieldMutex;
+ delete maInstData.mpSalWaitMutex;
+#ifdef WIN
+ DestroyWindow( maInstData.mhComWnd );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef _VOS_NO_NAMESPACE
+IMutex* SalInstance::GetYieldMutex()
+#else
+vos::IMutex* SalInstance::GetYieldMutex()
+#endif
+{
+ return maInstData.mpSalYieldMutex;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInstance::ReleaseYieldMutex()
+{
+ return ImplSalReleaseYieldMutex();
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::AcquireYieldMutex( ULONG nCount )
+{
+ ImplSalAcquireYieldMutex( nCount );
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+static void ImplSalDispatchMessage( MSG* pMsg )
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstObject )
+ {
+ if ( ImplSalPreDispatchMsg( pMsg ) )
+ return;
+ }
+ LRESULT lResult = ImplDispatchMessage( pMsg );
+ if ( pSalData->mpFirstObject )
+ ImplSalPostDispatchMsg( pMsg, lResult );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+void ImplSalYield( BOOL bWait )
+{
+#ifdef WIN
+ MSG aMsg;
+
+ if ( bWait )
+ {
+ if ( ImplGetMessage( &aMsg, 0, 0, 0 ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplSalDispatchMessage( &aMsg );
+ }
+ }
+ else
+ {
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplSalDispatchMessage( &aMsg );
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::Yield( BOOL bWait )
+{
+#ifdef WIN
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ SalData* pSalData = GetSalData();
+ DWORD nCurThreadId = GetCurrentThreadId();
+ ULONG nCount = pYieldMutex->GetAcquireCount( nCurThreadId );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ ImplSendMessage( maInstData.mhComWnd, SAL_MSG_THREADYIELD, (WPARAM)bWait, (LPARAM)0 );
+ n = nCount;
+ while ( n )
+ {
+ pYieldMutex->acquire();
+ n--;
+ }
+ }
+ else
+ {
+ ImplSalYield( bWait );
+
+ n = nCount;
+ while ( n )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ n--;
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalComWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ LRESULT nRet = 0;
+
+#ifdef WIN
+ switch ( nMsg )
+ {
+ case SAL_MSG_PRINTABORTJOB:
+ ImplSalPrinterAbortJobAsync( (HDC)wParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_THREADYIELD:
+ ImplSalYield( (BOOL)wParam );
+ rDef = FALSE;
+ break;
+ // If we get this message, because another GetMessage() call
+ // has recieved this message, we must post this message to
+ // us again, because in the other case we wait forever.
+ case SAL_MSG_RELEASEWAITYIELD:
+ {
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst && pInst->maInstData.mnYieldWaitCount )
+ ImplPostMessage( hWnd, SAL_MSG_RELEASEWAITYIELD, wParam, lParam );
+ }
+ rDef = FALSE;
+ break;
+ case SAL_MSG_STARTTIMER:
+ ImplSalStartTimer( (ULONG) lParam, FALSE );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_CREATEFRAME:
+ nRet = (LRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, (HWND)lParam, (ULONG)wParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_DESTROYFRAME:
+ delete (SalFrame*)lParam;
+ rDef = FALSE;
+ break;
+ case SAL_MSG_CREATEOBJECT:
+ nRet = (LRESULT)ImplSalCreateObject( GetSalData()->mpFirstInstance, (SalFrame*)lParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_DESTROYOBJECT:
+ delete (SalObject*)lParam;
+ rDef = FALSE;
+ break;
+ case SAL_MSG_CREATESOUND:
+ nRet = ((SalSound*)lParam)->ImplCreate();
+ rDef = FALSE;
+ break;
+ case SAL_MSG_DESTROYSOUND:
+ ((SalSound*)lParam)->ImplDestroy();
+ rDe
+ break;
+ }
+#endif
+
+ return nRet;
+}
+
+#ifdef WIN
+LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ {
+ if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ }
+ return nRet;
+}
+#endif
+
+#ifdef WIN
+LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ {
+ if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ }
+ return nRet;
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+BOOL SalInstance::AnyInput( USHORT nType )
+{
+#ifdef WIN
+ MSG aMsg;
+
+ if ( (nType & (INPUT_ANY)) == (INPUT_ANY) )
+ {
+ // Any Input
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+ else
+ {
+ if ( nType & INPUT_MOUSE )
+ {
+ // Test auf Mouseinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_MOUSEFIRST, WM_MOUSELAST,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_KEYBOARD )
+ {
+ // Test auf Keyinput
+#ifdef WIN
+ if ( ImplPeekMessage( &aMsg, 0, WM_KEYDOWN, WM_KEYDOWN,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ {
+ if ( (aMsg.wParam == VK_SHIFT) ||
+ (aMsg.wParam == VK_CONTROL) ||
+ (aMsg.wParam == VK_MENU) )
+ return FALSE;
+ else
+ return TRUE;
+ }
+#endif
+ }
+
+ if ( nType & INPUT_PAINT )
+ {
+ // Test auf Paintinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_PAINT, WM_PAINT,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_TIMER )
+ {
+ // Test auf Timerinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_TIMER, WM_TIMER,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_OTHER )
+ {
+ // Test auf sonstigen Input
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+ }
+#endif
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::Start( ULONG nMS )
+{
+ // Um auf Main-Thread umzuschalten
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstInstance )
+ {
+#ifdef WIN
+ if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
+ ImplPostMessage( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
+ else
+ ImplSendMessage( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
+#endif
+ }
+ else
+ ImplSalStartTimer( nMS, FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* SalInstance::CreateChildFrame( SystemParentData* pSystemParentData, ULONG nSalFrameStyle )
+{
+ // Um auf Main-Thread umzuschalten
+#ifdef WIN
+ return (SalFrame*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)pSystemParentData->hWnd );
+#else
+ return NULL;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* SalInstance::CreateFrame( SalFrame* pParent, ULONG nSalFrameStyle )
+{
+ // Um auf Main-Thread umzuschalten
+ HWND hWndParent;
+ if ( pParent )
+ hWndParent = pParent->maFrameData.mhWnd;
+ else
+ hWndParent = 0;
+#ifdef WIN
+ return (SalFrame*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)hWndParent );
+#else
+ return NULL;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyFrame( SalFrame* pFrame )
+{
+#ifdef WIN
+ ImplSendMessage( maInstData.mhComWnd, SAL_MSG_DESTROYFRAME, 0, (LPARAM)pFrame );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+SalObject* SalInstance::CreateObject( SalFrame* pParent )
+{
+ // Um auf Main-Thread umzuschalten
+#ifdef WIN
+ return (SalObject*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEOBJECT, 0, (LPARAM)pParent );
+#else
+ return NULL;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyObject( SalObject* pObject )
+{
+#ifdef WIN
+ ImplSendMessage( maInstData.mhComWnd, SAL_MSG_DESTROYOBJECT, 0, (LPARAM)pObject );
+#endif
+}
diff --git a/vcl/aqua/source/app/salsys.cxx b/vcl/aqua/source/app/salsys.cxx
new file mode 100644
index 000000000000..be5914ba7d9e
--- /dev/null
+++ b/vcl/aqua/source/app/salsys.cxx
@@ -0,0 +1,202 @@
+/*************************************************************************
+ *
+ * $RCSfile: salsys.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#define _SV_SALSYS_CXX
+
+#ifndef _SV_SALAQUA_HXX
+#include <salaqua.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+
+#ifndef _SV_KEYCOES_HXX
+#include <keycodes.hxx>
+#endif
+
+// =======================================================================
+
+SalSystem* SalInstance::CreateSystem()
+{
+ return new SalSystem();
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroySystem( SalSystem* pSystem )
+{
+ delete pSystem;
+}
+
+// =======================================================================
+
+SalSystem::SalSystem()
+{
+}
+
+// -----------------------------------------------------------------------
+
+SalSystem::~SalSystem()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalSystem::StartProcess( SalFrame* pFrame, const XubString& rFileName,
+ const XubString& rParam, const XubString& rWorkDir )
+{
+ return FALSE;
+ // !!! UNICODE Was ist ... --> Mit HRO nach seinem Urlaub klaeren
+/*
+ XubString aParam = rParam;
+ XubString aFileName = rFileName;
+
+ // HRO: #75283#
+ // Hack for Office2000 Links
+ // We can only start the lnk-file, so we packed it within the arguments
+ xub_StrLen nIndex = aParam.Search( (sal_Unicode)0x07 );
+ if ( nIndex != STRING_NOTFOUND )
+ {
+ aFileName = aParam.Copy( nIndex + 1 );
+ aParam.Erase( nIndex );
+ }
+
+ BOOL bSuccess;
+ if ( aSalShlData.mbWNT )
+ {
+ LPCWSTR pszWorkDir = NULL;
+ if ( rWorkDir.Len() )
+ pszWorkDir = rWorkDir.GetBuffer();
+ bSuccess = SHInvokeCommandW( pFrame->maFrameData.mhWnd, 0,
+ aFileName.GetBuffer(),
+ CMDSTR_DEFAULT,
+ aParam.GetBuffer(), pszWorkDir,
+ SW_SHOWNORMAL );
+ }
+ else
+ {
+ ByteString aFileNameA = ImplSalGetWinAnsiString( aFileName, TRUE );
+ ByteString aParamA = ImplSalGetWinAnsiString( aParam, TRUE );
+ ByteString aWorkDirA = ImplSalGetWinAnsiString( rWorkDir, TRUE );
+ LPCSTR pszWorkDir = NULL;
+ if ( aWorkDirA.Len() )
+ pszWorkDir = aWorkDirA.GetBuffer();
+ bSuccess = SHInvokeCommandA( pFrame->maFrameData.mhWnd, 0,
+ aFileNameA.GetBuffer(),
+ CMDSTR_DEFAULT,
+ aParamA.GetBuffer(), pszWorkDir,
+ SW_SHOWNORMAL );
+ }
+*/
+/*
+ // HRO: Tasks #62485# #64619#
+ // Weil ein paar Naddels jeden Scheiss hier reinstopfen und sich nicht
+ // entscheiden koennen, was sie wie und wann aufrufen, darf ich
+ // um die BUGs drumrumkurven. GRRRRR !!!
+
+ if ( !bSuccess )
+ {
+ ItemIDPath aIDPath( aFileName );
+
+ if ( aIDPath.GetTokenCount() )
+ bSuccess = WIN_SHInvokeCommand( pFrame->maFrameData.mhWnd, SHIC_PIDL,
+ (LPCTSTR)aIDPath.GetDataPtr(), CMDSTR_DEFAULT, aParam.GetStr(),
+ pszWorkDir, SW_SHOWNORMAL );
+ }
+*/
+// return bSuccess;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalSystem::AddRecentDoc( SalFrame*, const XubString& rFileName )
+{
+ return FALSE;
+ // !!! UNICODE Was ist ... --> Mit HRO nach seinem Urlaub klaeren
+/*
+ if ( aSalShlData.mbWNT )
+ SHAddToRecentDocsW( SHARD_PATH, (LPCVOID)rFileName.GetBuffer() );
+ else
+ {
+ ByteString aFileNameA = ImplSalGetWinAnsiString( rFileName, TRUE );
+ SHAddToRecentDocsA( SHARD_PATH, (LPCVOID)aFileNameA.GetBuffer() );
+ }
+ return TRUE;
+*/
+}
diff --git a/vcl/aqua/source/app/saltimer.cxx b/vcl/aqua/source/app/saltimer.cxx
new file mode 100644
index 000000000000..f55bbc77d34e
--- /dev/null
+++ b/vcl/aqua/source/app/saltimer.cxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * $RCSfile: saltimer.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALTIMER_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+
+// =======================================================================
+
+// Maximale Periode
+#define MAX_SYSPERIOD 65533
+
+// =======================================================================
+
+void ImplSalStartTimer( ULONG nMS, BOOL bMutex )
+{
+ SalData* pSalData = GetSalData();
+
+ // Remenber the time of the timer
+ pSalData->mnTimerMS = nMS;
+ if ( !bMutex )
+ pSalData->mnTimerOrgMS = nMS;
+
+ // Periode darf nicht zu gross sein, da Windows mit USHORT arbeitet
+ if ( nMS > MAX_SYSPERIOD )
+ nMS = MAX_SYSPERIOD;
+
+#ifdef WIN
+ // Gibt es einen Timer, dann zerstoren
+ if ( pSalData->mnTimerId )
+ KillTimer( 0, pSalData->mnTimerId );
+
+ // Make a new timer with new period
+ pSalData->mnTimerId = SetTimer( 0, 0, (UINT)nMS, SalTimerProc );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::Stop()
+{
+ SalData* pSalData = GetSalData();
+
+#ifdef WIN
+ // If we have a timer, than
+ if ( pSalData->mnTimerId )
+ {
+ KillTimer( 0, pSalData->mnTimerId );
+ pSalData->mnTimerId = 0;
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::SetCallback( SALTIMERPROC pProc )
+{
+ SalData* pSalData = GetSalData();
+ pSalData->mpTimerProc = pProc;
+}
+
+// -----------------------------------------------------------------------
+
+void CALLBACK SalTimerProc( HWND, UINT, UINT, DWORD )
+{
+ SalData* pSalData = GetSalData();
+
+ // Test for MouseLeave
+ SalTestMouseLeave();
+
+ if ( pSalData->mpTimerProc )
+ {
+ // Try to aquire the mutex. If we don't get the mutex then we
+ // try this a short time later again.
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSalData->mpTimerProc();
+ ImplSalYieldMutexRelease();
+
+ // Run the timer in the correct time, if we start this
+ // with a small timeout, because we don't get the mutex
+ if ( pSalData->mnTimerId &&
+ (pSalData->mnTimerMS != pSalData->mnTimerOrgMS) )
+ ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE );
+ }
+ else
+ ImplSalStartTimer( 10, TRUE );
+ }
+}
diff --git a/vcl/aqua/source/gdi/makefile.mk b/vcl/aqua/source/gdi/makefile.mk
new file mode 100644
index 000000000000..b05c6a5db9a2
--- /dev/null
+++ b/vcl/aqua/source/gdi/makefile.mk
@@ -0,0 +1,113 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salgdi
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(OS)"!="MACOSX"
+
+dummy:
+ @echo "Nothing to build for this platform"
+
+.ELSE # "$(OS)"!="MACOSX"
+
+.IF "$(remote)"==""
+
+SLOFILES= $(SLO)$/salgdi.obj \
+ $(SLO)$/salgdi2.obj \
+ $(SLO)$/salgdi3.obj \
+ $(SLO)$/salvd.obj \
+ $(SLO)$/salprn.obj \
+ $(SLO)$/salbmp.obj \
+ $(SLO)$/salogl.obj
+
+.IF "$(UPDATER)"=="YES"
+OBJFILES= $(OBJ)$/salgdi.obj \
+ $(OBJ)$/salgdi2.obj \
+ $(OBJ)$/salgdi3.obj \
+ $(OBJ)$/salvd.obj \
+ $(OBJ)$/salprn.obj \
+ $(OBJ)$/salbmp.obj \
+ $(OBJ)$/salogl.obj
+.ENDIF
+
+.ENDIF
+
+.ENDIF # "$(OS)"!="MACOSX"
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
+
diff --git a/vcl/aqua/source/gdi/salbmp.cxx b/vcl/aqua/source/gdi/salbmp.cxx
new file mode 100644
index 000000000000..7802fb20e132
--- /dev/null
+++ b/vcl/aqua/source/gdi/salbmp.cxx
@@ -0,0 +1,686 @@
+/*************************************************************************
+ *
+ * $RCSfile: salbmp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALBMP_CXX
+
+#ifndef _SV_SALAQUA_HXX
+#include <salaqua.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#include <string.h>
+
+#ifdef WIN
+#define BI_BITFIELDS 3
+#endif
+
+// -----------
+// - Inlines -
+// -----------
+
+inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex )
+{
+ BYTE& rByte = pScanline[ nX >> 1 ];
+
+ ( nX & 1 ) ? ( rByte &= 0xf0, rByte |= ( cIndex & 0x0f ) ) :
+ ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) );
+}
+
+// -------------
+// - SalBitmap -
+// -------------
+
+SalBitmap::SalBitmap() :
+ mhDIB ( 0 ),
+ mhDDB ( 0 ),
+ mnBitCount ( 0 )
+{
+}
+
+// ------------------------------------------------------------------
+
+SalBitmap::~SalBitmap()
+{
+ Destroy();
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( HANDLE hBitmap, BOOL bDIB, BOOL bCopyHandle )
+{
+ BOOL bRet = TRUE;
+
+ if( bDIB )
+ mhDIB = (HGLOBAL) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, TRUE ) : hBitmap );
+ else
+ mhDDB = (HBITMAP) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, FALSE ) : hBitmap );
+
+#ifdef WIN
+ if( mhDIB )
+ {
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) GlobalLock( mhDIB );
+
+ maSize = Size( pBIH->biWidth, pBIH->biHeight );
+ mnBitCount = pBIH->biBitCount;
+
+ if( mnBitCount )
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 : ( mnBitCount <= 4 ) ? 4 : ( mnBitCount <= 8 ) ? 8 : 24;
+
+ GlobalUnlock( mhDIB );
+ }
+ else if( mhDDB )
+ {
+ BITMAP aDDBInfo;
+
+ if( WIN_GetObject( mhDDB, sizeof( BITMAP ), &aDDBInfo ) )
+ {
+ maSize = Size( aDDBInfo.bmWidth, aDDBInfo.bmHeight );
+ mnBitCount = aDDBInfo.bmPlanes * aDDBInfo.bmBitsPixel;
+
+ if( mnBitCount )
+ {
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 :
+ ( mnBitCount <= 4 ) ? 4 :
+ ( mnBitCount <= 8 ) ? 8 : 24;
+ }
+ }
+ else
+ {
+ mhDDB = 0;
+ bRet = FALSE;
+ }
+ }
+ else
+#endif
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal )
+{
+ BOOL bRet = FALSE;
+
+ mhDIB = ImplCreateDIB( rSize, nBitCount, rPal );
+
+ if( mhDIB )
+ {
+ maSize = rSize;
+ mnBitCount = nBitCount;
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBitmap )
+{
+ BOOL bRet = FALSE;
+
+ if ( rSalBitmap.mhDIB || rSalBitmap.mhDDB )
+ {
+ HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB,
+ rSalBitmap.mhDIB != 0 );
+
+ if ( hNewHdl )
+ {
+ if( rSalBitmap.mhDIB )
+ mhDIB = (HGLOBAL) hNewHdl;
+ else if( rSalBitmap.mhDDB )
+ mhDDB = (HBITMAP) hNewHdl;
+
+ maSize = rSalBitmap.maSize;
+ mnBitCount = rSalBitmap.mnBitCount;
+
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
+{
+ BOOL bRet = FALSE;
+
+ if( rSalBmp.mhDIB )
+ {
+#ifdef WIN
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( rSalBmp.mhDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+ HDC hDC = pGraphics->maGraphicsData.mhDC;
+ HBITMAP hNewDDB;
+ BITMAP aDDBInfo;
+ PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
+ ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGBQUAD );
+
+ if( pBIH->biBitCount == 1 )
+ {
+ hNewDDB = CreateBitmap( pBIH->biWidth, pBIH->biHeight, 1, 1, NULL );
+
+ if( hNewDDB )
+ SetDIBits( hDC, hNewDDB, 0, pBIH->biHeight, pBits, pBI, DIB_RGB_COLORS );
+ }
+ else
+ hNewDDB = CreateDIBitmap( hDC, (PBITMAPINFOHEADER) pBI, CBM_INIT, pBits, pBI, DIB_RGB_COLORS );
+
+ GlobalUnlock( rSalBmp.mhDIB );
+
+ if( hNewDDB && WIN_GetObject( hNewDDB, sizeof( BITMAP ), &aDDBInfo ) )
+ {
+ mhDDB = hNewDDB;
+ maSize = Size( aDDBInfo.bmWidth, aDDBInfo.bmHeight );
+ mnBitCount = aDDBInfo.bmPlanes * aDDBInfo.bmBitsPixel;
+
+ if( mnBitCount )
+ {
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 :
+ ( mnBitCount <= 4 ) ? 4 :
+ ( mnBitCount <= 8 ) ? 8 : 24;
+ }
+
+ bRet = TRUE;
+ }
+ else if( hNewDDB )
+ DeleteObject( hNewDDB );
+#endif
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, USHORT nNewBitCount )
+{
+ BOOL bRet = FALSE;
+
+ if( rSalBmp.mhDDB )
+ {
+ mhDIB = ImplCreateDIB( rSalBmp.maSize, nNewBitCount, BitmapPalette() );
+
+ if( mhDIB )
+ {
+#ifdef WIN
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
+ const int nLines = (int) rSalBmp.maSize.Height();
+ HDC hDC = GetDC( 0 );
+ PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
+ ImplGetDIBColorCount( mhDIB ) * sizeof( RGBQUAD );
+ SalData* pSalData = GetSalData();
+ HPALETTE hOldPal = 0;
+
+ if ( pSalData->mhDitherPal )
+ {
+ hOldPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( hDC );
+ }
+
+ if( GetDIBits( hDC, rSalBmp.mhDDB, 0, nLines, pBits, pBI, DIB_RGB_COLORS ) == nLines )
+ {
+ GlobalUnlock( mhDIB );
+ maSize = rSalBmp.maSize;
+ mnBitCount = nNewBitCount;
+ bRet = TRUE;
+ }
+ else
+ {
+ GlobalUnlock( mhDIB );
+ GlobalFree( mhDIB );
+ mhDIB = 0;
+ }
+
+ if( hOldPal )
+ SelectPalette( hDC, hOldPal, TRUE );
+
+ ReleaseDC( 0, hDC );
+#endif
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::Destroy()
+{
+#ifdef WIN
+ if( mhDIB )
+ GlobalFree( mhDIB );
+ else if( mhDDB )
+ DeleteObject( mhDDB );
+#endif
+
+ maSize = Size();
+ mnBitCount = 0;
+}
+
+// ------------------------------------------------------------------
+
+USHORT SalBitmap::ImplGetDIBColorCount( HGLOBAL hDIB )
+{
+ USHORT nColors = 0;
+
+ if( hDIB )
+ {
+#ifdef WIN
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+
+ if ( pBIH->biSize != sizeof( BITMAPCOREHEADER ) )
+ {
+ if( pBIH->biBitCount <= 8 )
+ {
+ if ( pBIH->biClrUsed )
+ nColors = (USHORT) pBIH->biClrUsed;
+ else
+ nColors = 1 << pBIH->biBitCount;
+ }
+ }
+ else if( ( (PBITMAPCOREHEADER) pBI )->bcBitCount <= 8 )
+ nColors = 1 << ( (PBITMAPCOREHEADER) pBI )->bcBitCount;
+
+ GlobalUnlock( hDIB );
+#endif
+ }
+
+ return nColors;
+}
+
+// ------------------------------------------------------------------
+
+HGLOBAL SalBitmap::ImplCreateDIB( const Size& rSize, USHORT nBits, const BitmapPalette& rPal )
+{
+ DBG_ASSERT( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24, "Unsupported BitCount!" );
+
+ HGLOBAL hDIB = 0;
+
+ if ( rSize.Width() && rSize.Height() && ( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24 ) )
+ {
+#ifdef WIN
+ const ULONG nImageSize = AlignedWidth4Bytes( nBits * rSize.Width() ) * rSize.Height();
+ const USHORT nColors = ( nBits <= 8 ) ? ( 1 << nBits ) : 0;
+
+ hDIB = GlobalAlloc( GHND, sizeof( BITMAPINFOHEADER ) + nColors * sizeof( RGBQUAD ) + nImageSize );
+
+ if( hDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+
+ pBIH->biSize = sizeof( BITMAPINFOHEADER );
+ pBIH->biWidth = rSize.Width();
+ pBIH->biHeight = rSize.Height();
+ pBIH->biPlanes = 1;
+ pBIH->biBitCount = nBits;
+ pBIH->biCompression = BI_RGB;
+ pBIH->biSizeImage = nImageSize;
+ pBIH->biXPelsPerMeter = 0;
+ pBIH->biYPelsPerMeter = 0;
+ pBIH->biClrUsed = 0;
+ pBIH->biClrImportant = 0;
+
+ if ( nColors )
+ {
+ const USHORT nMinCount = Min( nColors, rPal.GetEntryCount() );
+
+ if( nMinCount )
+ HMEMCPY( pBI->bmiColors, rPal.ImplGetColorBuffer(), nMinCount * sizeof( RGBQUAD ) );
+ }
+
+ GlobalUnlock( hDIB );
+ }
+#endif
+ }
+
+ return hDIB;
+}
+
+// ------------------------------------------------------------------
+
+HANDLE SalBitmap::ImplCopyDIBOrDDB( HANDLE hHdl, BOOL bDIB )
+{
+ HANDLE hCopy = 0;
+
+#ifdef WIN
+ if ( bDIB && hHdl )
+ {
+ const ULONG nSize = GlobalSize( hHdl );
+
+ if ( hCopy = GlobalAlloc( GHND, nSize ) )
+ {
+ HMEMCPY( (LPSTR) GlobalLock( hCopy ), (LPSTR) GlobalLock( hHdl ), nSize );
+
+ GlobalUnlock( hCopy );
+ GlobalUnlock( hHdl );
+ }
+ }
+ else if ( hHdl )
+ {
+ BITMAP aBmp;
+
+ // Source-Bitmap nach Groesse befragen
+ WIN_GetObject( hHdl, sizeof( BITMAP ), (LPSTR) &aBmp );
+
+ // Destination-Bitmap erzeugen
+ if ( hCopy = CreateBitmapIndirect( &aBmp ) )
+ {
+ HDC hBmpDC = CreateCompatibleDC( 0 );
+ HBITMAP hBmpOld = (HBITMAP) SelectObject( hBmpDC, hHdl );
+ HDC hCopyDC = CreateCompatibleDC( hBmpDC );
+ HBITMAP hCopyOld = (HBITMAP) SelectObject( hCopyDC, hCopy );
+
+ BitBlt( hCopyDC, 0, 0, aBmp.bmWidth, aBmp.bmHeight, hBmpDC, 0, 0, SRCCOPY );
+
+ SelectObject( hCopyDC, hCopyOld );
+ DeleteDC( hCopyDC );
+
+ SelectObject( hBmpDC, hBmpOld );
+ DeleteDC( hBmpDC );
+ }
+ }
+#endif
+
+ return hCopy;
+}
+
+// ------------------------------------------------------------------
+
+BitmapBuffer* SalBitmap::AcquireBuffer( BOOL bReadOnly )
+{
+ BitmapBuffer* pBuffer = NULL;
+
+ if( mhDIB )
+ {
+#ifdef WIN
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+
+ if( ( pBIH->biCompression == BI_RLE4 ) || ( pBIH->biCompression == BI_RLE8 ) )
+ {
+ Size aSizePix( pBIH->biWidth, pBIH->biHeight );
+ HGLOBAL hNewDIB = ImplCreateDIB( aSizePix, pBIH->biBitCount, BitmapPalette() );
+
+ if( hNewDIB )
+ {
+ PBITMAPINFO pNewBI = (PBITMAPINFO) GlobalLock( hNewDIB );
+ PBITMAPINFOHEADER pNewBIH = (PBITMAPINFOHEADER) pNewBI;
+ const USHORT nColorCount = ImplGetDIBColorCount( hNewDIB );
+ const ULONG nOffset = *(DWORD*) pBI + nColorCount * sizeof( RGBQUAD );
+ BYTE* pOldBits = (PBYTE) pBI + nOffset;
+ BYTE* pNewBits = (PBYTE) pNewBI + nOffset;
+
+ HMEMCPY( pNewBI, pBI, nOffset );
+ pNewBIH->biCompression = 0;
+ ImplDecodeRLEBuffer( pOldBits, pNewBits, aSizePix, pBIH->biCompression == BI_RLE4 );
+
+ GlobalUnlock( mhDIB );
+ GlobalFree( mhDIB );
+ mhDIB = hNewDIB;
+ pBI = pNewBI;
+ pBIH = pNewBIH;
+ }
+ }
+
+ if( pBIH->biPlanes == 1 )
+ {
+ pBuffer = new BitmapBuffer;
+
+ pBuffer->mnFormat = BMP_FORMAT_BOTTOM_UP |
+ ( pBIH->biBitCount == 1 ? BMP_FORMAT_1BIT_MSB_PAL :
+ pBIH->biBitCount == 4 ? BMP_FORMAT_4BIT_MSN_PAL :
+ pBIH->biBitCount == 8 ? BMP_FORMAT_8BIT_PAL :
+ pBIH->biBitCount == 16 ? BMP_FORMAT_16BIT_TC_MASK :
+ pBIH->biBitCount == 24 ? BMP_FORMAT_24BIT_TC_BGR :
+ pBIH->biBitCount == 32 ? BMP_FORMAT_32BIT_TC_MASK : 0UL );
+
+ if( BMP_SCANLINE_FORMAT( pBuffer->mnFormat ) )
+ {
+ pBuffer->mnWidth = maSize.Width();
+ pBuffer->mnHeight = maSize.Height();
+ pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->biBitCount );
+ pBuffer->mnBitCount = (USHORT) pBIH->biBitCount;
+
+ if( pBuffer->mnBitCount <= 8 )
+ {
+ const USHORT nPalCount = ImplGetDIBColorCount( mhDIB );
+
+ pBuffer->maPalette.SetEntryCount( nPalCount );
+ HMEMCPY( pBuffer->maPalette.ImplGetColorBuffer(), pBI->bmiColors, nPalCount * sizeof( RGBQUAD ) );
+ pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI + nPalCount * sizeof( RGBQUAD );
+ }
+ else if( ( pBIH->biBitCount == 16 ) || ( pBIH->biBitCount == 32 ) )
+ {
+ ULONG nOffset = 0UL;
+
+ if( pBIH->biCompression == BI_BITFIELDS )
+ {
+ nOffset = 3 * sizeof( RGBQUAD );
+ pBuffer->maColorMask = ColorMask( *(UINT32*) &pBI->bmiColors[ 0 ],
+ *(UINT32*) &pBI->bmiColors[ 1 ],
+ *(UINT32*) &pBI->bmiColors[ 2 ] );
+ }
+ else if( pBIH->biCompression == 16 )
+ pBuffer->maColorMask = ColorMask( 0x00007c00UL, 0x000003e0UL, 0x0000001fUL );
+ else
+ pBuffer->maColorMask = ColorMask( 0x00ff0000UL, 0x0000ff00UL, 0x000000ffUL );
+
+ pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI + nOffset;
+ }
+ else
+ pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI;
+ }
+ else
+ {
+ GlobalUnlock( mhDIB );
+ delete pBuffer;
+ pBuffer = NULL;
+ }
+ }
+ else
+ GlobalUnlock( mhDIB );
+#endif
+ }
+
+ return pBuffer;
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BOOL bReadOnly )
+{
+ if( pBuffer )
+ {
+ if( mhDIB )
+ {
+#ifdef WIN
+ if( !bReadOnly && !!pBuffer->maPalette )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
+ const USHORT nCount = pBuffer->maPalette.GetEntryCount();
+
+ HMEMCPY( pBI->bmiColors, pBuffer->maPalette.ImplGetColorBuffer(), nCount * sizeof( RGBQUAD ) );
+ GlobalUnlock( mhDIB );
+ }
+
+ GlobalUnlock( mhDIB );
+#endif
+ }
+
+ delete pBuffer;
+ }
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::ImplDecodeRLEBuffer( const BYTE* pSrcBuf, BYTE* pDstBuf,
+ const Size& rSizePixel, BOOL bRLE4 )
+{
+ HPBYTE pRLE = (HPBYTE) pSrcBuf;
+ HPBYTE pDIB = (HPBYTE) pDstBuf;
+ HPBYTE pRow = (HPBYTE) pDstBuf;
+ ULONG nWidthAl = AlignedWidth4Bytes( rSizePixel.Width() * ( bRLE4 ? 4UL : 8UL ) );
+ HPBYTE pLast = pDIB + rSizePixel.Height() * nWidthAl - 1;
+ ULONG nCountByte;
+ ULONG nRunByte;
+ ULONG nX = 0;
+ ULONG i;
+ BYTE cTmp;
+ BOOL bEndDecoding = FALSE;
+
+ if( pRLE && pDIB )
+ {
+ do
+ {
+ if( !( nCountByte = *pRLE++ ) )
+ {
+ nRunByte = *pRLE++;
+
+ if( nRunByte > 2UL )
+ {
+ if( bRLE4 )
+ {
+ nCountByte = nRunByte >> 1UL;
+
+ for( i = 0; i < nCountByte; i++ )
+ {
+ cTmp = *pRLE++;
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
+ }
+
+ if( nRunByte & 1 )
+ ImplSetPixel4( pDIB, nX++, *pRLE++ >> 4 );
+
+ if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
+ pRLE++;
+ }
+ else
+ {
+ HMEMCPY( &pDIB[ nX ], pRLE, nRunByte );
+ pRLE += nRunByte;
+ nX += nRunByte;
+
+ if( nRunByte & 1 )
+ pRLE++;
+ }
+ }
+ else if( !nRunByte )
+ {
+ pDIB = ( pRow += nWidthAl );
+ nX = 0UL;
+ }
+ else if( nRunByte == 1 )
+ bEndDecoding = TRUE;
+ else
+ {
+ nX += *pRLE++;
+ pDIB = ( pRow += ( *pRLE++ ) * nWidthAl );
+ }
+ }
+ else
+ {
+ cTmp = *pRLE++;
+
+ if( bRLE4 )
+ {
+ nRunByte = nCountByte >> 1;
+
+ for( i = 0; i < nRunByte; i++ )
+ {
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
+ }
+
+ if( nCountByte & 1 )
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ }
+ else
+ {
+ for( i = 0; i < nCountByte; i++ )
+ pDIB[ nX++ ] = cTmp;
+ }
+ }
+ }
+ while( !bEndDecoding && ( pDIB <= pLast ) );
+ }
+}
diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx
new file mode 100644
index 000000000000..18e82f845f0f
--- /dev/null
+++ b/vcl/aqua/source/gdi/salgdi.cxx
@@ -0,0 +1,1536 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+#define _SV_SALGDI_CXX
+
+#ifndef _SV_SALAQUA_HXX
+#include <salaqua.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// =======================================================================
+
+#define DITHER_PAL_DELTA 51
+#define DITHER_PAL_STEPS 6
+#define DITHER_PAL_COUNT (DITHER_PAL_STEPS*DITHER_PAL_STEPS*DITHER_PAL_STEPS)
+#define DITHER_MAX_SYSCOLOR 16
+#define DITHER_EXTRA_COLORS 1
+#define DMAP( _def_nVal, _def_nThres ) ((pDitherDiff[_def_nVal]>(_def_nThres))?pDitherHigh[_def_nVal]:pDitherLow[_def_nVal])
+
+// =======================================================================
+
+struct SysColorEntry
+{
+ DWORD nRGB;
+ SysColorEntry* pNext;
+};
+
+// =======================================================================
+
+static SysColorEntry* pFirstSysColor = NULL;
+static SysColorEntry* pActSysColor = NULL;
+
+// -----------------------------------------------------------------------------
+
+// Blue7
+#ifdef WIN
+static PALETTEENTRY aImplExtraColor1 =
+{
+ 0, 184, 255, 0
+};
+#endif
+
+// -----------------------------------------------------------------------------
+
+#ifdef WIN
+static PALETTEENTRY aImplSalSysPalEntryAry[ DITHER_MAX_SYSCOLOR ] =
+{
+{ 0, 0, 0, 0 },
+{ 0, 0, 0x80, 0 },
+{ 0, 0x80, 0, 0 },
+{ 0, 0x80, 0x80, 0 },
+{ 0x80, 0, 0, 0 },
+{ 0x80, 0, 0x80, 0 },
+{ 0x80, 0x80, 0, 0 },
+{ 0x80, 0x80, 0x80, 0 },
+{ 0xC0, 0xC0, 0xC0, 0 },
+{ 0, 0, 0xFF, 0 },
+{ 0, 0xFF, 0, 0 },
+{ 0, 0xFF, 0xFF, 0 },
+{ 0xFF, 0, 0, 0 },
+{ 0xFF, 0, 0xFF, 0 },
+{ 0xFF, 0xFF, 0, 0 },
+{ 0xFF, 0xFF, 0xFF, 0 }
+};
+#endif
+
+// -----------------------------------------------------------------------------
+
+static BYTE aOrdDither8Bit[8][8] =
+{
+ 0, 38, 9, 48, 2, 40, 12, 50,
+ 25, 12, 35, 22, 28, 15, 37, 24,
+ 6, 44, 3, 41, 8, 47, 5, 44,
+ 32, 19, 28, 16, 34, 21, 31, 18,
+ 1, 40, 11, 49, 0, 39, 10, 48,
+ 27, 14, 36, 24, 26, 13, 36, 23,
+ 8, 46, 4, 43, 7, 45, 4, 42,
+ 33, 20, 30, 17, 32, 20, 29, 16
+};
+
+// -----------------------------------------------------------------------------
+
+static BYTE aOrdDither16Bit[8][8] =
+{
+ 0, 6, 1, 7, 0, 6, 1, 7,
+ 4, 2, 5, 3, 4, 2, 5, 3,
+ 1, 7, 0, 6, 1, 7, 0, 6,
+ 5, 3, 4, 2, 5, 3, 4, 2,
+ 0, 6, 1, 7, 0, 6, 1, 7,
+ 4, 2, 5, 3, 4, 2, 5, 3,
+ 1, 7, 0, 6, 1, 7, 0, 6,
+ 5, 3, 4, 2, 5, 3, 4, 2
+};
+
+// =======================================================================
+
+// Pens muessen wir mit 1 Pixel-Breite erzeugen, da ansonsten die S3-Karte
+// viele Paintprobleme hat, wenn Polygone/PolyLines gezeichnet werden und
+// eine komplexe ClipRegion gesetzt ist
+#define GSL_PEN_WIDTH 1
+
+// =======================================================================
+
+#define SAL_POLYPOLYCOUNT_STACKBUF 8
+#define SAL_POLYPOLYPOINTS_STACKBUF 64
+
+// =======================================================================
+
+void ImplInitSalGDI()
+{
+ SalData* pSalData = GetSalData();
+
+#ifdef WIN
+ // init stock brushes
+ pSalData->maStockPenColorAry[0] = PALETTERGB( 0, 0, 0 );
+ pSalData->maStockPenColorAry[1] = PALETTERGB( 0xFF, 0xFF, 0xFF );
+ pSalData->maStockPenColorAry[2] = PALETTERGB( 0xC0, 0xC0, 0xC0 );
+ pSalData->maStockPenColorAry[3] = PALETTERGB( 0x80, 0x80, 0x80 );
+ pSalData->mhStockPenAry[0] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[0] );
+ pSalData->mhStockPenAry[1] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[1] );
+ pSalData->mhStockPenAry[2] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[2] );
+ pSalData->mhStockPenAry[3] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[3] );
+ pSalData->mnStockPenCount = 4;
+
+ pSalData->maStockBrushColorAry[0] = PALETTERGB( 0, 0, 0 );
+ pSalData->maStockBrushColorAry[1] = PALETTERGB( 0xFF, 0xFF, 0xFF );
+ pSalData->maStockBrushColorAry[2] = PALETTERGB( 0xC0, 0xC0, 0xC0 );
+ pSalData->maStockBrushColorAry[3] = PALETTERGB( 0x80, 0x80, 0x80 );
+ pSalData->mhStockBrushAry[0] = CreateSolidBrush( pSalData->maStockBrushColorAry[0] );
+ pSalData->mhStockBrushAry[1] = CreateSolidBrush( pSalData->maStockBrushColorAry[1] );
+ pSalData->mhStockBrushAry[2] = CreateSolidBrush( pSalData->maStockBrushColorAry[2] );
+ pSalData->mhStockBrushAry[3] = CreateSolidBrush( pSalData->maStockBrushColorAry[3] );
+ pSalData->mnStockBrushCount = 4;
+#endif
+
+ // DC-Cache aufbauen
+ pSalData->mpHDCCache = new HDCCache[ CACHESIZE_HDC ];
+ memset( pSalData->mpHDCCache, 0, CACHESIZE_HDC * sizeof( HDCCache ) );
+
+#ifdef WIN
+ // Nur bei 256 Farben Displays, die Paletten unterstuetzen
+ HDC hDC = GetDC( 0 );
+ int nBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
+ int nPlanes = GetDeviceCaps( hDC, PLANES );
+ int nRasterCaps = GetDeviceCaps( hDC, RASTERCAPS );
+ int nBitCount = nBitsPixel * nPlanes;
+
+ if ( (nBitCount > 8) && (nBitCount < 24) )
+ {
+ // test, if we have to dither
+ HDC hMemDC = ::CreateCompatibleDC( hDC );
+ HBITMAP hMemBmp = ::CreateCompatibleBitmap( hDC, 8, 8 );
+ HBITMAP hBmpOld = (HBITMAP) ::SelectObject( hMemDC, hMemBmp );
+ HBRUSH hMemBrush = ::CreateSolidBrush( PALETTERGB( 175, 171, 169 ) );
+ HBRUSH hBrushOld = (HBRUSH) ::SelectObject( hMemDC, hMemBrush );
+ BOOL bDither16 = TRUE;
+
+ ::PatBlt( hMemDC, 0, 0, 8, 8, PATCOPY );
+ const COLORREF aCol( ::GetPixel( hMemDC, 0, 0 ) );
+
+ for( int nY = 0; ( nY < 8 ) && bDither16; nY++ )
+ for( int nX = 0; ( nX < 8 ) && bDither16; nX++ )
+ if( ::GetPixel( hMemDC, nX, nY ) != aCol )
+ bDither16 = FALSE;
+
+ ::SelectObject( hMemDC, hBrushOld ), ::DeleteObject( hMemBrush );
+ ::SelectObject( hMemDC, hBmpOld ), ::DeleteObject( hMemBmp );
+ ::DeleteDC( hMemDC );
+
+ if( bDither16 )
+ {
+ // create DIBPattern for 16Bit dithering
+ long n;
+
+ pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, sizeof( BITMAPINFOHEADER ) + 192 );
+ pSalData->mpDitherDIB = (BYTE*) GlobalLock( pSalData->mhDitherDIB );
+ pSalData->mpDitherDiff = new long[ 256 ];
+ pSalData->mpDitherLow = new BYTE[ 256 ];
+ pSalData->mpDitherHigh = new BYTE[ 256 ];
+ pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER );
+ memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) );
+
+ BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) pSalData->mpDitherDIB;
+
+ pBIH->biSize = sizeof( BITMAPINFOHEADER );
+ pBIH->biWidth = 8;
+ pBIH->biHeight = 8;
+ pBIH->biPlanes = 1;
+ pBIH->biBitCount = 24;
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherDiff[ n ] = n - ( n & 248L );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherLow[ n ] = (BYTE) ( n & 248 );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherHigh[ n ] = (BYTE) Min( pSalData->mpDitherLow[ n ] + 8L, 255L );
+ }
+ }
+ else if ( (nRasterCaps & RC_PALETTE) && (nBitCount == 8) )
+ {
+ BYTE nRed, nGreen, nBlue;
+ BYTE nR, nG, nB;
+ PALETTEENTRY* pPalEntry;
+ LOGPALETTE* pLogPal;
+ const USHORT nDitherPalCount = DITHER_PAL_COUNT;
+ ULONG nTotalCount = DITHER_MAX_SYSCOLOR + nDitherPalCount + DITHER_EXTRA_COLORS;
+
+ // create logical palette
+ pLogPal = (LOGPALETTE*) new char[ sizeof( LOGPALETTE ) + ( nTotalCount * sizeof( PALETTEENTRY ) ) ];
+ pLogPal->palVersion = 0x0300;
+ pLogPal->palNumEntries = (USHORT) nTotalCount;
+ pPalEntry = pLogPal->palPalEntry;
+
+ // Standard colors
+ memcpy( pPalEntry, aImplSalSysPalEntryAry, DITHER_MAX_SYSCOLOR * sizeof( PALETTEENTRY ) );
+ pPalEntry += DITHER_MAX_SYSCOLOR;
+
+ // own palette (6/6/6)
+ for( nB=0, nBlue=0; nB < DITHER_PAL_STEPS; nB++, nBlue += DITHER_PAL_DELTA )
+ {
+ for( nG=0, nGreen=0; nG < DITHER_PAL_STEPS; nG++, nGreen += DITHER_PAL_DELTA )
+ {
+ for( nR=0, nRed=0; nR < DITHER_PAL_STEPS; nR++, nRed += DITHER_PAL_DELTA )
+ {
+ pPalEntry->peRed = nRed;
+ pPalEntry->peGreen = nGreen;
+ pPalEntry->peBlue = nBlue;
+ pPalEntry->peFlags = 0;
+ pPalEntry++;
+ }
+ }
+ }
+
+ // insert special 'Blue' as standard drawing color
+ *pPalEntry++ = aImplExtraColor1;
+
+ // create palette
+ pSalData->mhDitherPal = CreatePalette( pLogPal );
+ delete[] (char*) pLogPal;
+
+ if( pSalData->mhDitherPal )
+ {
+ // create DIBPattern for 8Bit dithering
+ long nSize = sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) ) + 64;
+ long n;
+
+ pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, nSize );
+ pSalData->mpDitherDIB = (BYTE*) GlobalLock( pSalData->mhDitherDIB );
+ pSalData->mpDitherDiff = new long[ 256 ];
+ pSalData->mpDitherLow = new BYTE[ 256 ];
+ pSalData->mpDitherHigh = new BYTE[ 256 ];
+ pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) );
+ memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) );
+
+ BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) pSalData->mpDitherDIB;
+ short* pColors = (short*) ( pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) );
+
+ pBIH->biSize = sizeof( BITMAPINFOHEADER );
+ pBIH->biWidth = 8;
+ pBIH->biHeight = 8;
+ pBIH->biPlanes = 1;
+ pBIH->biBitCount = 8;
+
+ for( n = 0; n < nDitherPalCount; n++ )
+ pColors[ n ] = (short)( n + DITHER_MAX_SYSCOLOR );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherDiff[ n ] = n % 51L;
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherLow[ n ] = (BYTE) ( n / 51L );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherHigh[ n ] = Min( pSalData->mpDitherLow[ n ] + 1, 5 );
+ }
+
+ // get system color entries
+ ImplUpdateSysColorEntries();
+ }
+
+ ReleaseDC( 0, hDC );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFreeSalGDI()
+{
+ SalData* pSalData = GetSalData();
+ USHORT i;
+
+ // destroy stock objects
+ for ( i = 0; i < pSalData->mnStockPenCount; i++ )
+ DeletePen( pSalData->mhStockPenAry[i] );
+ for ( i = 0; i < pSalData->mnStockBrushCount; i++ )
+ DeleteBrush( pSalData->mhStockBrushAry[i] );
+
+ // 50% Brush loeschen
+ if ( pSalData->mh50Brush )
+ {
+ DeleteBrush( pSalData->mh50Brush );
+ pSalData->mh50Brush = 0;
+ }
+
+ // 50% Bitmap loeschen
+ if ( pSalData->mh50Bmp )
+ {
+ DeleteBitmap( pSalData->mh50Bmp );
+ pSalData->mh50Bmp = 0;
+ }
+
+ ImplClearHDCCache( pSalData );
+ delete[] pSalData->mpHDCCache;
+
+ // Ditherpalette loeschen, wenn vorhanden
+ if ( pSalData->mhDitherPal )
+ {
+#ifdef WIN
+ DeleteObject( pSalData->mhDitherPal );
+#endif
+ pSalData->mhDitherPal = 0;
+ }
+
+ // delete buffers for dithering DIB patterns, if neccessary
+ if ( pSalData->mhDitherDIB )
+ {
+#ifdef WIN
+ GlobalUnlock( pSalData->mhDitherDIB );
+ GlobalFree( pSalData->mhDitherDIB );
+#endif
+ pSalData->mhDitherDIB = 0;
+ delete[] pSalData->mpDitherDiff;
+ delete[] pSalData->mpDitherLow;
+ delete[] pSalData->mpDitherHigh;
+ }
+
+ // delete SysColorList
+ SysColorEntry* pEntry = pFirstSysColor;
+ while( pEntry )
+ {
+ SysColorEntry* pTmp = pEntry->pNext;
+ delete pEntry;
+ pEntry = pTmp;
+ }
+ pFirstSysColor = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue )
+{
+ // dither color?
+ if ( !(nRed % DITHER_PAL_DELTA) && !(nGreen % DITHER_PAL_DELTA) && !(nBlue % DITHER_PAL_DELTA) )
+ return TRUE;
+
+#ifdef WIN
+ PALETTEENTRY* pPalEntry = aImplSalSysPalEntryAry;
+
+ // standard palette color?
+ for ( USHORT i = 0; i < DITHER_MAX_SYSCOLOR; i++, pPalEntry++ )
+ {
+ if( pPalEntry->peRed == nRed && pPalEntry->peGreen == nGreen && pPalEntry->peBlue == nBlue )
+ return TRUE;
+ }
+
+ // extra color?
+ if ( aImplExtraColor1.peRed == nRed &&
+ aImplExtraColor1.peGreen == nGreen &&
+ aImplExtraColor1.peBlue == nBlue )
+ {
+ return TRUE;
+ }
+
+#endif
+ return FALSE;
+}
+
+// =======================================================================
+
+int ImplIsSysColorEntry( SalColor nSalColor )
+{
+ SysColorEntry* pEntry = pFirstSysColor;
+#ifdef WIN
+ const DWORD nTestRGB = (DWORD)RGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ while ( pEntry )
+ {
+ if ( pEntry->nRGB == nTestRGB )
+ return TRUE;
+ pEntry = pEntry->pNext;
+ }
+#endif
+
+ return FALSE;
+}
+
+// =======================================================================
+
+static void ImplInsertSysColorEntry( int nSysIndex )
+{
+#ifdef WIN
+ const DWORD nRGB = GetSysColor( nSysIndex );
+
+ if ( !ImplIsPaletteEntry( GetRValue( nRGB ), GetGValue( nRGB ), GetBValue( nRGB ) ) )
+ {
+ if ( !pFirstSysColor )
+ {
+ pActSysColor = pFirstSysColor = new SysColorEntry;
+ pFirstSysColor->nRGB = nRGB;
+ pFirstSysColor->pNext = NULL;
+ }
+ else
+ {
+ pActSysColor = pActSysColor->pNext = new SysColorEntry;
+ pActSysColor->nRGB = nRGB;
+ pActSysColor->pNext = NULL;
+ }
+ }
+#endif
+}
+
+// =======================================================================
+
+void ImplUpdateSysColorEntries()
+{
+ // delete old SysColorList
+ SysColorEntry* pEntry = pFirstSysColor;
+ while( pEntry )
+ {
+ SysColorEntry* pTmp = pEntry->pNext;
+ delete pEntry;
+ pEntry = pTmp;
+ }
+ pActSysColor = pFirstSysColor = NULL;
+
+#ifdef WIN
+ // create new sys color list
+ ImplInsertSysColorEntry( COLOR_ACTIVEBORDER );
+ ImplInsertSysColorEntry( COLOR_INACTIVEBORDER );
+ if( aSalShlData.mnVersion >= 410 )
+ {
+ ImplInsertSysColorEntry( COLOR_GRADIENTACTIVECAPTION );
+ ImplInsertSysColorEntry( COLOR_GRADIENTINACTIVECAPTION );
+ }
+ ImplInsertSysColorEntry( COLOR_3DFACE );
+ ImplInsertSysColorEntry( COLOR_3DHILIGHT );
+ ImplInsertSysColorEntry( COLOR_3DLIGHT );
+ ImplInsertSysColorEntry( COLOR_3DSHADOW );
+ ImplInsertSysColorEntry( COLOR_3DDKSHADOW );
+ ImplInsertSysColorEntry( COLOR_INFOBK );
+ ImplInsertSysColorEntry( COLOR_INFOTEXT );
+ ImplInsertSysColorEntry( COLOR_BTNTEXT );
+ ImplInsertSysColorEntry( COLOR_WINDOW );
+ ImplInsertSysColorEntry( COLOR_WINDOWTEXT );
+ ImplInsertSysColorEntry( COLOR_HIGHLIGHT );
+ ImplInsertSysColorEntry( COLOR_HIGHLIGHTTEXT );
+ ImplInsertSysColorEntry( COLOR_MENU );
+ ImplInsertSysColorEntry( COLOR_MENUTEXT );
+ ImplInsertSysColorEntry( COLOR_ACTIVECAPTION );
+ ImplInsertSysColorEntry( COLOR_CAPTIONTEXT );
+ ImplInsertSysColorEntry( COLOR_INACTIVECAPTION );
+ ImplInsertSysColorEntry( COLOR_INACTIVECAPTIONTEXT );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
+{
+ SalColor nSalColor;
+ if ( nROPColor == SAL_ROP_0 )
+ nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
+ else
+ nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
+ return nSalColor;
+}
+
+// =======================================================================
+
+void ImplSalInitGraphics( SalGraphicsData* pData )
+{
+#ifdef WIN
+ // Beim Printer berechnen wir die minimale Linienstaerke
+ if ( pData->mbPrinter )
+ {
+ int nDPIX = GetDeviceCaps( pData->mhDC, LOGPIXELSX );
+ if ( nDPIX <= 300 )
+ pData->mnPenWidth = 0;
+ else
+ pData->mnPenWidth = nDPIX/300;
+ }
+
+ ::SetTextAlign( pData->mhDC, TA_BASELINE | TA_LEFT | TA_NOUPDATECP );
+ ::SetBkMode( pData->mhDC, TRANSPARENT );
+ ::SetROP2( pData->mhDC, R2_COPYPEN );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalDeInitGraphics( SalGraphicsData* pData )
+{
+ // Default Objekte selektieren
+ if ( pData->mhDefPen )
+ SelectPen( pData->mhDC, pData->mhDefPen );
+ if ( pData->mhDefBrush )
+ SelectBrush( pData->mhDC, pData->mhDefBrush );
+ if ( pData->mhDefFont )
+ SelectFont( pData->mhDC, pData->mhDefFont );
+}
+
+// =======================================================================
+
+HDC ImplGetCachedDC( ULONG nID, HBITMAP hBmp )
+{
+ SalData* pSalData = GetSalData();
+ HDCCache* pC = &pSalData->mpHDCCache[ nID ];
+
+#ifdef WIN
+ if( !pC->mhDC )
+ {
+ HDC hDC = GetDC( 0 );
+
+ // neuen DC mit DefaultBitmap anlegen
+ pC->mhDC = CreateCompatibleDC( hDC );
+
+ if( pSalData->mhDitherPal )
+ {
+ pC->mhDefPal = SelectPalette( pC->mhDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( pC->mhDC );
+ }
+
+ pC->mhSelBmp = CreateCompatibleBitmap( hDC, CACHED_HDC_DEFEXT, CACHED_HDC_DEFEXT );
+ pC->mhDefBmp = (HBITMAP) SelectObject( pC->mhDC, pC->mhSelBmp );
+
+ ReleaseDC( 0, hDC );
+ }
+
+ if ( hBmp )
+ SelectObject( pC->mhDC, pC->mhActBmp = hBmp );
+ else
+#endif
+ pC->mhActBmp = 0;
+
+ return pC->mhDC;
+}
+
+// =======================================================================
+
+void ImplReleaseCachedDC( ULONG nID )
+{
+ SalData* pSalData = GetSalData();
+ HDCCache* pC = &pSalData->mpHDCCache[ nID ];
+
+#ifdef WIN
+ if ( pC->mhActBmp )
+ SelectObject( pC->mhDC, pC->mhSelBmp );
+#endif
+}
+
+// =======================================================================
+
+void ImplClearHDCCache( SalData* pData )
+{
+ for( ULONG i = 0; i < CACHESIZE_HDC; i++ )
+ {
+ HDCCache* pC = &pData->mpHDCCache[ i ];
+
+#ifdef WIN
+ if( pC->mhDC )
+ {
+ SelectObject( pC->mhDC, pC->mhDefBmp );
+
+ if( pC->mhDefPal )
+ SelectPalette( pC->mhDC, pC->mhDefPal, TRUE );
+
+ DeleteDC( pC->mhDC );
+ DeleteObject( pC->mhSelBmp );
+ }
+#endif
+ }
+}
+
+// =======================================================================
+
+SalGraphics::SalGraphics()
+{
+ maGraphicsData.mhDC = 0;
+ maGraphicsData.mhPen = 0;
+ maGraphicsData.mhBrush = 0;
+ maGraphicsData.mhFont = 0;
+ maGraphicsData.mhRegion = 0;
+ maGraphicsData.mhDefPen = 0;
+ maGraphicsData.mhDefBrush = 0;
+ maGraphicsData.mhDefFont = 0;
+ maGraphicsData.mhDefPal = 0;
+#ifdef WIN
+ maGraphicsData.mpStdClipRgnData = NULL;
+ maGraphicsData.mpLogFont = NULL;
+#endif
+ maGraphicsData.mpFontCharSets = NULL;
+ maGraphicsData.mnFontCharSetCount = 0;
+#ifdef WIN
+ maGraphicsData.mpFontKernPairs = NULL;
+#endif
+ maGraphicsData.mnFontKernPairCount = 0;
+ maGraphicsData.mbFontKernInit = FALSE;
+ maGraphicsData.mnFontOverhang = 0;
+ maGraphicsData.mbXORMode = FALSE;
+ maGraphicsData.mnPenWidth = GSL_PEN_WIDTH;
+ maGraphicsData.mbCalcOverhang = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics::~SalGraphics()
+{
+ // Objekte zerstoeren
+ if ( maGraphicsData.mhPen )
+ {
+ if ( !maGraphicsData.mbStockPen )
+ DeletePen( maGraphicsData.mhPen );
+ }
+ if ( maGraphicsData.mhBrush )
+ {
+ if ( !maGraphicsData.mbStockBrush )
+ DeleteBrush( maGraphicsData.mhBrush );
+ }
+ if ( maGraphicsData.mhFont )
+ DeleteFont( maGraphicsData.mhFont );
+
+ if ( maGraphicsData.mhRegion )
+ {
+ DeleteRegion( maGraphicsData.mhRegion );
+ maGraphicsData.mhRegion = 0;
+ }
+
+ // Cache-Daten zerstoeren
+#ifdef WIN
+ if ( maGraphicsData.mpStdClipRgnData )
+ delete maGraphicsData.mpStdClipRgnData;
+
+ if ( maGraphicsData.mpLogFont )
+ delete maGraphicsData.mpLogFont;
+#endif
+
+ if ( maGraphicsData.mpFontCharSets )
+ delete maGraphicsData.mpFontCharSets;
+
+#ifdef WIN
+ if ( maGraphicsData.mpFontKernPairs )
+ delete maGraphicsData.mpFontKernPairs;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetResolution( long& rDPIX, long& rDPIY )
+{
+#ifdef WIN
+ rDPIX = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSX );
+ rDPIY = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSY );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetScreenFontResolution( long& rDPIX, long& rDPIY )
+{
+#ifdef WIN
+ rDPIX = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSX );
+ rDPIY = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSY );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalGraphics::GetBitCount()
+{
+#ifdef WIN
+ return (USHORT)GetDeviceCaps( maGraphicsData.mhDC, BITSPIXEL );
+#else
+ return 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::ResetClipRegion()
+{
+ if ( maGraphicsData.mhRegion )
+ {
+ DeleteRegion( maGraphicsData.mhRegion );
+ maGraphicsData.mhRegion = 0;
+ }
+
+#ifdef WIN
+ SelectClipRgn( maGraphicsData.mhDC, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::BeginSetClipRegion( ULONG nRectCount )
+{
+ if ( maGraphicsData.mhRegion )
+ {
+ DeleteRegion( maGraphicsData.mhRegion );
+ maGraphicsData.mhRegion = 0;
+ }
+
+ ULONG nRectBufSize = sizeof(RECT)*nRectCount;
+#ifdef WIN
+ if ( nRectCount < SAL_CLIPRECT_COUNT )
+ {
+ if ( !maGraphicsData.mpStdClipRgnData )
+ maGraphicsData.mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
+ maGraphicsData.mpClipRgnData = maGraphicsData.mpStdClipRgnData;
+ }
+ else
+ maGraphicsData.mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
+ maGraphicsData.mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
+ maGraphicsData.mpClipRgnData->rdh.iType = RDH_RECTANGLES;
+ maGraphicsData.mpClipRgnData->rdh.nCount = nRectCount;
+ maGraphicsData.mpClipRgnData->rdh.nRgnSize = nRectBufSize;
+ SetRectEmpty( &(maGraphicsData.mpClipRgnData->rdh.rcBound) );
+ maGraphicsData.mpNextClipRect = (RECT*)(&(maGraphicsData.mpClipRgnData->Buffer));
+ maGraphicsData.mbFirstClipRect = TRUE;
+#endif
+}
+
+
+// -----------------------------------------------------------------------
+
+BOOL SalGraphics::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+#ifdef WIN
+ if ( nWidth && nHeight )
+ {
+ RECT* pRect = maGraphicsData.mpNextClipRect;
+ RECT* pBoundRect = &(maGraphicsData.mpClipRgnData->rdh.rcBound);
+ long nRight = nX + nWidth;
+ long nBottom = nY + nHeight;
+
+ if ( maGraphicsData.mbFirstClipRect )
+ {
+ pBoundRect->left = nX;
+ pBoundRect->top = nY;
+ pBoundRect->right = nRight;
+ pBoundRect->bottom = nBottom;
+ maGraphicsData.mbFirstClipRect = FALSE;
+ }
+ else
+ {
+ if ( nX < pBoundRect->left )
+ pBoundRect->left = (int)nX;
+
+ if ( nY < pBoundRect->top )
+ pBoundRect->top = (int)nY;
+
+ if ( nRight > pBoundRect->right )
+ pBoundRect->right = (int)nRight;
+
+ if ( nBottom > pBoundRect->bottom )
+ pBoundRect->bottom = (int)nBottom;
+ }
+
+ pRect->left = (int)nX;
+ pRect->top = (int)nY;
+ pRect->right = (int)nRight;
+ pRect->bottom = (int)nBottom;
+ maGraphicsData.mpNextClipRect++;
+ }
+ else
+ {
+ maGraphicsData.mpClipRgnData->rdh.nCount--;
+ maGraphicsData.mpClipRgnData->rdh.nRgnSize -= sizeof( RECT );
+ }
+#endif
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::EndSetClipRegion()
+{
+#ifdef WIN
+ // Aus den Region-Daten muessen wir jetzt eine ClipRegion erzeugen
+ if ( maGraphicsData.mpClipRgnData->rdh.nCount == 1 )
+ {
+ RECT* pRect = &(maGraphicsData.mpClipRgnData->rdh.rcBound);
+ maGraphicsData.mhRegion = CreateRectRgn( pRect->left, pRect->top,
+ pRect->right, pRect->bottom );
+ }
+ else
+ {
+ ULONG nSize = maGraphicsData.mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
+ maGraphicsData.mhRegion = ExtCreateRegion( NULL, nSize, maGraphicsData.mpClipRgnData );
+
+ // if ExtCreateRegion(...) is not supported
+ if( !maGraphicsData.mhRegion )
+ {
+ RGNDATAHEADER* pHeader = (RGNDATAHEADER*) maGraphicsData.mpClipRgnData;
+
+ if( pHeader->nCount )
+ {
+ RECT* pRect = (RECT*) maGraphicsData.mpClipRgnData->Buffer;
+ maGraphicsData.mhRegion = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
+ pRect++;
+
+ for( ULONG n = 1; n < pHeader->nCount; n++, pRect++ )
+ {
+ HRGN hRgn = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
+ CombineRgn( maGraphicsData.mhRegion, maGraphicsData.mhRegion, hRgn, RGN_OR );
+ DeleteRegion( hRgn );
+ }
+ }
+ }
+
+ if ( maGraphicsData.mpClipRgnData != maGraphicsData.mpStdClipRgnData )
+ delete maGraphicsData.mpClipRgnData;
+ }
+
+ SelectClipRgn( maGraphicsData.mhDC, maGraphicsData.mhRegion );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetLineColor()
+{
+#ifdef WIN
+ // create and select new pen
+ HPEN hNewPen = GetStockPen( NULL_PEN );
+ HPEN hOldPen = SelectPen( maGraphicsData.mhDC, hNewPen );
+
+ // destory or save old pen
+ if ( maGraphicsData.mhPen )
+ {
+ if ( !maGraphicsData.mbStockPen )
+ DeletePen( maGraphicsData.mhPen );
+ }
+ else
+ maGraphicsData.mhDefPen = hOldPen;
+
+ // set new data
+ maGraphicsData.mhPen = hNewPen;
+ maGraphicsData.mbPen = FALSE;
+ maGraphicsData.mbStockPen = TRUE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetLineColor( SalColor nSalColor )
+{
+#ifdef WIN
+ COLORREF nPenColor = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+ HPEN hNewPen = 0;
+ BOOL bStockPen;
+
+ // search for stock pen (only screen, because printer have problems,
+ // when we use stock objects)
+ if ( !maGraphicsData.mbPrinter )
+ {
+ SalData* pSalData = GetSalData();
+ for ( USHORT i = 0; i < pSalData->mnStockPenCount; i++ )
+ {
+ if ( nPenColor == pSalData->maStockPenColorAry[i] )
+ {
+ hNewPen = pSalData->mhStockPenAry[i];
+ bStockPen = TRUE;
+ break;
+ }
+ }
+ }
+
+ // create new pen
+ if ( !hNewPen )
+ {
+ if ( !maGraphicsData.mbPrinter )
+ {
+ if ( GetSalData()->mhDitherPal && ImplIsSysColorEntry( nSalColor ) )
+ nPenColor = PALRGB_TO_RGB( nPenColor );
+ }
+
+ hNewPen = CreatePen( PS_SOLID, maGraphicsData.mnPenWidth, nPenColor );
+ bStockPen = FALSE;
+ }
+
+ // select new pen
+ HPEN hOldPen = SelectPen( maGraphicsData.mhDC, hNewPen );
+
+ // destory or save old pen
+ if ( maGraphicsData.mhPen )
+ {
+ if ( !maGraphicsData.mbStockPen )
+ DeletePen( maGraphicsData.mhPen );
+ }
+ else
+ maGraphicsData.mhDefPen = hOldPen;
+
+ // set new data
+ maGraphicsData.mnPenColor = nPenColor;
+ maGraphicsData.mhPen = hNewPen;
+ maGraphicsData.mbPen = TRUE;
+ maGraphicsData.mbStockPen = bStockPen;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetFillColor()
+{
+ // create and select new brush
+#ifdef WIN
+ HBRUSH hNewBrush = GetStockBrush( NULL_BRUSH );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hNewBrush );
+#endif
+
+ // destory or save old brush
+ if ( maGraphicsData.mhBrush )
+ {
+ if ( !maGraphicsData.mbStockBrush )
+ DeleteBrush( maGraphicsData.mhBrush );
+ }
+#ifdef WIN
+ else
+ maGraphicsData.mhDefBrush = hOldBrush;
+
+ // set new data
+ maGraphicsData.mhBrush = hNewBrush;
+#endif
+ maGraphicsData.mbBrush = FALSE;
+ maGraphicsData.mbStockBrush = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetFillColor( SalColor nSalColor )
+{
+#ifdef WIN
+ SalData* pSalData = GetSalData();
+ BYTE nRed = SALCOLOR_RED( nSalColor );
+ BYTE nGreen = SALCOLOR_GREEN( nSalColor );
+ BYTE nBlue = SALCOLOR_BLUE( nSalColor );
+ COLORREF nBrushColor = PALETTERGB( nRed, nGreen, nBlue );
+ HBRUSH hNewBrush = 0;
+ BOOL bStockBrush;
+
+ // search for stock brush (only screen, because printer have problems,
+ // when we use stock objects)
+ if ( !maGraphicsData.mbPrinter )
+ {
+ for ( USHORT i = 0; i < pSalData->mnStockBrushCount; i++ )
+ {
+ if ( nBrushColor == pSalData->maStockBrushColorAry[ i ] )
+ {
+ hNewBrush = pSalData->mhStockBrushAry[i];
+ bStockBrush = TRUE;
+ break;
+ }
+ }
+ }
+
+ // create new brush
+ if ( !hNewBrush )
+ {
+ if ( maGraphicsData.mbPrinter || !pSalData->mhDitherDIB )
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ else
+ {
+ if ( 24 == ((BITMAPINFOHEADER*)pSalData->mpDitherDIB)->biBitCount )
+ {
+ BYTE* pTmp = pSalData->mpDitherDIBData;
+ long* pDitherDiff = pSalData->mpDitherDiff;
+ BYTE* pDitherLow = pSalData->mpDitherLow;
+ BYTE* pDitherHigh = pSalData->mpDitherHigh;
+
+ for( long nY = 0L; nY < 8L; nY++ )
+ {
+ for( long nX = 0L; nX < 8L; nX++ )
+ {
+ const long nThres = aOrdDither16Bit[ nY ][ nX ];
+ *pTmp++ = DMAP( nBlue, nThres );
+ *pTmp++ = DMAP( nGreen, nThres );
+ *pTmp++ = DMAP( nRed, nThres );
+ }
+ }
+
+ hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_RGB_COLORS );
+ }
+ else if ( ImplIsSysColorEntry( nSalColor ) )
+ {
+ nBrushColor = PALRGB_TO_RGB( nBrushColor );
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ }
+ else if ( ImplIsPaletteEntry( nRed, nGreen, nBlue ) )
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ else
+ {
+ BYTE* pTmp = pSalData->mpDitherDIBData;
+ long* pDitherDiff = pSalData->mpDitherDiff;
+ BYTE* pDitherLow = pSalData->mpDitherLow;
+ BYTE* pDitherHigh = pSalData->mpDitherHigh;
+
+ for ( long nY = 0L; nY < 8L; nY++ )
+ {
+ for ( long nX = 0L; nX < 8L; nX++ )
+ {
+ const long nThres = aOrdDither8Bit[ nY ][ nX ];
+ *pTmp = DMAP( nRed, nThres ) + DMAP( nGreen, nThres ) * 6 + DMAP( nBlue, nThres ) * 36;
+ pTmp++;
+ }
+ }
+
+ hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_PAL_COLORS );
+ }
+ }
+
+ bStockBrush = FALSE;
+ }
+
+ // select new brush
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hNewBrush );
+
+ // destory or save old brush
+ if ( maGraphicsData.mhBrush )
+ {
+ if ( !maGraphicsData.mbStockBrush )
+ DeleteBrush( maGraphicsData.mhBrush );
+ }
+ else
+ maGraphicsData.mhDefBrush = hOldBrush;
+
+ // set new data
+ maGraphicsData.mnBrushColor = nBrushColor;
+ maGraphicsData.mhBrush = hNewBrush;
+ maGraphicsData.mbBrush = FALSE;
+ maGraphicsData.mbStockBrush = bStockBrush;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetXORMode( BOOL bSet )
+{
+ maGraphicsData.mbXORMode = bSet;
+#ifdef WIn
+ ::SetROP2( maGraphicsData.mhDC, bSet ? R2_XORPEN : R2_COPYPEN );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetROPLineColor( SalROPColor nROPColor )
+{
+ SetLineColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetROPFillColor( SalROPColor nROPColor )
+{
+ SetFillColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPixel( long nX, long nY )
+{
+#ifdef WIN
+ if ( maGraphicsData.mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( maGraphicsData.mnPenColor );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ PatBlt( maGraphicsData.mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ SetPixel( maGraphicsData.mhDC, (int)nX, (int)nY, maGraphicsData.mnPenColor );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPixel( long nX, long nY, SalColor nSalColor )
+{
+#ifdef WIN
+ COLORREF nCol = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ if ( !maGraphicsData.mbPrinter &&
+ GetSalData()->mhDitherPal &&
+ ImplIsSysColorEntry( nSalColor ) )
+ nCol = PALRGB_TO_RGB( nCol );
+
+ if ( maGraphicsData.mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( nCol );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ PatBlt( maGraphicsData.mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ ::SetPixel( maGraphicsData.mhDC, (int)nX, (int)nY, nCol );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+#ifdef WIN
+ MoveToEx( maGraphicsData.mhDC, (int)nX1, (int)nY1, NULL );
+#endif
+
+ // we must paint the endpoint
+ int bPaintEnd = TRUE;
+ if ( nX1 == nX2 )
+ {
+ bPaintEnd = FALSE;
+ if ( nY1 <= nY2 )
+ nY2++;
+ else
+ nY2--;
+ }
+ if ( nY1 == nY2 )
+ {
+ bPaintEnd = FALSE;
+ if ( nX1 <= nX2 )
+ nX2++;
+ else
+ nX2--;
+ }
+
+#ifdef WIN
+ LineTo( maGraphicsData.mhDC, (int)nX2, (int)nY2 );
+#endif
+
+ if ( bPaintEnd && !maGraphicsData.mbPrinter )
+ {
+#ifdef WIN
+ if ( maGraphicsData.mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( maGraphicsData.mnPenColor );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ PatBlt( maGraphicsData.mhDC, (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ SetPixel( maGraphicsData.mhDC, (int)nX2, (int)nY2, maGraphicsData.mnPenColor );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ if ( !maGraphicsData.mbPen )
+ {
+ if ( !maGraphicsData.mbPrinter )
+ {
+#ifdef WIN
+ PatBlt( maGraphicsData.mhDC, (int)nX, (int)nY, (int)nWidth, (int)nHeight, maGraphicsData.mbXORMode ? PATINVERT : PATCOPY );
+#endif
+ }
+ else
+ {
+ RECT aWinRect;
+ aWinRect.left = nX;
+ aWinRect.top = nY;
+ aWinRect.right = nX+nWidth;
+ aWinRect.bottom = nY+nHeight;
+#ifdef WIN
+ ::FillRect( maGraphicsData.mhDC, &aWinRect, maGraphicsData.mhBrush );
+#endif
+ }
+ }
+#ifdef WIN
+ else
+ WIN_Rectangle( maGraphicsData.mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolyLine( ULONG nPoints, const SalPoint* pPtAry )
+{
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolyLine(): POINT != SalPoint" );
+
+ POINT* pWinPtAry = (POINT*)pPtAry;
+ // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
+ // von Punkten
+#ifdef WIN
+ if ( !Polyline( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ Polyline( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolygon( ULONG nPoints, const SalPoint* pPtAry )
+{
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolygon(): POINT != SalPoint" );
+
+ POINT* pWinPtAry = (POINT*)pPtAry;
+#ifdef WIN
+ // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
+ // von Punkten
+ if ( !WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolyPolygon( ULONG nPoly, const ULONG* pPoints,
+ PCONSTSALPOINT* pPtAry )
+{
+ UINT aWinPointAry[SAL_POLYPOLYCOUNT_STACKBUF];
+ UINT* pWinPointAry;
+ UINT nPolyPolyPoints = 0;
+ UINT nPoints;
+ UINT i;
+
+ if ( nPoly <= SAL_POLYPOLYCOUNT_STACKBUF )
+ pWinPointAry = aWinPointAry;
+ else
+ pWinPointAry = new UINT[nPoly];
+
+ for ( i = 0; i < (UINT)nPoly; i++ )
+ {
+ nPoints = (UINT)pPoints[i]+1;
+ pWinPointAry[i] = nPoints;
+ nPolyPolyPoints += nPoints;
+ }
+
+ POINT aWinPointAryAry[SAL_POLYPOLYPOINTS_STACKBUF];
+ POINT* pWinPointAryAry;
+ if ( nPolyPolyPoints <= SAL_POLYPOLYPOINTS_STACKBUF )
+ pWinPointAryAry = aWinPointAryAry;
+ else
+ pWinPointAryAry = new POINT[nPolyPolyPoints];
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolyPolygon(): POINT != SalPoint" );
+ const SalPoint* pPolyAry;
+ UINT n = 0;
+ for ( i = 0; i < (UINT)nPoly; i++ )
+ {
+ nPoints = pWinPointAry[i];
+ pPolyAry = pPtAry[i];
+ memcpy( pWinPointAryAry+n, pPolyAry, (nPoints-1)*sizeof(POINT) );
+ pWinPointAryAry[n+nPoints-1] = pWinPointAryAry[n];
+ n += nPoints;
+ }
+
+#ifdef WIN
+ if ( !WIN_PolyPolygon( maGraphicsData.mhDC, pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) &&
+ (nPolyPolyPoints > MAX_64KSALPOINTS) )
+ {
+ nPolyPolyPoints = 0;
+ nPoly = 0;
+ do
+ {
+ nPolyPolyPoints += pWinPointAry[(UINT)nPoly];
+ nPoly++;
+ }
+ while ( nPolyPolyPoints < MAX_64KSALPOINTS );
+ nPoly--;
+ if ( pWinPointAry[(UINT)nPoly] > MAX_64KSALPOINTS )
+ pWinPointAry[(UINT)nPoly] = MAX_64KSALPOINTS;
+ if ( nPoly == 1 )
+ WIN_Polygon( maGraphicsData.mhDC, pWinPointAryAry, *pWinPointAry );
+ else
+ WIN_PolyPolygon( maGraphicsData.mhDC, pWinPointAryAry, (int*)pWinPointAry, nPoly );
+ }
+#endif
+
+ if ( pWinPointAry != aWinPointAry )
+ delete pWinPointAry;
+ if ( pWinPointAryAry != aWinPointAryAry )
+ delete pWinPointAryAry;
+}
+
+
+// -----------------------------------------------------------------------
+
+#define POSTSCRIPT_BUFSIZE 0x4000 // MAXIMUM BUFSIZE EQ 0xFFFF
+#define POSTSCRIPT_BOUNDINGSEARCH 0x1000 // we only try to get the BoundingBox
+ // in the first 4096 bytes
+
+static BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, ULONG nComp, ULONG nSize )
+{
+ while ( nComp-- >= nSize )
+ {
+ for ( ULONG i = 0; i < nSize; i++ )
+ {
+ if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
+ break;
+ }
+ if ( i == nSize )
+ return pSource;
+ pSource++;
+ }
+ return NULL;
+}
+
+static BOOL ImplGetBoundingBox( double* nNumb, BYTE* pSource, ULONG nSize )
+{
+ BOOL bRetValue = FALSE;
+ ULONG nBytesRead;
+
+ if ( nSize < 256 ) // we assume that the file is greater than 256 bytes
+ return FALSE;
+
+ if ( nSize < POSTSCRIPT_BOUNDINGSEARCH )
+ nBytesRead = nSize;
+ else
+ nBytesRead = POSTSCRIPT_BOUNDINGSEARCH;
+
+ BYTE* pDest = ImplSearchEntry( pSource, (BYTE*)"%%BoundingBox:", nBytesRead, 14 );
+ if ( pDest )
+ {
+ int nSecurityCount = 100; // only 100 bytes following the bounding box will be checked
+ nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
+ pDest += 14;
+ for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ )
+ {
+ int nDivision = 1;
+ BOOL bDivision = FALSE;
+ BOOL bNegative = FALSE;
+ BOOL bValid = TRUE;
+
+ while ( ( --nSecurityCount ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++;
+ BYTE nByte = *pDest;
+ while ( nSecurityCount && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
+ {
+ switch ( nByte )
+ {
+ case '.' :
+ if ( bDivision )
+ bValid = FALSE;
+ else
+ bDivision = TRUE;
+ break;
+ case '-' :
+ bNegative = TRUE;
+ break;
+ default :
+ if ( ( nByte < '0' ) || ( nByte > '9' ) )
+ nSecurityCount = 1; // error parsing the bounding box values
+ else if ( bValid )
+ {
+ if ( bDivision )
+ nDivision*=10;
+ nNumb[i] *= 10;
+ nNumb[i] += nByte - '0';
+ }
+ break;
+ }
+ nSecurityCount--;
+ nByte = *(++pDest);
+ }
+ if ( bNegative )
+ nNumb[i] = -nNumb[i];
+ if ( bDivision && ( nDivision != 1 ) )
+ nNumb[i] /= nDivision;
+ }
+ if ( nSecurityCount)
+ bRetValue = TRUE;
+ }
+ return bRetValue;
+}
+
+inline void ImplWriteDouble( BYTE** pBuf, double nNumb )
+{
+ *pBuf += sprintf( (char*)*pBuf, "%f", nNumb );
+ *(*pBuf)++ = ' ';
+}
+
+inline void ImplWriteString( BYTE** pBuf, const char* sString )
+{
+ strcpy( (char*)*pBuf, sString );
+ *pBuf += strlen( sString );
+}
+
+BOOL SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize )
+{
+ BOOL bRetValue = FALSE;
+
+ if ( maGraphicsData.mbPrinter )
+ {
+#ifdef WIN
+ int nEscape = POSTSCRIPT_PASSTHROUGH;
+
+ if ( Escape( maGraphicsData.mhDC, QUERYESCSUPPORT, sizeof( int ), ( LPSTR )&nEscape, 0 ) )
+ {
+ BYTE* pBuf = new BYTE[ POSTSCRIPT_BUFSIZE ];
+
+ double nBoundingBox[4];
+
+ if ( pBuf && ImplGetBoundingBox( nBoundingBox, (BYTE*)pPtr, nSize ) )
+ {
+ double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] );
+ double dM22 = nHeight / (nBoundingBox[1] - nBoundingBox[3] );
+ BYTE* pTemp = pBuf + 2; // +2 because we want to insert the size later
+ ImplWriteString( &pTemp, "\n\nsave\n[ " );
+ ImplWriteDouble( &pTemp, dM11 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, dM22 );
+ ImplWriteDouble( &pTemp, nX - ( dM11 * nBoundingBox[0] ) );
+ ImplWriteDouble( &pTemp, nY - ( dM22 * nBoundingBox[3] ) );
+ ImplWriteString( &pTemp, "] concat /showpage {} def\n" );
+ ImplWriteString( &pTemp, "%%BeginDocument:\n" );
+ *((USHORT*)pBuf) = (USHORT)( pTemp - pBuf - 2 );
+ Escape ( maGraphicsData.mhDC, nEscape, pTemp - pBuf, (LPTSTR)((BYTE*)pBuf), 0 );
+
+ ULONG nToDo = nSize;
+ ULONG nDoNow;
+ while ( nToDo )
+ {
+ nDoNow = nToDo;
+ if ( nToDo > POSTSCRIPT_BUFSIZE - 2 )
+ nDoNow = POSTSCRIPT_BUFSIZE - 2;
+ *((USHORT*)pBuf) = (USHORT)nDoNow;
+ memcpy( pBuf + 2, (BYTE*)pPtr + nSize - nToDo, nDoNow );
+ ULONG nResult = Escape ( maGraphicsData.mhDC, nEscape, nDoNow + 2, (LPTSTR)((BYTE*)pBuf), 0 );
+ if (!nResult )
+ break;
+ nToDo -= nResult;
+ }
+ pTemp = pBuf + 2;
+ ImplWriteString( &pTemp, "%%EndDocument\n" );
+ ImplWriteString( &pTemp, "restore\n\n" );
+ *((USHORT*)pBuf) = (USHORT)( pTemp - pBuf - 2 );
+ Escape ( maGraphicsData.mhDC, nEscape, pTemp - pBuf, (LPTSTR)((BYTE*)pBuf), 0 );
+ bRetValue = TRUE;
+ }
+ delete pBuf;
+ }
+#endif
+ }
+
+ return bRetValue;
+}
diff --git a/vcl/aqua/source/gdi/salogl.cxx b/vcl/aqua/source/gdi/salogl.cxx
new file mode 100644
index 000000000000..dc6cb109f5fa
--- /dev/null
+++ b/vcl/aqua/source/gdi/salogl.cxx
@@ -0,0 +1,351 @@
+/*************************************************************************
+ *
+ * $RCSfile: salogl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALOGL_CXX
+
+#ifndef _SV_SALOGL_HXX
+#include <salogl.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+
+// -------------------------------
+// - Additional typedefs for init.
+// -------------------------------
+
+typedef HGLRC ( *OGLFncCreateContext )( HDC hDC );
+typedef BOOL ( *OGLFncDeleteContext )( HGLRC hContext );
+typedef HGLRC ( *OGLFncGetCurrentContext )( void );
+typedef void ( *OGLFncMakeCurrent )( HDC hDC, HGLRC hContext );
+
+// ------------
+// - Lib-Name -
+// ------------
+
+#ifdef WIN
+#define OGL_LIBNAME "OPENGL32.DLL"
+#endif
+
+// ----------
+// - Macros -
+// ----------
+
+#ifdef WIN
+#define INIT_OGLFNC_WGL( FncName ) static OGLFnc##FncName pImplOpenWGLFnc##FncName = NULL;
+#define GET_OGLFNC_WGL( FncName ) \
+pImplOpenWGLFnc##FncName = (OGLFnc##FncName##) GetProcAddress( hImplOGLLib, "wgl" #FncName ); \
+if( !pImplOpenWGLFnc##FncName ) bRet = FALSE;
+#endif
+
+// -----------------
+// - Statics init. -
+// -----------------
+
+// Members
+static HINSTANCE hImplOGLLib;
+HGLRC SalOpenGL::mhOGLContext = 0;
+HDC SalOpenGL::mhOGLLastDC = 0;
+ULONG SalOpenGL::mnOGLState = OGL_STATE_UNLOADED;
+
+#ifdef
+INIT_OGLFNC_WGL( CreateContext );
+INIT_OGLFNC_WGL( DeleteContext );
+INIT_OGLFNC_WGL( GetCurrentContext );
+INIT_OGLFNC_WGL( MakeCurrent );
+#endif
+
+// -----------
+// - WndProc -
+// -----------
+
+#ifdef WIN
+LRESULT CALLBACK OpenGLWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
+{
+ return DefWindowProc( hWnd, nMsg, nPar1, nPar2 );
+}
+#endif
+
+// -------------
+// - SalOpenGL -
+// -------------
+
+SalOpenGL::SalOpenGL( SalGraphics* pGraphics )
+{
+ // Set mhOGLLastDC only the first time a
+ // SalOpenGL object is created; we need
+ // this DC in SalOpenGL::Create();
+ if ( OGL_STATE_UNLOADED == mnOGLState )
+ mhOGLLastDC = pGraphics->maGraphicsData.mhDC;
+}
+
+// ------------------------------------------------------------------------
+
+SalOpenGL::~SalOpenGL()
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::Create()
+{
+ BOOL bRet = FALSE;
+
+ if ( OGL_STATE_UNLOADED == mnOGLState )
+ {
+ if( ImplInitLib() )
+ {
+#ifdef WIN
+ USHORT nBitCount = GetDeviceCaps( mhOGLLastDC, BITSPIXEL );
+ PIXELFORMATDESCRIPTOR pfd =
+ {
+ sizeof( PIXELFORMATDESCRIPTOR ),
+ 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ (BYTE) nBitCount,
+ 0, 0, 0, 0, 0, 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,
+ 0, 0, 0
+ };
+
+ const int nIndex = ChoosePixelFormat( mhOGLLastDC, &pfd );
+
+ if( nIndex && SetPixelFormat( mhOGLLastDC, nIndex, &pfd ) )
+ {
+ if ( (nBitCount > 8) && ImplInit() &&
+ (mhOGLContext = pImplOpenWGLFncCreateContext( mhOGLLastDC )) != 0 )
+ {
+ WNDCLASS aWc;
+ HWND hDummyWnd;
+
+ SaveDC( mhOGLLastDC );
+ SelectClipRgn( mhOGLLastDC, NULL );
+ pImplOpenWGLFncMakeCurrent( mhOGLLastDC, mhOGLContext );
+ RestoreDC( mhOGLLastDC, -1 );
+ mnOGLState = OGL_STATE_VALID;
+ bRet = TRUE;
+
+ memset( &aWc, 0, sizeof( aWc ) );
+ aWc.hInstance = GetModuleHandle( NULL );
+ aWc.lpfnWndProc = OpenGLWndProc;
+ aWc.lpszClassName = "OpenGLWnd";
+ RegisterClass( &aWc );
+ hDummyWnd = CreateWindow( aWc.lpszClassName, NULL, WS_OVERLAPPED, 0, -50, 1, 1, HWND_DESKTOP, NULL, aWc.hInstance, 0 );
+ ShowWindow( hDummyWnd, SW_SHOW );
+ DestroyWindow( hDummyWnd );
+ UnregisterClass( aWc.lpszClassName, aWc.hInstance );
+ }
+ else
+ {
+ ImplFreeLib();
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ }
+ else
+ mnOGLState = OGL_STATE_INVALID;
+#endif
+ }
+ else
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ else if( OGL_STATE_VALID == mnOGLState )
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::Release()
+{
+ ImplFreeLib();
+}
+
+// ------------------------------------------------------------------------
+
+void* SalOpenGL::GetOGLFnc( const char* pFncName )
+{
+#ifdef WIN
+ if ( hImplOGLLib )
+ return (void*)GetProcAddress( hImplOGLLib, pFncName );
+ else
+#endif
+ return NULL;
+}
+
+// ------------------------------------------------------------------------
+
+#ifdef WIN
+typedef BOOL (WINAPI *MyFuncType)(HDC, HGLRC);
+#endif
+
+void SalOpenGL::OGLEntry( SalGraphics* pGraphics )
+{
+ if ( pGraphics->maGraphicsData.mhDC != mhOGLLastDC )
+ {
+#ifdef WIN
+ PIXELFORMATDESCRIPTOR pfd =
+ {
+ sizeof( PIXELFORMATDESCRIPTOR ),
+ 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ GetDeviceCaps( pGraphics->maGraphicsData.mhDC, BITSPIXEL ),
+ 0, 0, 0, 0, 0, 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,
+ 0, 0, 0
+ };
+
+ const int nIndex = ChoosePixelFormat( pGraphics->maGraphicsData.mhDC, &pfd );
+ if ( nIndex && SetPixelFormat( pGraphics->maGraphicsData.mhDC, nIndex, &pfd ) )
+ {
+ WNDCLASS aWc;
+ HWND hDummyWnd;
+
+ pImplOpenWGLFncDeleteContext( mhOGLContext );
+ mhOGLLastDC = pGraphics->maGraphicsData.mhDC;
+ mhOGLContext = pImplOpenWGLFncCreateContext( mhOGLLastDC );
+
+ SaveDC( mhOGLLastDC );
+ SelectClipRgn( mhOGLLastDC, NULL );
+ pImplOpenWGLFncMakeCurrent( mhOGLLastDC, mhOGLContext );
+ RestoreDC( mhOGLLastDC, -1 );
+
+ memset( &aWc, 0, sizeof( aWc ) );
+ aWc.hInstance = GetModuleHandle( NULL );
+ aWc.lpfnWndProc = OpenGLWndProc;
+ aWc.lpszClassName = "OpenGLWnd";
+ RegisterClass( &aWc );
+ hDummyWnd = CreateWindow( aWc.lpszClassName, NULL, WS_OVERLAPPED, 0, -50, 1, 1, HWND_DESKTOP, NULL, aWc.hInstance, 0 );
+ ShowWindow( hDummyWnd, SW_SHOW );
+ DestroyWindow( hDummyWnd );
+ UnregisterClass( aWc.lpszClassName, aWc.hInstance );
+ }
+#endif
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::OGLExit( SalGraphics* pGraphics )
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::ImplInitLib()
+{
+#ifdef WIN
+ return ((hImplOGLLib = LoadLibrary( OGL_LIBNAME )) != NULL);
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::ImplFreeLib()
+{
+ if ( hImplOGLLib )
+ {
+#ifdef WIN
+ FreeLibrary( hImplOGLLib );
+#endif
+ hImplOGLLib = NULL;
+ mnOGLState = OGL_STATE_UNLOADED;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::ImplInit()
+{
+ BOOL bRet = TRUE;
+
+#ifdef WIN
+ // Internal use
+ GET_OGLFNC_WGL( CreateContext );
+ GET_OGLFNC_WGL( DeleteContext );
+ GET_OGLFNC_WGL( GetCurrentContext );
+ GET_OGLFNC_WGL( MakeCurrent );
+#endif
+
+ return bRet;
+}
diff --git a/vcl/aqua/source/gdi/salprn.cxx b/vcl/aqua/source/gdi/salprn.cxx
new file mode 100644
index 000000000000..522c9ef18e91
--- /dev/null
+++ b/vcl/aqua/source/gdi/salprn.cxx
@@ -0,0 +1,1487 @@
+/*************************************************************************
+ *
+ * $RCSfile: salprn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALPRN_CXX
+
+#ifndef _SV_SALAQUA_HXX
+#include <salaqua.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALPTYPE_HXX
+#include <salptype.hxx>
+#endif
+#ifndef _SV_SALPRN_HXX
+#include <salprn.hxx>
+#endif
+
+#ifndef _NEW_HXX
+#include <tools/new.hxx>
+#endif
+
+#ifndef _SV_PRINT_H
+#include <print.h>
+#endif
+#ifndef _SV_JOBSET_H
+#include <jobset.h>
+#endif
+
+// =======================================================================
+
+static char aImplWindows[] = "windows";
+static char aImplDevices[] = "devices";
+static char aImplDevice[] = "device";
+
+// =======================================================================
+
+static ULONG ImplWinQueueStatusToSal( DWORD nWinStatus )
+{
+ ULONG nStatus = 0;
+#ifdef WIN
+ if ( nWinStatus & PRINTER_STATUS_PAUSED )
+ nStatus |= QUEUE_STATUS_PAUSED;
+ if ( nWinStatus & PRINTER_STATUS_ERROR )
+ nStatus |= QUEUE_STATUS_ERROR;
+ if ( nWinStatus & PRINTER_STATUS_PENDING_DELETION )
+ nStatus |= QUEUE_STATUS_PENDING_DELETION;
+ if ( nWinStatus & PRINTER_STATUS_PAPER_JAM )
+ nStatus |= QUEUE_STATUS_PAPER_JAM;
+ if ( nWinStatus & PRINTER_STATUS_PAPER_OUT )
+ nStatus |= QUEUE_STATUS_PAPER_OUT;
+ if ( nWinStatus & PRINTER_STATUS_MANUAL_FEED )
+ nStatus |= QUEUE_STATUS_MANUAL_FEED;
+ if ( nWinStatus & PRINTER_STATUS_PAPER_PROBLEM )
+ nStatus |= QUEUE_STATUS_PAPER_PROBLEM;
+ if ( nWinStatus & PRINTER_STATUS_OFFLINE )
+ nStatus |= QUEUE_STATUS_OFFLINE;
+ if ( nWinStatus & PRINTER_STATUS_IO_ACTIVE )
+ nStatus |= QUEUE_STATUS_IO_ACTIVE;
+ if ( nWinStatus & PRINTER_STATUS_BUSY )
+ nStatus |= QUEUE_STATUS_BUSY;
+ if ( nWinStatus & PRINTER_STATUS_PRINTING )
+ nStatus |= QUEUE_STATUS_PRINTING;
+ if ( nWinStatus & PRINTER_STATUS_OUTPUT_BIN_FULL )
+ nStatus |= QUEUE_STATUS_OUTPUT_BIN_FULL;
+ if ( nWinStatus & PRINTER_STATUS_WAITING )
+ nStatus |= QUEUE_STATUS_WAITING;
+ if ( nWinStatus & PRINTER_STATUS_PROCESSING )
+ nStatus |= QUEUE_STATUS_PROCESSING;
+ if ( nWinStatus & PRINTER_STATUS_INITIALIZING )
+ nStatus |= QUEUE_STATUS_INITIALIZING;
+ if ( nWinStatus & PRINTER_STATUS_WARMING_UP )
+ nStatus |= QUEUE_STATUS_WARMING_UP;
+ if ( nWinStatus & PRINTER_STATUS_TONER_LOW )
+ nStatus |= QUEUE_STATUS_TONER_LOW;
+ if ( nWinStatus & PRINTER_STATUS_NO_TONER )
+ nStatus |= QUEUE_STATUS_NO_TONER;
+ if ( nWinStatus & PRINTER_STATUS_PAGE_PUNT )
+ nStatus |= QUEUE_STATUS_PAGE_PUNT;
+ if ( nWinStatus & PRINTER_STATUS_USER_INTERVENTION )
+ nStatus |= QUEUE_STATUS_USER_INTERVENTION;
+ if ( nWinStatus & PRINTER_STATUS_OUT_OF_MEMORY )
+ nStatus |= QUEUE_STATUS_OUT_OF_MEMORY;
+ if ( nWinStatus & PRINTER_STATUS_DOOR_OPEN )
+ nStatus |= QUEUE_STATUS_DOOR_OPEN;
+ if ( nWinStatus & PRINTER_STATUS_SERVER_UNKNOWN )
+ nStatus |= QUEUE_STATUS_SERVER_UNKNOWN;
+ if ( nWinStatus & PRINTER_STATUS_POWER_SAVE )
+ nStatus |= QUEUE_STATUS_POWER_SAVE;
+ if ( !nStatus && !(nWinStatus & PRINTER_STATUS_NOT_AVAILABLE) )
+ nStatus |= QUEUE_STATUS_READY;
+#endif
+ return nStatus;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
+{
+// !!! UNICODE - NT Optimierung !!!
+ DWORD i;
+ DWORD n;
+ DWORD nBytes = 0;
+// DWORD nInfoRet;
+ DWORD nInfoPrn2;
+ BOOL bFound = FALSE;
+#ifdef WIN
+ PRINTER_INFO_2* pWinInfo2 = NULL;
+ PRINTER_INFO_2* pGetInfo2;
+ EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoPrn2 );
+#endif
+ if ( nBytes )
+ {
+#ifdef WIN
+ pWinInfo2 = (PRINTER_INFO_2*)new BYTE[nBytes];
+ if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoPrn2 ) )
+ {
+ pGetInfo2 = pWinInfo2;
+ for ( i = 0; i < nInfoPrn2; i++ )
+ {
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+ pInfo->maPrinterName = ImplSalGetUniString( pGetInfo2->pPrinterName );
+ pInfo->maDriver = ImplSalGetUniString( pGetInfo2->pDriverName );
+ XubString aPortName;
+ if ( pGetInfo2->pPortName )
+ aPortName = ImplSalGetUniString( pGetInfo2->pPortName );
+ // pLocation can be 0 (the Windows docu doesn't describe this)
+ if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) )
+ pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation );
+ else
+ pInfo->maLocation = aPortName;
+ // pComment can be 0 (the Windows docu doesn't describe this)
+ if ( pGetInfo2->pComment )
+ pInfo->maComment = ImplSalGetUniString( pGetInfo2->pComment );
+ pInfo->mnStatus = ImplWinQueueStatusToSal( pGetInfo2->Status );
+ pInfo->mnJobs = pGetInfo2->cJobs;
+ pInfo->mpSysData = new XubString( aPortName );
+ pList->Add( pInfo );
+ pGetInfo2++;
+ }
+
+ bFound = TRUE;
+ }
+#endif
+ }
+
+/* Siehe Kommentar unten !!!
+ EnumPrinters( PRINTER_ENUM_NETWORK | PRINTER_ENUM_REMOTE, NULL, 1, NULL, 0, &nBytes, &nInfoRet );
+ if ( nBytes )
+ {
+ PRINTER_INFO_1* pWinInfo1 = (PRINTER_INFO_1*)new BYTE[nBytes];
+ if ( EnumPrinters( PRINTER_ENUM_NETWORK | PRINTER_ENUM_REMOTE, NULL, 1, (LPBYTE)pWinInfo1, nBytes, &nBytes, &nInfoRet ) )
+ {
+ PRINTER_INFO_1* pGetInfo1 = pWinInfo1;
+ for ( i = 0; i < nInfoRet; i++ )
+ {
+ // Feststellen, ob Printer durch erste Abfrage schon gefunden
+ // wurde
+ BOOL bAdd = TRUE;
+#ifdef WIN
+ if ( pWinInfo2 )
+ {
+ pGetInfo2 = pWinInfo2;
+ for ( n = 0; n < nInfoPrn2; n++ )
+ {
+ if ( strcmp( pGetInfo1->pName, pGetInfo2->pPrinterName ) == 0 )
+ {
+ bAdd = FALSE;
+ break;
+ }
+ pGetInfo2++;
+ }
+ }
+#endif
+ // Wenn neuer Printer, dann aufnehmen
+ if ( bAdd )
+ {
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+ XubString aPrnName( pGetInfo1->pName );
+ pInfo->maPrinterName = aPrnName;
+ pInfo->maDriver = "winspool";
+ pInfo->maComment = pGetInfo1->pComment;
+ pInfo->mnStatus = 0;
+ pInfo->mnJobs = QUEUE_JOBS_DONTKNOW;
+ pInfo->mpSysData = new String();
+ pList->Add( pInfo );
+ }
+ pGetInfo1++;
+ }
+
+ bFound = TRUE;
+ }
+
+ delete pWinInfo1;
+ }
+*/
+
+// if ( bFound )
+// return;
+
+#ifdef WIN
+// !!! UNICODE - NT Optimierung !!!
+ // Drucker aus WIN.INI lesen
+ UINT nSize = 4096;
+ char* pBuf = new char[nSize];
+ UINT nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize );
+ while ( nRead >= nSize-2 )
+ {
+ nSize += 2048;
+ delete pBuf;
+ pBuf = new char[nSize];
+ nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize );
+ }
+
+ // Druckernamen aus Buffer extrahieren und Liste aufbauen
+ char* pName = pBuf;
+ while ( *pName )
+ {
+ char* pPortName;
+ char* pTmp;
+ char aPortBuf[256];
+ GetProfileStringA( aImplDevices, pName, "", aPortBuf, sizeof( aPortBuf ) );
+
+ pPortName = aPortBuf;
+
+ // Namen anlegen
+ xub_StrLen nNameLen = strlen( pName );
+ XubString aName( ImplSalGetUniString( pName, nNameLen ) );
+
+ // Treibernamen rausfischen
+ pTmp = pPortName;
+ while ( *pTmp != ',' )
+ pTmp++;
+ XubString aDriver( ImplSalGetUniString( pPortName, (USHORT)(pTmp-pPortName) ) );
+ pPortName = pTmp;
+
+ // Alle Portnamen raussuchen
+ do
+ {
+ pPortName++;
+ pTmp = pPortName;
+ while ( *pTmp && (*pTmp != ',') )
+ pTmp++;
+
+ String aPortName( ImplSalGetUniString( pPortName, (USHORT)(pTmp-pPortName) ) );
+
+ // Neuen Eintrag anlegen
+ // !!! Da ich zu bloeb bin, die Netzwerk-Printer zur 5.0
+ // !!! richtig zu integrieren, gehen wir zusaetzlich
+ // !!! noch ueber das W16-Interface, da uns dort die
+ // !!! Drucker noch einfach und schnell geliefert werden
+ // !!! ohne das wir jetzt zu grossen Aufwand treiben muessen.
+ // !!! Somit sollten wir dann jedenfalls nicht schlechter sein
+ // !!! als in einer 4.0 SP2.
+ // Feststellen, ob Printer durch erste Abfrage schon gefunden
+ // wurde
+ BOOL bAdd = TRUE;
+ if ( pWinInfo2 )
+ {
+ pGetInfo2 = pWinInfo2;
+ for ( n = 0; n < nInfoPrn2; n++ )
+ {
+ if ( aName.EqualsIgnoreCaseAscii( pGetInfo2->pPrinterName ) )
+ {
+ bAdd = FALSE;
+ break;
+ }
+ pGetInfo2++;
+ }
+ }
+ // Wenn neuer Printer, dann aufnehmen
+ if ( bAdd )
+ {
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+ pInfo->maPrinterName = aName;
+ pInfo->maDriver = aDriver;
+ pInfo->maLocation = aPortName;
+ pInfo->mnStatus = 0;
+ pInfo->mnJobs = QUEUE_JOBS_DONTKNOW;
+ pInfo->mpSysData = new XubString( aPortName );
+ pList->Add( pInfo );
+ }
+ }
+ while ( *pTmp == ',' );
+
+ pName += nNameLen + 1;
+ }
+
+ delete pBuf;
+ delete pWinInfo2;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo )
+{
+// !!! UNICODE - NT Optimierung !!!
+ DWORD nBytes = 0;
+ DWORD nInfoRet;
+#ifdef WIN
+ PRINTER_INFO_2* pWinInfo2;
+ EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoRet );
+#endif
+ if ( nBytes )
+ {
+#ifdef WIN
+ pWinInfo2 = (PRINTER_INFO_2*)new BYTE[nBytes];
+ if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoRet ) )
+ {
+ PRINTER_INFO_2* pGetInfo2 = pWinInfo2;
+ for ( DWORD i = 0; i < nInfoRet; i++ )
+ {
+ if ( pInfo->maPrinterName.EqualsAscii( pGetInfo2->pPrinterName ) &&
+ pInfo->maDriver.EqualsAscii( pGetInfo2->pDriverName ) )
+ {
+ if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) )
+ pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation );
+ else
+ pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pPortName );
+ pInfo->mnStatus = ImplWinQueueStatusToSal( pGetInfo2->Status );
+ pInfo->mnJobs = pGetInfo2->cJobs;
+ break;
+ }
+
+ pGetInfo2++;
+ }
+ }
+
+ delete pWinInfo2;
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
+{
+ delete (String*)(pInfo->mpSysData);
+ delete pInfo;
+}
+
+// -----------------------------------------------------------------------
+
+// !!! UNICODE - NT Optimierung !!!
+XubString SalInstance::GetDefaultPrinter()
+{
+ // Default-Printer-String aus win.ini holen
+ char szBuffer[256];
+#ifdef WIN
+ GetProfileStringA( aImplWindows, aImplDevice, "", szBuffer, sizeof( szBuffer ) );
+#endif
+ if ( szBuffer[0] )
+ {
+ // Printername suchen
+ char* pBuf = szBuffer;
+ char* pTmp = pBuf;
+ while ( *pTmp && (*pTmp != ',') )
+ pTmp++;
+ return ImplSalGetUniString( pBuf, (xub_StrLen)(pTmp-pBuf) );
+ }
+ else
+ return XubString();
+}
+
+// =======================================================================
+
+static DWORD ImplDeviceCaps( SalInfoPrinter* pPrinter, WORD nCaps,
+ LPTSTR pOutput, const ImplJobSetup* pSetupData )
+{
+#ifdef WIN
+ DEVMODE* pDevMode;
+ if ( !pSetupData || !pSetupData->mpDriverData )
+ pDevMode = NULL;
+ else
+ pDevMode = SAL_DEVMODE( pSetupData );
+
+// !!! UNICODE - NT Optimierung !!!
+ return DeviceCapabilitiesA( ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ ImplSalGetWinAnsiString( pPrinter->maPrinterData.maPortName, TRUE ).GetBuffer(),
+ nCaps, (LPSTR)pOutput, pDevMode );
+#else
+ return 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplTestSalJobSetup( SalInfoPrinter* pPrinter,
+ ImplJobSetup* pSetupData, BOOL bDelete )
+{
+ if ( pSetupData && pSetupData->mpDriverData )
+ {
+ // Signature und Groesse muss uebereinstimmen, damit wir keine
+ // JobSetup's von anderen Systemen setzen
+ if ( (pSetupData->mnSystem == JOBSETUP_SYSTEM_WINDOWS) &&
+ (pSetupData->mnDriverDataLen > sizeof( SalDriverData )) &&
+ (((SalDriverData*)(pSetupData->mpDriverData))->mnSysSignature == SAL_DRIVERDATA_SYSSIGN) )
+ return TRUE;
+ else if ( bDelete )
+ {
+ delete pSetupData->mpDriverData;
+ pSetupData->mpDriverData = NULL;
+ pSetupData->mnDriverDataLen = 0;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplUpdateSalJobSetup( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData,
+ BOOL bIn, SalFrame* pVisibleDlgParent )
+{
+#ifdef WIN
+ HANDLE hPrn;
+// !!! UNICODE - NT Optimierung !!!
+ if ( !OpenPrinterA( (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(), &hPrn, NULL ) )
+ return FALSE;
+
+ LONG nRet;
+ LONG nSysJobSize;
+ HWND hWnd = 0;
+ DWORD nMode = DM_OUT_BUFFER;
+ ULONG nDriverDataLen = 0;
+ SalDriverData* pOutBuffer = NULL;
+ DEVMODE* pInDevBuffer = NULL;
+ DEVMODE* pOutDevBuffer = NULL;
+
+// !!! UNICODE - NT Optimierung !!!
+ nSysJobSize = DocumentPropertiesA( hWnd, hPrn,
+ (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ NULL, NULL, 0 );
+ if ( nSysJobSize < 0 )
+ {
+ ClosePrinter( hPrn );
+ return FALSE;
+ }
+
+ // Outputbuffer anlegen
+ nDriverDataLen = sizeof(SalDriverData)+nSysJobSize-1;
+ pOutBuffer = (SalDriverData*)SvMemAlloc( nDriverDataLen );
+ memset( pOutBuffer, 0, nDriverDataLen );
+ pOutDevBuffer = (LPDEVMODE)(pOutBuffer->maDriverData);
+ pOutBuffer->mnSysSignature = SAL_DRIVERDATA_SYSSIGN;
+ pOutBuffer->mnVersion = SAL_DRIVERDATA_VERSION;
+ pOutBuffer->mnDriverOffset = (USHORT)(((SalDriverData*)NULL)->maDriverData);
+
+ // Testen, ob wir einen geeigneten Inputbuffer haben
+ if ( bIn && ImplTestSalJobSetup( pPrinter, pSetupData, FALSE ) )
+ {
+ pInDevBuffer = SAL_DEVMODE( pSetupData );
+ nMode |= DM_IN_BUFFER;
+ }
+
+ // Testen, ob Dialog angezeigt werden soll
+ if ( pVisibleDlgParent )
+ {
+ hWnd = pVisibleDlgParent->maFrameData.mhWnd;
+ nMode |= DM_IN_PROMPT;
+ }
+
+// !!! UNICODE - NT Optimierung !!!
+ // Release mutex, in the other case we don't get paints and so on
+ ULONG nMutexCount = ImplSalReleaseYieldMutex();
+ nRet = DocumentPropertiesA( hWnd, hPrn,
+ (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ pOutDevBuffer, pInDevBuffer, nMode );
+ ImplSalAcquireYieldMutex( nMutexCount );
+ ClosePrinter( hPrn );
+
+ if ( (nRet < 0) || (pVisibleDlgParent && (nRet == IDCANCEL)) )
+ {
+ SvMemFree( pOutBuffer );
+ return FALSE;
+ }
+
+ // String-Buffer am Ende immer mit 0 initialisieren, damit
+ // die JobSetups nach Moeglichkeit bei memcmp immer
+ // identisch sind
+ if ( pOutDevBuffer->dmSize >= 32 )
+ {
+ USHORT nLen = strlen( (const char*)pOutDevBuffer->dmDeviceName );
+ if ( nLen < sizeof( pOutDevBuffer->dmDeviceName ) )
+ memset( pOutDevBuffer->dmDeviceName+nLen, 0, sizeof( pOutDevBuffer->dmDeviceName )-nLen );
+ }
+ if ( pOutDevBuffer->dmSize >= 102 )
+ {
+ USHORT nLen = strlen( (const char*)pOutDevBuffer->dmFormName );
+ if ( nLen < sizeof( pOutDevBuffer->dmFormName ) )
+ memset( pOutDevBuffer->dmFormName+nLen, 0, sizeof( pOutDevBuffer->dmFormName )-nLen );
+ }
+
+ // Daten updaten
+ if ( pSetupData->mpDriverData )
+ delete pSetupData->mpDriverData;
+ pSetupData->mnDriverDataLen = nDriverDataLen;
+ pSetupData->mpDriverData = (BYTE*)pOutBuffer;
+ pSetupData->mnSystem = JOBSETUP_SYSTEM_WINDOWS;
+
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDevModeToJobSetup( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, ULONG nFlags )
+{
+#ifdef WIN
+ if ( !pSetupData || !pSetupData->mpDriverData )
+ return;
+
+ DEVMODE* pDevMode = SAL_DEVMODE( pSetupData );
+
+ // Orientation
+ if ( nFlags & SAL_JOBSET_ORIENTATION )
+ {
+ if ( pDevMode->dmOrientation == DMORIENT_PORTRAIT )
+ pSetupData->meOrientation = ORIENTATION_PORTRAIT;
+ else if ( pDevMode->dmOrientation == DMORIENT_LANDSCAPE )
+ pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
+ }
+
+ // PaperBin
+ if ( nFlags & SAL_JOBSET_PAPERBIN )
+ {
+ ULONG nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData );
+
+ if ( nCount && (nCount != ((ULONG)-1)) )
+ {
+ WORD* pBins = new WORD[nCount];
+ memset( (BYTE*)pBins, 0, nCount*sizeof(WORD) );
+ ImplDeviceCaps( pPrinter, DC_BINS, (LPTSTR)pBins, pSetupData );
+ pSetupData->mnPaperBin = 0;
+
+ // search the right bin and assign index to mnPaperBin
+ for( ULONG i = 0; i < nCount; i++ )
+ {
+ if( pDevMode->dmDefaultSource == pBins[ i ] )
+ {
+ pSetupData->mnPaperBin = (USHORT)i;
+ break;
+ }
+ }
+
+ delete[] pBins;
+ }
+ }
+
+ // PaperSize
+ if ( nFlags & SAL_JOBSET_PAPERSIZE )
+ {
+ pSetupData->mnPaperWidth = pDevMode->dmPaperWidth*10;
+ pSetupData->mnPaperHeight = pDevMode->dmPaperLength*10;
+ switch( pDevMode->dmPaperSize )
+ {
+ case( DMPAPER_A3 ):
+ pSetupData->mePaperFormat = PAPER_A3;
+ break;
+ case( DMPAPER_A4 ):
+ pSetupData->mePaperFormat = PAPER_A4;
+ break;
+ case( DMPAPER_A5 ):
+ pSetupData->mePaperFormat = PAPER_A5;
+ break;
+ case( DMPAPER_B4 ):
+ pSetupData->mePaperFormat = PAPER_B4;
+ break;
+ case( DMPAPER_B5 ):
+ pSetupData->mePaperFormat = PAPER_B5;
+ break;
+ case( DMPAPER_LETTER ):
+ pSetupData->mePaperFormat = PAPER_LETTER;
+ break;
+ case( DMPAPER_LEGAL ):
+ pSetupData->mePaperFormat = PAPER_LEGAL;
+ break;
+ case( DMPAPER_TABLOID ):
+ pSetupData->mePaperFormat = PAPER_TABLOID;
+ break;
+ default:
+ pSetupData->mePaperFormat = PAPER_USER;
+ break;
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplPaperSizeEqual( short nPaperWidth1, short nPaperHeight1,
+ short nPaperWidth2, short nPaperHeight2 )
+{
+ return (((nPaperWidth1 >= nPaperWidth2-1) && (nPaperWidth1 <= nPaperWidth2+1)) &&
+ ((nPaperHeight1 >= nPaperHeight2-1) && (nPaperHeight1 <= nPaperHeight2+1)));
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplJobSetupToDevMode( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, ULONG nFlags )
+{
+#ifdef WIN
+ if ( !pSetupData || !pSetupData->mpDriverData )
+ return;
+
+ DEVMODE* pDevMode = SAL_DEVMODE( pSetupData );
+
+ // Orientation
+ if ( nFlags & SAL_JOBSET_ORIENTATION )
+ {
+ pDevMode->dmFields |= DM_ORIENTATION;
+ if ( pSetupData->meOrientation == ORIENTATION_PORTRAIT )
+ pDevMode->dmOrientation = DMORIENT_PORTRAIT;
+ else
+ pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
+ }
+
+ // PaperBin
+ if ( nFlags & SAL_JOBSET_PAPERBIN )
+ {
+ ULONG nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData );
+
+ if ( nCount && (nCount != ((ULONG)-1)) )
+ {
+ WORD* pBins = new WORD[nCount];
+ memset( pBins, 0, nCount*sizeof(WORD) );
+ ImplDeviceCaps( pPrinter, DC_BINS, (LPTSTR)pBins, pSetupData );
+ pDevMode->dmFields |= DM_DEFAULTSOURCE;
+ pDevMode->dmDefaultSource = pBins[ pSetupData->mnPaperBin ];
+ delete[] pBins;
+ }
+ }
+
+ // PaperSize
+ if ( nFlags & SAL_JOBSET_PAPERSIZE )
+ {
+ pDevMode->dmFields |= DM_PAPERSIZE;
+ pDevMode->dmPaperWidth = 0;
+ pDevMode->dmPaperLength = 0;
+
+ switch( pDevMode->dmPaperSize )
+ {
+ case( PAPER_A3 ):
+ pDevMode->dmPaperSize = DMPAPER_A3;
+ break;
+ case( PAPER_A4 ):
+ pDevMode->dmPaperSize = DMPAPER_A4;
+ break;
+ case( PAPER_A5 ):
+ pDevMode->dmPaperSize = DMPAPER_A5;
+ break;
+ case( PAPER_B4 ):
+ pDevMode->dmPaperSize = DMPAPER_B4;
+ break;
+ case( PAPER_B5 ):
+ pDevMode->dmPaperSize = DMPAPER_B5;
+ break;
+ case( PAPER_LETTER ):
+ pDevMode->dmPaperSize = DMPAPER_LETTER;
+ break;
+ case( PAPER_LEGAL ):
+ pDevMode->dmPaperSize = DMPAPER_LEGAL;
+ break;
+ case( PAPER_TABLOID ):
+ pDevMode->dmPaperSize = DMPAPER_TABLOID;
+ break;
+ default:
+ {
+ short nPaper = 0;
+ ULONG nPaperCount = ImplDeviceCaps( pPrinter, DC_PAPERS, NULL, pSetupData );
+ WORD* pPapers = NULL;
+ ULONG nPaperSizeCount = ImplDeviceCaps( pPrinter, DC_PAPERSIZE, NULL, pSetupData );
+ POINT* pPaperSizes = NULL;
+ if ( nPaperCount && (nPaperCount != ((ULONG)-1)) )
+ {
+ pPapers = new WORD[nPaperCount];
+ memset( pPapers, 0, nPaperCount*sizeof(WORD) );
+ ImplDeviceCaps( pPrinter, DC_PAPERS, (LPTSTR)pPapers, pSetupData );
+ }
+ if ( nPaperSizeCount && (nPaperSizeCount != ((ULONG)-1)) )
+ {
+ pPaperSizes = new POINT[nPaperSizeCount];
+ memset( pPaperSizes, 0, nPaperSizeCount*sizeof(POINT) );
+ ImplDeviceCaps( pPrinter, DC_PAPERSIZE, (LPTSTR)pPaperSizes, pSetupData );
+ }
+ if ( (nPaperSizeCount == nPaperCount) && pPapers && pPaperSizes )
+ {
+ // Alle Papierformate vergleichen und ein passendes
+ // raussuchen
+ for ( ULONG i = 0; i < nPaperCount; i++ )
+ {
+ if ( ImplPaperSizeEqual( (short)(pSetupData->mnPaperWidth/10),
+ (short)(pSetupData->mnPaperHeight/10),
+ (short)pPaperSizes[i].x,
+ (short)pPaperSizes[i].y ) )
+ {
+ nPaper = pPapers[i];
+ break;
+ }
+ }
+ }
+ if ( pPapers )
+ delete pPapers;
+ if ( pPaperSizes )
+ delete pPaperSizes;
+
+ if ( nPaper )
+ pDevMode->dmPaperSize = nPaper;
+ else
+ {
+ pDevMode->dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH;
+ pDevMode->dmPaperSize = DMPAPER_USER;
+ pDevMode->dmPaperWidth = pSetupData->mnPaperWidth/10;
+ pDevMode->dmPaperLength = pSetupData->mnPaperHeight/10;
+ }
+ }
+ break;
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static HDC ImplCreateSalPrnIC( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData )
+{
+#ifdef WIN
+ LPDEVMODE pDevMode;
+ if ( pSetupData && pSetupData->mpDriverData )
+ pDevMode = SAL_DEVMODE( pSetupData );
+ else
+ pDevMode = NULL;
+// !!! UNICODE - NT Optimierung !!!
+ HDC hDC = CreateICA( ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDriverName, TRUE ).GetBuffer(),
+ ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ 0,
+ (LPDEVMODE)pDevMode );
+ return hDC;
+#else
+ return NULL;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static SalGraphics* ImplCreateSalPrnGraphics( HDC hDC )
+{
+ SalGraphics* pGraphics = new SalGraphics;
+ pGraphics->maGraphicsData.mhDC = hDC;
+ pGraphics->maGraphicsData.mhWnd = 0;
+ pGraphics->maGraphicsData.mbPrinter = TRUE;
+ pGraphics->maGraphicsData.mbVirDev = FALSE;
+ pGraphics->maGraphicsData.mbWindow = FALSE;
+ pGraphics->maGraphicsData.mbScreen = FALSE;
+ ImplSalInitGraphics( &(pGraphics->maGraphicsData) );
+ return pGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplUpdateSalPrnIC( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData )
+{
+ HDC hNewDC = ImplCreateSalPrnIC( pPrinter, pSetupData );
+ if ( !hNewDC )
+ return FALSE;
+
+ if ( pPrinter->maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) );
+#ifdef WIN
+ DeleteDC( pPrinter->maPrinterData.mpGraphics->maGraphicsData.mhDC );
+#endif
+ delete pPrinter->maPrinterData.mpGraphics;
+ }
+
+ SalGraphics* pGraphics = ImplCreateSalPrnGraphics( hNewDC );
+ pPrinter->maPrinterData.mhDC = hNewDC;
+ pPrinter->maPrinterData.mpGraphics = pGraphics;
+
+ return TRUE;
+}
+
+// =======================================================================
+
+SalInfoPrinter* SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
+ ImplJobSetup* pSetupData )
+{
+ SalInfoPrinter* pPrinter = new SalInfoPrinter;
+ pPrinter->maPrinterData.maDriverName = pQueueInfo->maDriver;
+ pPrinter->maPrinterData.maDeviceName = pQueueInfo->maPrinterName;
+ pPrinter->maPrinterData.maPortName = *(String*)(pQueueInfo->mpSysData);
+
+ // Testen, ob Setupdaten zum Drucker gehoeren (erst aufrufen, nachdem
+ // die Member gesetzt sind, da diese in dieser Routine abgefragt werden)
+ ImplTestSalJobSetup( pPrinter, pSetupData, TRUE );
+
+ HDC hDC = ImplCreateSalPrnIC( pPrinter, pSetupData );
+ if ( !hDC )
+ {
+ delete pPrinter;
+ return NULL;
+ }
+
+ SalGraphics* pGraphics = ImplCreateSalPrnGraphics( hDC );
+ pPrinter->maPrinterData.mhDC = hDC;
+ pPrinter->maPrinterData.mpGraphics = pGraphics;
+ if ( !pSetupData->mpDriverData )
+ ImplUpdateSalJobSetup( pPrinter, pSetupData, FALSE, NULL );
+ ImplDevModeToJobSetup( pPrinter, pSetupData, SAL_JOBSET_ALL );
+ pSetupData->mnSystem = JOBSETUP_SYSTEM_WINDOWS;
+
+ return pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
+{
+ delete pPrinter;
+}
+
+// =======================================================================
+
+SalInfoPrinter::SalInfoPrinter()
+{
+ maPrinterData.mhDC = 0;
+ maPrinterData.mpGraphics = NULL;
+ maPrinterData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SalInfoPrinter::~SalInfoPrinter()
+{
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+#ifdef WIN
+ DeleteDC( maPrinterData.mpGraphics->maGraphicsData.mhDC );
+#endif
+ delete maPrinterData.mpGraphics;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalInfoPrinter::GetGraphics()
+{
+ if ( maPrinterData.mbGraphics )
+ return NULL;
+
+ if ( maPrinterData.mpGraphics )
+ maPrinterData.mbGraphics = TRUE;
+
+ return maPrinterData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInfoPrinter::ReleaseGraphics( SalGraphics* )
+{
+ maPrinterData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData )
+{
+ if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, pFrame ) )
+ {
+ ImplDevModeToJobSetup( this, pSetupData, SAL_JOBSET_ALL );
+ return ImplUpdateSalPrnIC( this, pSetupData );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::SetPrinterData( ImplJobSetup* pSetupData )
+{
+ if ( !ImplTestSalJobSetup( this, pSetupData, FALSE ) )
+ return FALSE;
+ return ImplUpdateSalPrnIC( this, pSetupData );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::SetData( ULONG nFlags, ImplJobSetup* pSetupData )
+{
+ ImplJobSetupToDevMode( this, pSetupData, nFlags );
+ if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, NULL ) )
+ {
+ ImplDevModeToJobSetup( this, pSetupData, nFlags );
+ return ImplUpdateSalPrnIC( this, pSetupData );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pSetupData )
+{
+#ifdef WIN
+ DWORD nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return nRet;
+ else
+#endif
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pSetupData, ULONG nPaperBin )
+{
+// !!! UNICODE - NT Optimierung !!!
+ XubString aPaperBinName;
+
+#ifdef WIN
+ DWORD nBins = ImplDeviceCaps( this, DC_BINNAMES, NULL, pSetupData );
+ if ( (nPaperBin < nBins) && (nBins != ((ULONG)-1)) )
+ {
+ char* pBuffer = new char[nBins*24];
+ DWORD nRet = ImplDeviceCaps( this, DC_BINNAMES, pBuffer, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ aPaperBinName = ImplSalGetUniString( (const char*)(pBuffer + (nPaperBin*24)) );
+ delete pBuffer;
+ }
+#endif
+
+ return aPaperBinName;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInfoPrinter::GetCapabilities( const ImplJobSetup* pSetupData, USHORT nType )
+{
+#ifdef WIN
+ DWORD nRet;
+
+ switch ( nType )
+ {
+ case PRINTER_CAPABILITIES_SUPPORTDIALOG:
+ return TRUE;
+ case PRINTER_CAPABILITIES_COPIES:
+ nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return nRet;
+ return 0;
+ case PRINTER_CAPABILITIES_COLLATECOPIES:
+ nRet = ImplDeviceCaps( this, DC_COLLATE, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ {
+ nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return nRet;
+ }
+ return 0;
+
+ case PRINTER_CAPABILITIES_SETORIENTATION:
+ nRet = ImplDeviceCaps( this, DC_ORIENTATION, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return TRUE;
+ return FALSE;
+
+ case PRINTER_CAPABILITIES_SETPAPERBIN:
+ nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return TRUE;
+ return FALSE;
+
+ case PRINTER_CAPABILITIES_SETPAPERSIZE:
+ case PRINTER_CAPABILITIES_SETPAPER:
+ nRet = ImplDeviceCaps( this, DC_PAPERS, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return TRUE;
+ return FALSE;
+ }
+#endif
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInfoPrinter::GetPageInfo( const ImplJobSetup*,
+ long& rOutWidth, long& rOutHeight,
+ long& rPageOffX, long& rPageOffY,
+ long& rPageWidth, long& rPageHeight )
+{
+ HDC hDC = maPrinterData.mhDC;
+
+#ifdef WIN
+ rOutWidth = GetDeviceCaps( hDC, HORZRES );
+ rOutHeight = GetDeviceCaps( hDC, VERTRES );
+
+ rPageOffX = GetDeviceCaps( hDC, PHYSICALOFFSETX );
+ rPageOffY = GetDeviceCaps( hDC, PHYSICALOFFSETY );
+ rPageWidth = GetDeviceCaps( hDC, PHYSICALWIDTH );
+ rPageHeight = GetDeviceCaps( hDC, PHYSICALHEIGHT );
+#endif
+}
+
+// =======================================================================
+
+SalPrinter* SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
+{
+ SalPrinter* pPrinter = new SalPrinter;
+ pPrinter->maPrinterData.mpInfoPrinter = pInfoPrinter;
+ return pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyPrinter( SalPrinter* pPrinter )
+{
+ delete pPrinter;
+}
+
+// =======================================================================
+
+WIN_BOOL CALLBACK SalPrintAbortProc( HDC hPrnDC, int /* nError */ )
+{
+ SalData* pSalData = GetSalData();
+ SalPrinter* pPrinter;
+ BOOL bWhile = TRUE;
+ int i = 0;
+
+ do
+ {
+#ifdef WIN
+ // Messages verarbeiten
+ MSG aMsg;
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplDispatchMessage( &aMsg );
+ i++;
+ if ( i > 15 )
+ bWhile = FALSE;
+ }
+ else
+#endif
+ bWhile = FALSE;
+
+ pPrinter = pSalData->mpFirstPrinter;
+ while ( pPrinter )
+ {
+ if( pPrinter->maPrinterData.mhDC == hPrnDC )
+ break;
+
+ pPrinter = pPrinter->maPrinterData.mpNextPrinter;
+ }
+
+ if ( !pPrinter || pPrinter->maPrinterData.mbAbort )
+ return FALSE;
+ }
+ while ( bWhile );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+static LPDEVMODE ImplSalSetCopies( LPDEVMODE pDevMode, ULONG nCopies, BOOL bCollate )
+{
+ LPDEVMODE pNewDevMode = pDevMode;
+ if ( pDevMode && (nCopies > 1) )
+ {
+ if ( nCopies > 32765 )
+ nCopies = 32765;
+ ULONG nDevSize = pDevMode->dmSize+pDevMode->dmDriverExtra;
+ pNewDevMode = (LPDEVMODE)new BYTE[nDevSize];
+ memcpy( pNewDevMode, pDevMode, nDevSize );
+ pDevMode = pNewDevMode;
+ pDevMode->dmFields |= DM_COPIES;
+ pDevMode->dmCopies = (short)(USHORT)nCopies;
+ if ( aSalShlData.mbW40 )
+ {
+ pDevMode->dmFields |= DM_COLLATE;
+ if ( bCollate )
+ pDevMode->dmCollate = DMCOLLATE_TRUE;
+ else
+ pDevMode->dmCollate = DMCOLLATE_FALSE;
+ }
+ }
+
+ return pNewDevMode;
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+SalPrinter::SalPrinter()
+{
+ SalData* pSalData = GetSalData();
+
+ maPrinterData.mhDC = 0;
+ maPrinterData.mpGraphics = NULL;
+ maPrinterData.mbAbort = FALSE;
+ maPrinterData.mnCopies = 0;
+ maPrinterData.mbCollate = FALSE;
+
+ // insert frame in framelist
+ maPrinterData.mpNextPrinter = pSalData->mpFirstPrinter;
+ pSalData->mpFirstPrinter = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalPrinter::~SalPrinter()
+{
+ SalData* pSalData = GetSalData();
+
+ // DC freigeben, wenn er noch durch ein AbortJob existiert
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC )
+ {
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ }
+
+#ifdef WIN
+ DeleteDC( hDC );
+#endif
+ }
+
+ // remove printer from printerlist
+ if ( this == pSalData->mpFirstPrinter )
+ pSalData->mpFirstPrinter = maPrinterData.mpNextPrinter;
+ else
+ {
+ SalPrinter* pTempPrinter = pSalData->mpFirstPrinter;
+
+ while( pTempPrinter->maPrinterData.mpNextPrinter != this )
+ pTempPrinter = pTempPrinter->maPrinterData.mpNextPrinter;
+
+ pTempPrinter->maPrinterData.mpNextPrinter = maPrinterData.mpNextPrinter;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::StartJob( const XubString* pFileName,
+ const XubString& rJobName,
+ const XubString&,
+ ULONG nCopies, BOOL bCollate,
+ ImplJobSetup* pSetupData )
+{
+#ifdef WIN
+ maPrinterData.mnError = 0;
+ maPrinterData.mbAbort = FALSE;
+ maPrinterData.mnCopies = nCopies;
+ maPrinterData.mbCollate = bCollate;
+
+ LPDEVMODE pOrgDevMode = NULL;
+ LPDEVMODE pDevMode;
+ BOOL bOwnDevMode = FALSE;
+ if ( pSetupData && pSetupData->mpDriverData )
+ {
+ pOrgDevMode = SAL_DEVMODE( pSetupData );
+ pDevMode = ImplSalSetCopies( pOrgDevMode, nCopies, bCollate );
+ }
+ else
+ pDevMode = NULL;
+
+// !!! UNICODE - NT Optimierung !!!
+ HDC hDC = CreateDCA( ImplSalGetWinAnsiString( maPrinterData.mpInfoPrinter->maPrinterData.maDriverName, TRUE ).GetBuffer(),
+ ImplSalGetWinAnsiString( maPrinterData.mpInfoPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ 0,
+ (LPDEVMODEA)pDevMode );
+
+ if ( pDevMode != pOrgDevMode )
+ delete pDevMode;
+
+ if ( !hDC )
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ if ( SetAbortProc( hDC, SalPrintAbortProc ) <= 0 )
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ maPrinterData.mnError = 0;
+ maPrinterData.mbAbort = FALSE;
+
+// !!! UNICODE - NT Optimierung !!!
+ // Both strings must be exist, if StartJob() is called
+ ByteString aJobName( ImplSalGetWinAnsiString( rJobName, TRUE ) );
+ ByteString aFileName;
+
+ DOCINFO aInfo;
+ memset( &aInfo, 0, sizeof( DOCINFO ) );
+ aInfo.cbSize = sizeof( aInfo );
+ aInfo.lpszDocName = (LPCSTR)aJobName.GetBuffer();
+ if ( pFileName )
+ {
+ if ( pFileName->Len() )
+ {
+ aFileName = ImplSalGetWinAnsiString( *pFileName, TRUE );
+ aInfo.lpszOutput = (LPCSTR)aFileName.GetBuffer();
+ }
+ else
+ aInfo.lpszOutput = "FILE:";
+ }
+ else
+ aInfo.lpszOutput = NULL;
+
+ // Wegen Telocom Balloon Fax-Treiber, der uns unsere Messages
+ // ansonsten oefters schickt, versuchen wir vorher alle
+ // zu verarbeiten und dann eine Dummy-Message reinstellen
+ BOOL bWhile = TRUE;
+ int i = 0;
+ do
+ {
+ // Messages verarbeiten
+ MSG aMsg;
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplDispatchMessage( &aMsg );
+ i++;
+ if ( i > 15 )
+ bWhile = FALSE;
+ }
+ else
+ bWhile = FALSE;
+ }
+ while ( bWhile );
+ ImplPostMessage( GetSalData()->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_DUMMY, 0, 0 );
+
+ // Job starten
+ int nRet = ::StartDoc( hDC, &aInfo );
+ if ( nRet <= 0 )
+ {
+ if ( (nRet == SP_USERABORT) || (nRet == SP_APPABORT) || (GetLastError() == ERROR_PRINT_CANCELLED) )
+ maPrinterData.mnError = SAL_PRINTER_ERROR_ABORT;
+ else
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ maPrinterData.mhDC = hDC;
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::EndJob()
+{
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC )
+ {
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ maPrinterData.mpGraphics = NULL;
+ }
+
+#ifdef WIN
+ ::EndDoc( hDC );
+ DeleteDC( hDC );
+#endif
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::AbortJob()
+{
+ maPrinterData.mbAbort = TRUE;
+
+ // Abort asyncron ausloesen
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC )
+ {
+ SalData* pSalData = GetSalData();
+#ifdef WIN
+ ImplPostMessage( pSalData->mpFirstInstance->maInstData.mhComWnd,
+ SAL_MSG_PRINTABORTJOB, (WPARAM)hDC, 0 );
+#endif
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalPrinterAbortJobAsync( HDC hPrnDC )
+{
+ SalData* pSalData = GetSalData();
+ SalPrinter* pPrinter = pSalData->mpFirstPrinter;
+
+ // Feststellen, ob Printer noch existiert
+ while ( pPrinter )
+ {
+ if ( pPrinter->maPrinterData.mhDC == hPrnDC )
+ break;
+
+ pPrinter = pPrinter->maPrinterData.mpNextPrinter;
+ }
+
+ // Wenn Printer noch existiert, dann den Job abbrechen
+ if ( pPrinter )
+ {
+ HDC hDC = pPrinter->maPrinterData.mhDC;
+ if ( hDC )
+ {
+ if ( pPrinter->maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) );
+ delete pPrinter->maPrinterData.mpGraphics;
+ pPrinter->maPrinterData.mpGraphics = NULL;
+ }
+
+#ifdef WIN
+ ::AbortDoc( hDC );
+ DeleteDC( hDC );
+#endif
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalPrinter::StartPage( ImplJobSetup* pSetupData, BOOL bNewJobData )
+{
+ HDC hDC = maPrinterData.mhDC;
+#ifdef WIN
+ if ( pSetupData && pSetupData->mpDriverData && bNewJobData )
+ {
+ LPDEVMODE pOrgDevMode;
+ LPDEVMODE pDevMode;
+ pOrgDevMode = SAL_DEVMODE( pSetupData );
+ pDevMode = ImplSalSetCopies( pOrgDevMode, maPrinterData.mnCopies, maPrinterData.mbCollate );
+ ResetDC( hDC, pDevMode );
+ if ( pDevMode != pOrgDevMode )
+ delete pDevMode;
+ }
+ int nRet = ::StartPage( hDC );
+ if ( nRet <= 0 )
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return NULL;
+ }
+
+ // Hack, damit alte PS-Treiber Leerseiten nicht wegoptimieren
+ HPEN hTempPen = SelectPen( hDC, GetStockPen( NULL_PEN ) );
+ HBRUSH hTempBrush = SelectBrush( hDC, GetStockBrush( NULL_BRUSH ) );
+ WIN_Rectangle( hDC, -8000, -8000, -7999, -7999 );
+ SelectPen( hDC, hTempPen );
+ SelectBrush( hDC, hTempBrush );
+#endif
+
+ SalGraphics* pGraphics = new SalGraphics;
+ pGraphics->maGraphicsData.mhDC = hDC;
+ pGraphics->maGraphicsData.mhWnd = 0;
+ pGraphics->maGraphicsData.mbPrinter = TRUE;
+ pGraphics->maGraphicsData.mbVirDev = FALSE;
+ pGraphics->maGraphicsData.mbWindow = FALSE;
+ pGraphics->maGraphicsData.mbScreen = FALSE;
+ ImplSalInitGraphics( &(pGraphics->maGraphicsData) );
+ maPrinterData.mpGraphics = pGraphics;
+ return pGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::EndPage()
+{
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC && maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ maPrinterData.mpGraphics = NULL;
+ }
+#ifdef WIN
+ int nRet = ::EndPage( hDC );
+ if ( nRet > 0 )
+ return TRUE;
+ else
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+#else
+ return FALSE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalPrinter::GetErrorCode()
+{
+ return maPrinterData.mnError;
+}
diff --git a/vcl/aqua/source/gdi/salvd.cxx b/vcl/aqua/source/gdi/salvd.cxx
new file mode 100644
index 000000000000..f0c33af6d17e
--- /dev/null
+++ b/vcl/aqua/source/gdi/salvd.cxx
@@ -0,0 +1,234 @@
+/*************************************************************************
+ *
+ * $RCSfile: salvd.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALVD_CXX
+
+#ifndef _SV_SALAQUA_HXX
+#include <salaqua.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+
+// =======================================================================
+
+static HBITMAP ImplCreateVirDevBitmap( HDC hDC, long nDX, long nDY,
+ USHORT nBitCount )
+{
+ HBITMAP hBitmap;
+
+#ifdef WIN
+ if ( nBitCount == 1 )
+ hBitmap = CreateBitmap( (int)nDX, (int)nDY, 1, 1, NULL );
+ else
+ hBitmap = CreateCompatibleBitmap( hDC, (int)nDX, (int)nDY );
+#endif
+
+ return hBitmap;
+}
+
+// =======================================================================
+
+SalVirtualDevice* SalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ USHORT nBitCount )
+{
+#ifdef WIN
+ HDC hDC = CreateCompatibleDC( pGraphics->maGraphicsData.mhDC );
+ HBITMAP hBmp = ImplCreateVirDevBitmap( pGraphics->maGraphicsData.mhDC,
+ nDX, nDY, nBitCount );
+
+ if ( hDC && hBmp )
+ {
+ SalVirtualDevice* pVDev = new SalVirtualDevice;
+ SalData* pSalData = GetSalData();
+ SalGraphics* pVirGraphics = new SalGraphics;
+ pVirGraphics->maGraphicsData.mhDC = hDC;
+ pVirGraphics->maGraphicsData.mhWnd = 0;
+ pVirGraphics->maGraphicsData.mbPrinter = FALSE;
+ pVirGraphics->maGraphicsData.mbVirDev = TRUE;
+ pVirGraphics->maGraphicsData.mbWindow = FALSE;
+ pVirGraphics->maGraphicsData.mbScreen = pGraphics->maGraphicsData.mbScreen;
+ if ( pSalData->mhDitherPal && pVirGraphics->maGraphicsData.mbScreen )
+ {
+ pVirGraphics->maGraphicsData.mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( hDC );
+ }
+ ImplSalInitGraphics( &(pVirGraphics->maGraphicsData) );
+
+ pVDev->maVirDevData.mhDC = hDC;
+ pVDev->maVirDevData.mhBmp = hBmp;
+ pVDev->maVirDevData.mhDefBmp = SelectBitmap( hDC, hBmp );
+ pVDev->maVirDevData.mpGraphics = pVirGraphics;
+ pVDev->maVirDevData.mnBitCount = nBitCount;
+ pVDev->maVirDevData.mbGraphics = FALSE;
+
+ // insert VirDev in VirDevList
+ pVDev->maVirDevData.mpNext = pSalData->mpFirstVD;
+ pSalData->mpFirstVD = pVDev;
+
+ return pVDev;
+ }
+ else
+ {
+ if ( hDC )
+ DeleteDC( hDC );
+ if ( hBmp )
+ DeleteBitmap( hBmp );
+ return NULL;
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
+{
+ delete pDevice;
+}
+
+// =======================================================================
+
+SalVirtualDevice::SalVirtualDevice()
+{
+}
+
+// -----------------------------------------------------------------------
+
+SalVirtualDevice::~SalVirtualDevice()
+{
+ SalData* pSalData = GetSalData();
+
+#ifdef WIN
+ // destroy saved DC
+ if ( maVirDevData.mpGraphics->maGraphicsData.mhDefPal )
+ SelectPalette( maVirDevData.mpGraphics->maGraphicsData.mhDC, maVirDevData.mpGraphics->maGraphicsData.mhDefPal, TRUE );
+#endif
+ ImplSalDeInitGraphics( &(maVirDevData.mpGraphics->maGraphicsData) );
+ SelectBitmap( maVirDevData.mpGraphics->maGraphicsData.mhDC, maVirDevData.mhDefBmp );
+#ifdef WIN
+ DeleteDC( maVirDevData.mpGraphics->maGraphicsData.mhDC );
+#endif
+ DeleteBitmap( maVirDevData.mhBmp );
+ delete maVirDevData.mpGraphics;
+
+ // remove VirDev from VirDevList
+ if ( this == pSalData->mpFirstVD )
+ pSalData->mpFirstVD = maVirDevData.mpNext;
+ else
+ {
+ SalVirtualDevice* pTempVD = pSalData->mpFirstVD;
+ while ( pTempVD->maVirDevData.mpNext != this )
+ pTempVD = pTempVD->maVirDevData.mpNext;
+
+ pTempVD->maVirDevData.mpNext = maVirDevData.mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalVirtualDevice::GetGraphics()
+{
+ if ( maVirDevData.mbGraphics )
+ return NULL;
+
+ if ( maVirDevData.mpGraphics )
+ maVirDevData.mbGraphics = TRUE;
+
+ return maVirDevData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{
+ maVirDevData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalVirtualDevice::SetSize( long nDX, long nDY )
+{
+ HBITMAP hNewBmp = ImplCreateVirDevBitmap( maVirDevData.mhDC, nDX, nDY,
+ maVirDevData.mnBitCount );
+ if ( hNewBmp )
+ {
+ SelectBitmap( maVirDevData.mhDC, hNewBmp );
+ DeleteBitmap( maVirDevData.mhBmp );
+ maVirDevData.mhBmp = hNewBmp;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
diff --git a/vcl/aqua/source/window/makefile.mk b/vcl/aqua/source/window/makefile.mk
new file mode 100644
index 000000000000..9f4791709673
--- /dev/null
+++ b/vcl/aqua/source/window/makefile.mk
@@ -0,0 +1,104 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salwin
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(OS)"!="MACOSX"
+
+dummy:
+ @echo "Nothing to build for this platform"
+
+.ELSE # "$(OS)"!="MACOSX"
+
+.IF "$(remote)"==""
+
+SLOFILES= \
+ $(SLO)/salframe.obj $(SLO)/salobj.obj
+
+.IF "$(UPDATER)"=="YES"
+OBJFILES= \
+ $(OBJ)/salframe.obj $(OBJ)/salobj.obj
+.ENDIF
+
+.ENDIF
+
+.ENDIF # "$(OS)"!="MACOSX"
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
diff --git a/vcl/aqua/source/window/salframe.cxx b/vcl/aqua/source/window/salframe.cxx
new file mode 100644
index 000000000000..2fb84cbfa02f
--- /dev/null
+++ b/vcl/aqua/source/window/salframe.cxx
@@ -0,0 +1,3991 @@
+/*************************************************************************
+ *
+ * $RCSfile: salframe.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <limits.h>
+
+#ifdef DBG_UTIL
+#include <stdio.h>
+#endif
+
+#ifndef _SVWIN_HXX
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALFRAME_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#define private public
+#ifndef _SV_SALAQUA_HXX
+#include <salaqua.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_KEYCOES_HXX
+#include <keycodes.hxx>
+#endif
+
+// =======================================================================
+
+// Wegen Fehler in Windows-Headerfiles
+#ifndef IMN_OPENCANDIDATE
+#define IMN_OPENCANDIDATE 0x0005
+#endif
+#ifndef IMN_CLOSECANDIDATE
+#define IMN_CLOSECANDIDATE 0x0004
+#endif
+
+// =======================================================================
+
+static void ImplSaveFrameState( SalFrame* pFrame )
+{
+#ifdef WIN
+ // Position, Groesse und Status fuer GetWindowState() merken
+ if ( !pFrame->maFrameData.mbFullScreen )
+ {
+ BOOL bVisible = (GetWindowStyle( pFrame->maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( IsIconic( pFrame->maFrameData.mhWnd ) )
+ {
+ pFrame->maFrameData.maState.mnState |= SAL_FRAMESTATE_MINIMIZED;
+ if ( bVisible )
+ pFrame->maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ }
+ else if ( IsZoomed( pFrame->maFrameData.mhWnd ) )
+ {
+ pFrame->maFrameData.maState.mnState &= ~SAL_FRAMESTATE_MINIMIZED;
+ pFrame->maFrameData.maState.mnState |= SAL_FRAMESTATE_MAXIMIZED;
+ if ( bVisible )
+ pFrame->maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ pFrame->maFrameData.mbRestoreMaximize = TRUE;
+ }
+ else
+ {
+ RECT aRect;
+ GetWindowRect( pFrame->maFrameData.mhWnd, &aRect );
+ pFrame->maFrameData.maState.mnState &= ~(SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED);
+ pFrame->maFrameData.maState.mnX = aRect.left;
+ pFrame->maFrameData.maState.mnY = aRect.top;
+ pFrame->maFrameData.maState.mnWidth = aRect.right-aRect.left;
+ pFrame->maFrameData.maState.mnHeight = aRect.bottom-aRect.top;
+ if ( bVisible )
+ pFrame->maFrameData.mnShowState = SW_SHOWNORMAL;
+ pFrame->maFrameData.mbRestoreMaximize = FALSE;
+ }
+ }
+#endif
+}
+
+// =======================================================================
+
+SalFrame* ImplSalCreateFrame( SalInstance* pInst,
+ HWND hWndParent, ULONG nSalFrameStyle )
+{
+ SalFrame* pFrame = new SalFrame;
+#ifdef WIN
+ HWND hWnd;
+ DWORD nSysStyle = 0;
+ DWORD nExSysStyle = 0;
+ BOOL bSaveBits = FALSE;
+
+ // determine creation data
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_CHILD )
+ nSysStyle |= WS_CHILD;
+ else if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
+ {
+ pFrame->maFrameData.mbCaption = TRUE;
+ nSysStyle |= WS_OVERLAPPED;
+ nExSysStyle |= WS_EX_APPWINDOW;
+ }
+ else
+ nSysStyle |= WS_POPUP;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE )
+ {
+ pFrame->maFrameData.mbSizeBorder = TRUE;
+ nSysStyle |= WS_THICKFRAME | WS_SYSMENU;
+ }
+ else if ( nSalFrameStyle & SAL_FRAME_STYLE_BORDER )
+ {
+ pFrame->maFrameData.mbBorder = TRUE;
+ nSysStyle |= WS_BORDER;
+ }
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE )
+ {
+ pFrame->maFrameData.mbCaption = TRUE;
+ nSysStyle |= WS_CAPTION | WS_SYSMENU;
+ }
+ else
+ nExSysStyle |= WS_EX_TOOLWINDOW;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MINABLE )
+ nSysStyle |= WS_MINIMIZEBOX | WS_SYSMENU;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MAXABLE )
+ nSysStyle |= WS_MAXIMIZEBOX | WS_SYSMENU;
+
+ // init frame data
+ pFrame->maFrameData.mnStyle = nSalFrameStyle;
+
+ // determine show style
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
+ {
+ SalData* pSalData = GetSalData();
+ pFrame->maFrameData.mnShowState = pSalData->mnCmdShow;
+ if ( (pFrame->maFrameData.mnShowState != SW_SHOWMINIMIZED) &&
+ (pFrame->maFrameData.mnShowState != SW_MINIMIZE) &&
+ (pFrame->maFrameData.mnShowState != SW_SHOWMINNOACTIVE) )
+ {
+ if ( (pFrame->maFrameData.mnShowState == SW_SHOWMAXIMIZED) ||
+ (pFrame->maFrameData.mnShowState == SW_MAXIMIZE) )
+ pFrame->maFrameData.mbOverwriteState = FALSE;
+ pFrame->maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ }
+ else
+ pFrame->maFrameData.mbOverwriteState = FALSE;
+ }
+ else
+ pFrame->maFrameData.mnShowState = SW_SHOWNORMAL;
+
+ // create frame
+ LPCSTR pClassName;
+ if ( bSaveBits )
+ pClassName = SAL_FRAME_CLASSNAME_SBA;
+ else
+ pClassName = SAL_FRAME_CLASSNAMEA;
+ hWnd = CreateWindowExA( nExSysStyle, pClassName, "", nSysStyle,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ hWndParent, 0, pInst->maInstData.mhInst, (void*)pFrame );
+ }
+ if ( !hWnd )
+ {
+ delete pFrame;
+ return NULL;
+ }
+
+ // disable close
+ if ( !(nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE) )
+ {
+ HMENU hSysMenu = GetSystemMenu( hWnd, FALSE );
+ if ( hSysMenu )
+ EnableMenuItem( hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED );
+ }
+
+ // reset input context
+#ifdef WIN
+ pFrame->maFrameData.mhDefIMEContext = ImmAssociateContext( hWnd, 0 );
+#endif
+
+ // determine output size and state
+ RECT aRect;
+ GetClientRect( hWnd, &aRect );
+ pFrame->maFrameData.mnWidth = aRect.right;
+ pFrame->maFrameData.mnHeight = aRect.bottom;
+ ImplSaveFrameState( pFrame );
+ pFrame->maFrameData.mbDefPos = TRUE;
+
+ // CreateHDC in the main thread
+ pFrame->ReleaseGraphics( pFrame->GetGraphics() );
+#endif
+
+ return pFrame;
+}
+
+// =======================================================================
+
+// Uebersetzungstabelle von System-Keycodes in StarView-Keycodes
+#define KEY_TAB_SIZE 146
+
+static USHORT aImplTranslateKeyTab[KEY_TAB_SIZE] =
+{
+ // StarView-Code System-Code Index
+ 0, // 0
+ 0, // VK_LBUTTON 1
+ 0, // VK_RBUTTON 2
+ 0, // VK_CANCEL 3
+ 0, // VK_MBUTTON 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ KEY_BACKSPACE, // VK_BACK 8
+ KEY_TAB, // VK_TAB 9
+ 0, // 10
+ 0, // 11
+ 0, // VK_CLEAR 12
+ KEY_RETURN, // VK_RETURN 13
+ 0, // 14
+ 0, // 15
+ 0, // VK_SHIFT 16
+ 0, // VK_CONTROL 17
+ 0, // VK_MENU 18
+ 0, // VK_PAUSE 19
+ 0, // VK_CAPITAL 20
+ 0, // 21
+ 0, // 22
+ 0, // 23
+ 0, // 24
+ 0, // 25
+ 0, // 26
+ KEY_ESCAPE, // VK_ESCAPE 27
+ 0, // 28
+ 0, // 29
+ 0, // 30
+ 0, // 31
+ KEY_SPACE, // VK_SPACE 32
+ KEY_PAGEUP, // VK_PRIOR 33
+ KEY_PAGEDOWN, // VK_NEXT 34
+ KEY_END, // VK_END 35
+ KEY_HOME, // VK_HOME 36
+ KEY_LEFT, // VK_LEFT 37
+ KEY_UP, // VK_UP 38
+ KEY_RIGHT, // VK_RIGHT 39
+ KEY_DOWN, // VK_DOWN 40
+ 0, // VK_SELECT 41
+ 0, // VK_PRINT 42
+ 0, // VK_EXECUTE 43
+ 0, // VK_SNAPSHOT 44
+ KEY_INSERT, // VK_INSERT 45
+ KEY_DELETE, // VK_DELETE 46
+ KEY_HELP, // VK_HELP 47
+ KEY_0, // 48
+ KEY_1, // 49
+ KEY_2, // 50
+ KEY_3, // 51
+ KEY_4, // 52
+ KEY_5, // 53
+ KEY_6, // 54
+ KEY_7, // 55
+ KEY_8, // 56
+ KEY_9, // 57
+ 0, // 58
+ 0, // 59
+ 0, // 60
+ 0, // 61
+ 0, // 62
+ 0, // 63
+ 0, // 64
+ KEY_A, // 65
+ KEY_B, // 66
+ KEY_C, // 67
+ KEY_D, // 68
+ KEY_E, // 69
+ KEY_F, // 70
+ KEY_G, // 71
+ KEY_H, // 72
+ KEY_I, // 73
+ KEY_J, // 74
+ KEY_K, // 75
+ KEY_L, // 76
+ KEY_M, // 77
+ KEY_N, // 78
+ KEY_O, // 79
+ KEY_P, // 80
+ KEY_Q, // 81
+ KEY_R, // 82
+ KEY_S, // 83
+ KEY_T, // 84
+ KEY_U, // 85
+ KEY_V, // 86
+ KEY_W, // 87
+ KEY_X, // 88
+ KEY_Y, // 89
+ KEY_Z, // 90
+ 0, // VK_LWIN 91
+ 0, // VK_RWIN 92
+ KEY_CONTEXTMENU, // VK_APPS 93
+ 0, // 94
+ 0, // 95
+ KEY_0, // VK_NUMPAD0 96
+ KEY_1, // VK_NUMPAD1 97
+ KEY_2, // VK_NUMPAD2 98
+ KEY_3, // VK_NUMPAD3 99
+ KEY_4, // VK_NUMPAD4 100
+ KEY_5, // VK_NUMPAD5 101
+ KEY_6, // VK_NUMPAD6 102
+ KEY_7, // VK_NUMPAD7 103
+ KEY_8, // VK_NUMPAD8 104
+ KEY_9, // VK_NUMPAD9 105
+ KEY_MULTIPLY, // VK_MULTIPLY 106
+ KEY_ADD, // VK_ADD 107
+ KEY_COMMA, // VK_SEPARATOR 108
+ KEY_SUBTRACT, // VK_SUBTRACT 109
+ KEY_POINT, // VK_DECIMAL 110
+ KEY_DIVIDE, // VK_DIVIDE 111
+ KEY_F1, // VK_F1 112
+ KEY_F2, // VK_F2 113
+ KEY_F3, // VK_F3 114
+ KEY_F4, // VK_F4 115
+ KEY_F5, // VK_F5 116
+ KEY_F6, // VK_F6 117
+ KEY_F7, // VK_F7 118
+ KEY_F8, // VK_F8 119
+ KEY_F9, // VK_F9 120
+ KEY_F10, // VK_F10 121
+ KEY_F11, // VK_F11 122
+ KEY_F12, // VK_F12 123
+ KEY_F13, // VK_F13 124
+ KEY_F14, // VK_F14 125
+ KEY_F15, // VK_F15 126
+ KEY_F16, // VK_F16 127
+ KEY_F17, // VK_F17 128
+ KEY_F18, // VK_F18 129
+ KEY_F19, // VK_F19 130
+ KEY_F20, // VK_F20 131
+ KEY_F21, // VK_F21 132
+ KEY_F22, // VK_F22 133
+ KEY_F23, // VK_F23 134
+ KEY_F24, // VK_F24 135
+ 0, // 136
+ 0, // 137
+ 0, // 138
+ 0, // 139
+ 0, // 140
+ 0, // 141
+ 0, // 142
+ 0, // 143
+ 0, // NUMLOCK 144
+ 0 // SCROLLLOCK 145
+};
+
+// =======================================================================
+
+long ImplSalCallbackDummy( void*, SalFrame*, USHORT, const void* )
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static UINT ImplSalGetWheelScrollLines()
+{
+ UINT nScrLines = 0;
+#ifdef WIN
+ HWND hWndMsWheel = WIN_FindWindow( MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE );
+ if ( hWndMsWheel )
+ {
+ UINT nGetScrollLinesMsgId = RegisterWindowMessage( MSH_SCROLL_LINES );
+ nScrLines = (UINT)ImplSendMessage( hWndMsWheel, nGetScrollLinesMsgId, 0, 0 );
+ }
+
+ if ( !nScrLines )
+ nScrLines = SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &nScrLines, 0 );
+
+ if ( !nScrLines )
+ nScrLines = 3;
+#endif
+
+ return nScrLines;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalCalcFullScreenSize( const SalFrame* pFrame,
+ int& rX, int& rY, int& rDX, int& rDY )
+{
+#ifdef WIN
+ // set window to screen size
+ int nFrameX;
+ int nFrameY;
+ int nCaptionY;
+ int nScreenDX;
+ int nScreenDY;
+
+ if ( pFrame->maFrameData.mbSizeBorder )
+ {
+ nFrameX = GetSystemMetrics( SM_CXFRAME );
+ nFrameY = GetSystemMetrics( SM_CYFRAME );
+ }
+ else if ( pFrame->maFrameData.mbBorder )
+ {
+ nFrameX = GetSystemMetrics( SM_CXBORDER );
+ nFrameY = GetSystemMetrics( SM_CYBORDER );
+ }
+ else
+ {
+ nFrameX = 0;
+ nFrameY = 0;
+ }
+ if ( pFrame->maFrameData.mbCaption )
+ nCaptionY = GetSystemMetrics( SM_CYCAPTION );
+ else
+ nCaptionY = 0;
+
+ nScreenDX = GetSystemMetrics( SM_CXSCREEN );
+ nScreenDY = GetSystemMetrics( SM_CYSCREEN );
+
+ rX = -nFrameX;
+ rY = -(nFrameY+nCaptionY);
+ rDX = nScreenDX+(nFrameX*2);
+ rDY = nScreenDY+(nFrameY*2)+nCaptionY;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalFrameFullScreenPos( SalFrame* pFrame, BOOL bAlways = FALSE )
+{
+#ifdef WIN
+ if ( bAlways || !IsIconic( pFrame->maFrameData.mhWnd ) )
+ {
+ // set window to screen size
+ int nX;
+ int nY;
+ int nWidth;
+ int nHeight;
+ ImplSalCalcFullScreenSize( pFrame, nX, nY, nWidth, nHeight );
+ SetWindowPos( pFrame->maFrameData.mhWnd, 0,
+ nX, nY, nWidth, nHeight,
+ SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame::SalFrame()
+{
+ SalData* pSalData = GetSalData();
+
+ maFrameData.mhWnd = 0;
+#ifdef WIN
+ maFrameData.mhCursor = LoadCursor( 0, IDC_ARROW );
+#endif
+ maFrameData.mhDefIMEContext = 0;
+ maFrameData.mpGraphics = NULL;
+ maFrameData.mpInst = NULL;
+ maFrameData.mpProc = ImplSalCallbackDummy;
+ maFrameData.mnInputLang = 0;
+ maFrameData.mnInputCodePage = 0;
+ maFrameData.mbGraphics = FALSE;
+ maFrameData.mbCaption = FALSE;
+ maFrameData.mbBorder = FALSE;
+ maFrameData.mbSizeBorder = FALSE;
+ maFrameData.mbFullScreen = FALSE;
+ maFrameData.mbPresentation = FALSE;
+ maFrameData.mbInShow = FALSE;
+ maFrameData.mbRestoreMaximize = FALSE;
+ maFrameData.mbInMoveMsg = FALSE;
+ maFrameData.mbInSizeMsg = FALSE;
+ maFrameData.mbFullScreenToolWin = FALSE;
+ maFrameData.mbDefPos = TRUE;
+ maFrameData.mbOverwriteState = TRUE;
+ maFrameData.mbIME = FALSE;
+ maFrameData.mbHandleIME = FALSE;
+ maFrameData.mbSpezIME = FALSE;
+ maFrameData.mbAtCursorIME = FALSE;
+ maFrameData.mbCompositionMode = FALSE;
+ maFrameData.mbCandidateMode = FALSE;
+ memset( &maFrameData.maState, 0, sizeof( SalFrameState ) );
+ maFrameData.maSysData.nSize = sizeof( SystemEnvData );
+
+ // Daten ermitteln, wenn erster Frame angelegt wird
+ if ( !pSalData->mpFirstFrame )
+ {
+#ifdef WIN
+ if ( !aSalShlData.mnWheelMsgId )
+ aSalShlData.mnWheelMsgId = RegisterWindowMessage( MSH_MOUSEWHEEL );
+#endif
+ if ( !aSalShlData.mnWheelScrollLines )
+ aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines();
+ }
+
+ // insert frame in framelist
+ maFrameData.mpNextFrame = pSalData->mpFirstFrame;
+ pSalData->mpFirstFrame = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame::~SalFrame()
+{
+ SalData* pSalData = GetSalData();
+
+ // destroy saved DC
+ if ( maFrameData.mpGraphics )
+ {
+#ifdef WIN
+ if ( maFrameData.mpGraphics->maGraphicsData.mhDefPal )
+ SelectPalette( maFrameData.mpGraphics->maGraphicsData.mhDC, maFrameData.mpGraphics->maGraphicsData.mhDefPal, TRUE );
+#endif
+ ImplSalDeInitGraphics( &(maFrameData.mpGraphics->maGraphicsData) );
+#ifdef WIN
+ ReleaseDC( maFrameData.mhWnd, maFrameData.mpGraphics->maGraphicsData.mhDC );
+#endif
+ delete maFrameData.mpGraphics;
+ }
+
+ if ( maFrameData.mhWnd )
+ {
+ // reset mouse leave data
+ if ( pSalData->mhWantLeaveMsg == maFrameData.mhWnd )
+ {
+ pSalData->mhWantLeaveMsg = 0;
+ if ( pSalData->mpMouseLeaveTimer )
+ {
+ delete pSalData->mpMouseLeaveTimer;
+ pSalData->mpMouseLeaveTimer = NULL;
+ }
+ }
+
+#ifdef WIN
+ // destroy system frame
+ if ( !DestroyWindow( maFrameData.mhWnd ) )
+ SetWindowPtr( maFrameData.mhWnd, 0 );
+#endif
+ }
+
+ // remove frame from framelist
+ if ( this == pSalData->mpFirstFrame )
+ pSalData->mpFirstFrame = maFrameData.mpNextFrame;
+ else
+ {
+ SalFrame* pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame->maFrameData.mpNextFrame != this )
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+
+ pTempFrame->maFrameData.mpNextFrame = maFrameData.mpNextFrame;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalFrame::GetGraphics()
+{
+ if ( maFrameData.mbGraphics )
+ return NULL;
+
+ if ( !maFrameData.mpGraphics )
+ {
+#ifdef WIN
+ HDC hDC = GetDC( maFrameData.mhWnd );
+ if ( hDC )
+ {
+ SalData* pSalData = GetSalData();
+ maFrameData.mpGraphics = new SalGraphics;
+ maFrameData.mpGraphics->maGraphicsData.mhDC = hDC;
+ maFrameData.mpGraphics->maGraphicsData.mhWnd = maFrameData.mhWnd;
+ maFrameData.mpGraphics->maGraphicsData.mbPrinter = FALSE;
+ maFrameData.mpGraphics->maGraphicsData.mbVirDev = FALSE;
+ maFrameData.mpGraphics->maGraphicsData.mbWindow = TRUE;
+ maFrameData.mpGraphics->maGraphicsData.mbScreen = TRUE;
+ if ( pSalData->mhDitherPal )
+ {
+ maFrameData.mpGraphics->maGraphicsData.mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( hDC );
+ }
+ ImplSalInitGraphics( &(maFrameData.mpGraphics->maGraphicsData) );
+ maFrameData.mbGraphics = TRUE;
+ }
+#endif
+ }
+ else
+ maFrameData.mbGraphics = TRUE;
+
+ return maFrameData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ReleaseGraphics( SalGraphics* )
+{
+ maFrameData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalFrame::PostEvent( void* pData )
+{
+#ifdef WIN
+ return (BOOL)ImplPostMessage( maFrameData.mhWnd, SAL_MSG_USEREVENT, 0, (LPARAM)pData );
+#else
+ return FALSE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetTitle( const XubString& rTitle )
+{
+ DBG_ASSERT( sizeof( wchar_t ) == sizeof( xub_Unicode ), "SalFrame::SetTitle(): wchar_t != sal_Unicode" );
+
+#ifdef WIN
+ if ( !SetWindowTextW( maFrameData.mhWnd, rTitle.GetBuffer() ) )
+ {
+ ByteString aAnsiTitle = ImplSalGetWinAnsiString( rTitle );
+ SetWindowTextA( maFrameData.mhWnd, aAnsiTitle.GetBuffer() );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetIcon( USHORT nIcon )
+{
+// ImplSendMessage( maFrameData.mhWnd, WM_SETICON, FALSE, hSmIcon );
+// ImplSendMessage( maFrameData.mhWnd, WM_SETICON, TRUE, hIcon );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalShow( HWND hWnd, BOOL bVisible )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return;
+
+ if ( bVisible )
+ {
+ pFrame->maFrameData.mbDefPos = FALSE;
+ pFrame->maFrameData.mbOverwriteState = TRUE;
+ pFrame->maFrameData.mbInShow = TRUE;
+#ifdef WIN
+ ShowWindow( hWnd, pFrame->maFrameData.mnShowState );
+#endif
+ // Damit Taskleiste unter W98 auch gleich ausgeblendet wird
+ if ( pFrame->maFrameData.mbPresentation )
+ {
+#ifdef WIN
+ HWND hWndParent = ::GetParent( hWnd );
+ if ( hWndParent )
+ SetForegroundWindow( hWndParent );
+ SetForegroundWindow( hWnd );
+#endif
+ }
+#ifdef WIN
+ pFrame->maFrameData.mnShowState = SW_SHOW;
+ pFrame->maFrameData.mbInShow = FALSE;
+ UpdateWindow( hWnd );
+#endif
+ }
+ else
+ {
+#ifdef WIN
+ if ( pFrame->maFrameData.mbFullScreen &&
+ pFrame->maFrameData.mbPresentation &&
+ !::GetParent( hWnd ) )
+ {
+ // Damit im Impress-Player in der Taskleiste nicht durch
+ // einen Windows-Fehler hin- und wieder mal ein leerer
+ // Button stehen bleibt, muessen wir hier die Taskleiste
+ // etwas austricksen. Denn wenn wir im FullScreenMode sind
+ // und das Fenster hiden kommt Windows anscheinend etwas aus
+ // dem tritt und somit minimieren wir das Fenster damit es
+ // nicht flackert
+ ANIMATIONINFO aInfo;
+ aInfo.cbSize = sizeof( aInfo );
+ SystemParametersInfo( SPI_GETANIMATION, 0, &aInfo, 0 );
+ if ( aInfo.iMinAnimate )
+ {
+ int nOldAni = aInfo.iMinAnimate;
+ aInfo.iMinAnimate = 0;
+ SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 );
+ ShowWindow( pFrame->maFrameData.mhWnd, SW_SHOWMINNOACTIVE );
+ aInfo.iMinAnimate = nOldAni;
+ SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 );
+ }
+ else
+ ShowWindow( hWnd, SW_SHOWMINNOACTIVE );
+ ShowWindow( hWnd, SW_HIDE );
+ }
+ else
+ ShowWindow( hWnd, SW_HIDE );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Show( BOOL bVisible )
+{
+#ifdef WIN
+ // Send this Message to the window, because this only works
+ // in the thread of the window, which has create this window
+ ImplSendMessage( maFrameData.mhWnd, SAL_MSG_SHOW, bVisible, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Enable( BOOL bEnable )
+{
+#ifdef WIN
+ EnableWindow( maFrameData.mhWnd, bEnable );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetMinClientSize( long nWidth, long nHeight )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetClientSize( long nWidth, long nHeight )
+{
+#ifdef WIN
+ BOOL bVisible = (GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( !bVisible )
+ maFrameData.mnShowState = SW_SHOWNORMAL;
+ else
+ {
+ if ( IsIconic( maFrameData.mhWnd ) || IsZoomed( maFrameData.mhWnd ) )
+ ShowWindow( maFrameData.mhWnd, SW_RESTORE );
+ }
+
+ // Fenstergroesse berechnen
+ RECT aWinRect;
+ aWinRect.left = 0;
+ aWinRect.right = (int)nWidth-1;
+ aWinRect.top = 0;
+ aWinRect.bottom = (int)nHeight-1;
+ AdjustWindowRectEx( &aWinRect,
+ GetWindowStyle( maFrameData.mhWnd ),
+ FALSE,
+ GetWindowExStyle( maFrameData.mhWnd ) );
+ nWidth = aWinRect.right - aWinRect.left + 1;
+ nHeight = aWinRect.bottom - aWinRect.top + 1;
+
+ // Position so berechnen, das Fenster zentiert auf dem Desktop
+ // angezeigt wird
+ int nX;
+ int nY;
+ int nScreenX;
+ int nScreenY;
+ int nScreenWidth;
+ int nScreenHeight;
+
+ RECT aRect;
+ SystemParametersInfo( SPI_GETWORKAREA, 0, &aRect, 0 );
+ nScreenX = aRect.left;
+ nScreenY = aRect.top;
+ nScreenWidth = aRect.right-aRect.left;
+ nScreenHeight = aRect.bottom-aRect.top;
+
+ if ( maFrameData.mbDefPos )
+ {
+ nX = (nScreenWidth-nWidth)/2 + nScreenX;
+ nY = (nScreenHeight-nHeight)/2 + nScreenY;
+ if ( bVisible )
+ maFrameData.mbDefPos = FALSE;
+ }
+ else
+ {
+ RECT aWinRect;
+ GetWindowRect( maFrameData.mhWnd, &aWinRect );
+ nX = aWinRect.left;
+ nY = aWinRect.top;
+ if ( nX+nWidth > nScreenX+nScreenWidth )
+ nX = (nScreenX+nScreenWidth) - nWidth;
+ if ( nY+nHeight > nScreenY+nScreenHeight )
+ nY = (nScreenY+nScreenHeight) - nHeight;
+ if ( nX < nScreenX )
+ nX = nScreenX;
+ if ( nY < nScreenY )
+ nY = nScreenY;
+ }
+
+ SetWindowPos( maFrameData.mhWnd, 0, nX, nY, (int)nWidth, (int)nHeight, SWP_NOZORDER | SWP_NOACTIVATE );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::GetClientSize( long& rWidth, long& rHeight )
+{
+ rWidth = maFrameData.mnWidth;
+ rHeight = maFrameData.mnHeight;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetWindowState( const SalFrameState* pState )
+{
+#ifdef WIN
+ // Wir testen, ob das Fenster ueberhaupt auf den Bildschirm passt, damit
+ // nicht wenn die Bildschirm-Aufloesung geaendert wurde, das Fenster aus
+ // diesem herausragt
+ int nX;
+ int nY;
+ int nWidth;
+ int nHeight;
+ int nScreenX;
+ int nScreenY;
+ int nScreenWidth;
+ int nScreenHeight;
+
+ RECT aRect;
+ SystemParametersInfo( SPI_GETWORKAREA, 0, &aRect, 0 );
+ nScreenX = aRect.left;
+ nScreenY = aRect.top;
+ nScreenWidth = aRect.right-aRect.left;
+ nScreenHeight = aRect.bottom-aRect.top;
+
+ // Fenster-Position/Groesse in den Bildschirm einpassen
+ nX = (int)pState->mnX;
+ nY = (int)pState->mnY;
+ nWidth = (int)pState->mnWidth;
+ nHeight = (int)pState->mnHeight;
+ if ( nX < nScreenX )
+ nX = nScreenX;
+ if ( nY < nScreenY )
+ nY = nScreenY;
+ if ( nScreenWidth < nWidth )
+ nWidth = nScreenWidth;
+ if ( nScreenHeight < nHeight )
+ nHeight = nScreenHeight;
+
+ // Restore-Position setzen
+ WINDOWPLACEMENT aPlacement;
+ aPlacement.length = sizeof( aPlacement );
+ GetWindowPlacement( maFrameData.mhWnd, &aPlacement );
+
+ // Status setzen
+ BOOL bVisible = (GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( !bVisible )
+ {
+ aPlacement.showCmd = SW_HIDE;
+
+ if ( maFrameData.mbOverwriteState )
+ {
+ if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
+ maFrameData.mnShowState = SW_SHOWMINIMIZED;
+ else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ else
+ maFrameData.mnShowState = SW_SHOWNORMAL;
+ }
+ }
+ else
+ {
+ if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
+ {
+ if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ aPlacement.flags |= WPF_RESTORETOMAXIMIZED;
+ aPlacement.showCmd = SW_SHOWMINIMIZED;
+ }
+ else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ aPlacement.showCmd = SW_SHOWMAXIMIZED;
+ else
+ aPlacement.showCmd = SW_RESTORE;
+ }
+
+ // Wenn Fenster nicht minimiert/maximiert ist oder nicht optisch
+ // umgesetzt werden muss, dann SetWindowPos() benutzen, da
+ // SetWindowPlacement() die TaskBar mit einrechnet
+ if ( !IsIconic( maFrameData.mhWnd ) && !IsZoomed( maFrameData.mhWnd ) &&
+ (!bVisible || (aPlacement.showCmd == SW_RESTORE)) )
+ {
+ SetWindowPos( maFrameData.mhWnd, 0,
+ nX, nY, nWidth, nHeight,
+ SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+ else
+ {
+ aPlacement.rcNormalPosition.left = nX-nScreenX;
+ aPlacement.rcNormalPosition.top = nY-nScreenY;
+ aPlacement.rcNormalPosition.right = nX+nWidth-nScreenX;
+ aPlacement.rcNormalPosition.bottom = nY+nHeight-nScreenY;
+ SetWindowPlacement( maFrameData.mhWnd, &aPlacement );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalFrame::GetWindowState( SalFrameState* pState )
+{
+ if ( maFrameData.maState.mnWidth && maFrameData.maState.mnHeight )
+ {
+ *pState = maFrameData.maState;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ShowFullScreen( BOOL bFullScreen )
+{
+ if ( maFrameData.mbFullScreen == bFullScreen )
+ return;
+
+ maFrameData.mbFullScreen = bFullScreen;
+#ifdef WIN
+ if ( bFullScreen )
+ {
+ // Damit Taskleiste von Windows ausgeblendet wird
+ DWORD nExStyle = GetWindowExStyle( maFrameData.mhWnd );
+ if ( nExStyle & WS_EX_TOOLWINDOW )
+ {
+ maFrameData.mbFullScreenToolWin = TRUE;
+ nExStyle &= ~WS_EX_TOOLWINDOW;
+ SetWindowExStyle( maFrameData.mhWnd, nExStyle );
+ }
+
+ // save old position
+ GetWindowRect( maFrameData.mhWnd, &maFrameData.maFullScreenRect );
+
+ // save show state
+ maFrameData.mnFullScreenShowState = maFrameData.mnShowState;
+ if ( !(GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) )
+ maFrameData.mnShowState = SW_SHOW;
+
+ // set window to screen size
+ ImplSalFrameFullScreenPos( this, TRUE );
+ }
+ else
+ {
+ // wenn ShowState wieder hergestellt werden muss, hiden wir zuerst
+ // das Fenster, damit es nicht so sehr flackert
+ BOOL bVisible = (GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( bVisible && (maFrameData.mnShowState != maFrameData.mnFullScreenShowState) )
+ ShowWindow( maFrameData.mhWnd, SW_HIDE );
+
+ if ( maFrameData.mbFullScreenToolWin )
+ SetWindowExStyle( maFrameData.mhWnd, GetWindowExStyle( maFrameData.mhWnd ) | WS_EX_TOOLWINDOW );
+ maFrameData.mbFullScreenToolWin = FALSE;
+
+ SetWindowPos( maFrameData.mhWnd, 0,
+ maFrameData.maFullScreenRect.left,
+ maFrameData.maFullScreenRect.top,
+ maFrameData.maFullScreenRect.right-maFrameData.maFullScreenRect.left,
+ maFrameData.maFullScreenRect.bottom-maFrameData.maFullScreenRect.top,
+ SWP_NOZORDER | SWP_NOACTIVATE );
+
+ // restore show state
+ if ( maFrameData.mnShowState != maFrameData.mnFullScreenShowState )
+ {
+ maFrameData.mnShowState = maFrameData.mnFullScreenShowState;
+ if ( bVisible )
+ {
+ maFrameData.mbInShow = TRUE;
+ ShowWindow( maFrameData.mhWnd, maFrameData.mnShowState );
+ maFrameData.mbInShow = FALSE;
+ UpdateWindow( maFrameData.mhWnd );
+ }
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::StartPresentation( BOOL bStart )
+{
+#ifdef WIN
+ if ( maFrameData.mbPresentation == bStart )
+ return;
+
+ maFrameData.mbPresentation = bStart;
+
+ SalData* pSalData = GetSalData();
+ if ( bStart )
+ {
+ if ( !pSalData->mpSageEnableProc )
+ {
+ if ( pSalData->mnSageStatus != DISABLE_AGENT )
+ {
+ OFSTRUCT aOS;
+ OpenFile( "SAGE.DLL", &aOS, OF_EXIST );
+
+ if ( !aOS.nErrCode )
+ {
+ pSalData->mhSageInst = LoadLibrary( aOS.szPathName );
+ pSalData->mpSageEnableProc = (SysAgt_Enable_PROC)GetProcAddress( pSalData->mhSageInst, "System_Agent_Enable" );
+ }
+ else
+ pSalData->mnSageStatus = DISABLE_AGENT;
+ }
+ }
+
+ if ( pSalData->mpSageEnableProc )
+ {
+ pSalData->mnSageStatus = pSalData->mpSageEnableProc( GET_AGENT_STATUS );
+ if ( pSalData->mnSageStatus == ENABLE_AGENT )
+ pSalData->mpSageEnableProc( DISABLE_AGENT );
+ }
+
+ // Bildschirmschoner ausschalten, wenn Praesentation laueft
+ SystemParametersInfo( SPI_GETSCREENSAVEACTIVE, 0,
+ &(pSalData->mbScrSvrEnabled), 0 );
+ if ( pSalData->mbScrSvrEnabled )
+ SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, FALSE, 0, 0 );
+ }
+ else
+ {
+ // Bildschirmschoner wieder einschalten
+ if ( pSalData->mbScrSvrEnabled )
+ SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, pSalData->mbScrSvrEnabled, 0, 0 );
+
+ // Systemagenten wieder aktivieren
+ if ( pSalData->mnSageStatus == ENABLE_AGENT )
+ pSalData->mpSageEnableProc( pSalData->mnSageStatus );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetAlwaysOnTop( BOOL bOnTop )
+{
+#ifdef WIN
+ HWND hWnd;
+ if ( bOnTop )
+ hWnd = HWND_TOPMOST;
+ else
+ hWnd = HWND_NOTOPMOST;
+ SetWindowPos( maFrameData.mhWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalToTop( HWND hWnd, USHORT nFlags )
+{
+#ifdef WIN
+ if ( nFlags & SAL_FRAME_TOTOP_FOREGROUNDTASK )
+ SetForegroundWindow( hWnd );
+ if ( !IsIconic( hWnd ) )
+ {
+ SetFocus( hWnd );
+
+ // Windows behauptet oefters mal, das man den Focus hat, obwohl
+ // man diesen nicht hat. Wenn dies der Fall ist, dann versuchen
+ // wir diesen auch ganz richtig zu bekommen.
+ if ( ::GetFocus() == hWnd )
+ SetForegroundWindow( hWnd );
+ }
+ else
+ {
+ if ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN )
+ {
+ if ( GetWindowPtr( hWnd )->maFrameData.mbRestoreMaximize )
+ ShowWindow( hWnd, SW_MAXIMIZE );
+ else
+ ShowWindow( hWnd, SW_RESTORE );
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ToTop( USHORT nFlags )
+{
+#ifdef WIN
+ // Send this Message to the window, because SetFocus() only work
+ // in the thread of the window, which has create this window
+ ImplSendMessage( maFrameData.mhWnd, SAL_MSG_TOTOP, nFlags, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetPointer( PointerStyle ePointerStyle )
+{
+#ifdef WIN
+ struct ImplPtrData
+ {
+ HCURSOR mhCursor;
+ LPCSTR mnSysId;
+ UINT mnOwnId;
+ };
+
+ static ImplPtrData aImplPtrTab[POINTER_COUNT] =
+ {
+ { 0, IDC_ARROW, 0 }, // POINTER_ARROW
+ { 0, 0, SAL_RESID_POINTER_NULL }, // POINTER_NULL
+ { 0, IDC_WAIT, 0 }, // POINTER_WAIT
+ { 0, IDC_IBEAM, 0 }, // POINTER_TEXT
+ { 0, 0, SAL_RESID_POINTER_HELP }, // POINTER_HELP
+ { 0, 0, SAL_RESID_POINTER_CROSS }, // POINTER_CROSS
+ { 0, 0, SAL_RESID_POINTER_MOVE }, // POINTER_MOVE
+ { 0, IDC_SIZENS, 0 }, // POINTER_NSIZE
+ { 0, IDC_SIZENS, 0 }, // POINTER_SSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_WSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_ESIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_NWSIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_NESIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_SWSIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_SESIZE
+ { 0, IDC_SIZENS, 0 }, // POINTER_WINDOW_NSIZE
+ { 0, IDC_SIZENS, 0 }, // POINTER_WINDOW_SSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_WINDOW_WSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_WINDOW_ESIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_WINDOW_NWSIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_WINDOW_NESIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_WINDOW_SWSIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_WINDOW_SESIZE
+ { 0, 0, SAL_RESID_POINTER_HSPLIT }, // POINTER_HSPLIT
+ { 0, 0, SAL_RESID_POINTER_VSPLIT }, // POINTER_VSPLIT
+ { 0, 0, SAL_RESID_POINTER_HSIZEBAR }, // POINTER_HSIZEBAR
+ { 0, 0, SAL_RESID_POINTER_VSIZEBAR }, // POINTER_VSIZEBAR
+ { 0, 0, SAL_RESID_POINTER_HAND }, // POINTER_HAND
+ { 0, 0, SAL_RESID_POINTER_REFHAND }, // POINTER_REFHAND
+ { 0, 0, SAL_RESID_POINTER_PEN }, // POINTER_PEN
+ { 0, 0, SAL_RESID_POINTER_MAGNIFY }, // POINTER_MAGNIFY
+ { 0, 0, SAL_RESID_POINTER_FILL }, // POINTER_FILL
+ { 0, 0, SAL_RESID_POINTER_ROTATE }, // POINTER_ROTATE
+ { 0, 0, SAL_RESID_POINTER_HSHEAR }, // POINTER_HSHEAR
+ { 0, 0, SAL_RESID_POINTER_VSHEAR }, // POINTER_VSHEAR
+ { 0, 0, SAL_RESID_POINTER_MIRROR }, // POINTER_MIRROR
+ { 0, 0, SAL_RESID_POINTER_CROOK }, // POINTER_CROOK
+ { 0, 0, SAL_RESID_POINTER_CROP }, // POINTER_CROP
+ { 0, 0, SAL_RESID_POINTER_MOVEPOINT }, // POINTER_MOVEPOINT
+ { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT }, // POINTER_MOVEBEZIERWEIGHT
+ { 0, 0, SAL_RESID_POINTER_MOVEDATA }, // POINTER_MOVEDATA
+ { 0, 0, SAL_RESID_POINTER_COPYDATA }, // POINTER_COPYDATA
+ { 0, 0, SAL_RESID_POINTER_LINKDATA }, // POINTER_LINKDATA
+ { 0, 0, SAL_RESID_POINTER_MOVEDATALINK }, // POINTER_MOVEDATALINK
+ { 0, 0, SAL_RESID_POINTER_COPYDATALINK }, // POINTER_COPYDATALINK
+ { 0, 0, SAL_RESID_POINTER_MOVEFILE }, // POINTER_MOVEFILE
+ { 0, 0, SAL_RESID_POINTER_COPYFILE }, // POINTER_COPYFILE
+ { 0, 0, SAL_RESID_POINTER_LINKFILE }, // POINTER_LINKFILE
+ { 0, 0, SAL_RESID_POINTER_MOVEFILELINK }, // POINTER_MOVEFILELINK
+ { 0, 0, SAL_RESID_POINTER_COPYFILELINK }, // POINTER_COPYFILELINK
+ { 0, 0, SAL_RESID_POINTER_MOVEFILES }, // POINTER_MOVEFILES
+ { 0, 0, SAL_RESID_POINTER_COPYFILES }, // POINTER_COPYFILES
+ { 0, 0, SAL_RESID_POINTER_NOTALLOWED }, // POINTER_NOTALLOWED
+ { 0, 0, SAL_RESID_POINTER_DRAW_LINE }, // POINTER_DRAW_LINE
+ { 0, 0, SAL_RESID_POINTER_DRAW_RECT }, // POINTER_DRAW_RECT
+ { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON }, // POINTER_DRAW_POLYGON
+ { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER }, // POINTER_DRAW_BEZIER
+ { 0, 0, SAL_RESID_POINTER_DRAW_ARC }, // POINTER_DRAW_ARC
+ { 0, 0, SAL_RESID_POINTER_DRAW_PIE }, // POINTER_DRAW_PIE
+ { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT }, // POINTER_DRAW_CIRCLECUT
+ { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE }, // POINTER_DRAW_ELLIPSE
+ { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND }, // POINTER_DRAW_FREEHAND
+ { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT }, // POINTER_DRAW_CONNECT
+ { 0, 0, SAL_RESID_POINTER_DRAW_TEXT }, // POINTER_DRAW_TEXT
+ { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION }, // POINTER_DRAW_CAPTION
+ { 0, 0, SAL_RESID_POINTER_CHART }, // POINTER_CHART
+ { 0, 0, SAL_RESID_POINTER_DETECTIVE }, // POINTER_DETECTIVE
+ { 0, 0, SAL_RESID_POINTER_PIVOT_COL }, // POINTER_PIVOT_COL
+ { 0, 0, SAL_RESID_POINTER_PIVOT_ROW }, // POINTER_PIVOT_ROW
+ { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD }, // POINTER_PIVOT_FIELD
+ { 0, 0, SAL_RESID_POINTER_CHAIN }, // POINTER_CHAIN
+ { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED }, // POINTER_CHAIN_NOTALLOWED
+ { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE }, // POINTER_TIMEEVENT_MOVE
+ { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE }, // POINTER_TIMEEVENT_SIZE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N }, // POINTER_AUTOSCROLL_N
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S }, // POINTER_AUTOSCROLL_S
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W }, // POINTER_AUTOSCROLL_W
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E }, // POINTER_AUTOSCROLL_E
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW }, // POINTER_AUTOSCROLL_NW
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE }, // POINTER_AUTOSCROLL_NE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW }, // POINTER_AUTOSCROLL_SW
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE }, // POINTER_AUTOSCROLL_SE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS }, // POINTER_AUTOSCROLL_NS
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE }, // POINTER_AUTOSCROLL_WE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE }, // POINTER_AUTOSCROLL_NSWE
+ { 0, 0, SAL_RESID_POINTER_AIRBRUSH } // POINTER_AIRBRUSH
+ };
+
+#if POINTER_COUNT != 86
+#error New Pointer must be defined!
+#endif
+
+ // Mousepointer loaded ?
+ if ( !aImplPtrTab[ePointerStyle].mhCursor )
+ {
+ if ( aImplPtrTab[ePointerStyle].mnOwnId )
+ aImplPtrTab[ePointerStyle].mhCursor = ImplLoadSalCursor( aImplPtrTab[ePointerStyle].mnOwnId );
+ else
+ aImplPtrTab[ePointerStyle].mhCursor = LoadCursor( 0, aImplPtrTab[ePointerStyle].mnSysId );
+ }
+
+ // Unterscheidet sich der Mauspointer, dann den neuen setzen
+ if ( maFrameData.mhCursor != aImplPtrTab[ePointerStyle].mhCursor )
+ {
+ maFrameData.mhCursor = aImplPtrTab[ePointerStyle].mhCursor;
+ SetCursor( maFrameData.mhCursor );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::CaptureMouse( BOOL bCapture )
+{
+#ifdef WIN
+ // Send this Message to the window, because CaptureMouse() only work
+ // in the thread of the window, which has create this window
+ int nMsg;
+ if ( bCapture )
+ nMsg = SAL_MSG_CAPTUREMOUSE;
+ else
+ nMsg = SAL_MSG_RELEASEMOUSE;
+ ImplSendMessage( maFrameData.mhWnd, nMsg, 0, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetPointerPos( long nX, long nY )
+{
+ POINT aPt;
+ aPt.x = (int)nX;
+ aPt.y = (int)nY;
+#ifdef WIN
+ ClientToScreen( maFrameData.mhWnd, &aPt );
+ SetCursorPos( aPt.x, aPt.y );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Flush()
+{
+#ifdef WIN
+ GdiFlush();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Sync()
+{
+#ifdef WIN
+ GdiFlush();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetInputContext( SalInputContext* pContext )
+{
+ BOOL bIME = pContext->mnOptions != 0;
+ if ( bIME == maFrameData.mbIME )
+ return;
+
+ maFrameData.mbIME = bIME;
+ if ( !bIME )
+ {
+#ifdef WIN
+ ImmAssociateContext( maFrameData.mhWnd, 0 );
+#endif
+ maFrameData.mbHandleIME = FALSE;
+ }
+ else
+ {
+ if ( maFrameData.mhDefIMEContext )
+ {
+#ifdef WIN
+ ImmAssociateContext( maFrameData.mhWnd, maFrameData.mhDefIMEContext );
+ UINT nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY );
+ maFrameData.mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
+ maFrameData.mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
+ maFrameData.mbHandleIME = !maFrameData.mbSpezIME;
+#endif
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::UpdateExtTextInputArea()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::EndExtTextInput( USHORT nFlags )
+{
+#ifdef WIN
+ HWND hWnd = maFrameData.mhWnd;
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ DWORD nIndex;
+ if ( nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE )
+ nIndex = CPS_COMPLETE;
+ else
+ nIndex = CPS_CANCEL;
+
+ ImmNotifyIME( hIMC, NI_COMPOSITIONSTR, nIndex, 0 );
+ ImmReleaseContext( hWnd, hIMC );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetKeyNameText( LONG lParam, sal_Unicode* pBuf,
+ UINT& rCount, UINT nMaxSize,
+ const sal_Char* pReplace )
+{
+#ifdef WIN
+ DBG_ASSERT( sizeof( wchar_t ) == sizeof( xub_Unicode ), "SalFrame::ImplGetKeyNameTextW(): wchar_t != sal_Unicode" );
+
+ wchar_t aKeyBuf[350];
+ int nKeyLen = 0;
+ if ( lParam )
+ {
+ nKeyLen = GetKeyNameTextW( lParam, aKeyBuf, sizeof( aKeyBuf ) / sizeof( sal_Unicode ) );
+ if ( nKeyLen > 0 )
+ {
+ // Convert name, so that the keyname start with an upper
+ // char and the rest of the word are in lower chars
+ CharLowerBuffW( aKeyBuf, nKeyLen );
+ CharUpperBuffW( aKeyBuf, 1 );
+ wchar_t cTempChar;
+ wchar_t* pKeyBuf = aKeyBuf;
+ while ( (cTempChar = *pKeyBuf) != 0 )
+ {
+ if ( (cTempChar == '+') || (cTempChar == '-') ||
+ (cTempChar == ' ') || (cTempChar == '.') )
+ CharUpperBuffW( pKeyBuf+1, 1 );
+ pKeyBuf++;
+ }
+ }
+ else
+ {
+ sal_Char aAnsiKeyBuf[250];
+ int nAnsiKeyLen = GetKeyNameTextA( lParam, aAnsiKeyBuf, sizeof( aAnsiKeyBuf ) / sizeof( sal_Char ) );
+ if ( nAnsiKeyLen )
+ {
+ // Convert name, so that the keyname start with an upper
+ // char and the rest of the word are in lower chars
+ CharLowerBuffA( aAnsiKeyBuf, nAnsiKeyLen );
+ CharUpperBuffA( aAnsiKeyBuf, 1 );
+ sal_Char cTempChar;
+ sal_Char* pAnsiKeyBuf = aAnsiKeyBuf;
+ while ( (cTempChar = *pAnsiKeyBuf) != 0 )
+ {
+ if ( (cTempChar == '+') || (cTempChar == '-') ||
+ (cTempChar == ' ') || (cTempChar == '.') )
+ CharUpperBuffA( pAnsiKeyBuf+1, 1 );
+ pAnsiKeyBuf++;
+ }
+
+ // Convert to Unicode and copy the data in the Unicode Buffer
+ nKeyLen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, aAnsiKeyBuf, nAnsiKeyLen, aKeyBuf, sizeof( aKeyBuf ) / sizeof( sal_Unicode ) );
+ }
+ }
+ }
+
+ if ( (nKeyLen > 0) || pReplace )
+ {
+ if ( rCount )
+ {
+ pBuf[rCount] = '+';
+ rCount++;
+ }
+
+ if ( nKeyLen )
+ {
+ memcpy( pBuf+rCount, aKeyBuf, nKeyLen*sizeof( sal_Unicode ) );
+ rCount += nKeyLen;
+ }
+ else
+ {
+ while ( *pReplace )
+ {
+ pBuf[rCount] = *pReplace;
+ rCount++;
+ pReplace++;
+ }
+ }
+ }
+ else
+ rCount = 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalFrame::GetKeyName( USHORT nKeyCode )
+{
+ XubString aKeyCode;
+#ifdef WIN
+ sal_Unicode aKeyBuf[350];
+ UINT nKeyBufLen = 0;
+ UINT nSysCode;
+
+ if ( nKeyCode & KEY_MOD2 )
+ {
+ nSysCode = MapVirtualKey( VK_MENU, 0 );
+ nSysCode = (nSysCode << 16) | (((ULONG)1) << 25);
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ "Alt" );
+ }
+
+ if ( nKeyCode & KEY_MOD1 )
+ {
+ nSysCode = MapVirtualKey( VK_CONTROL, 0 );
+ nSysCode = (nSysCode << 16) | (((ULONG)1) << 25);
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ "Ctrl" );
+ }
+
+ if ( nKeyCode & KEY_SHIFT )
+ {
+ nSysCode = MapVirtualKey( VK_SHIFT, 0 );
+ nSysCode = (nSysCode << 16) | (((ULONG)1) << 25);
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ "Shift" );
+ }
+
+ USHORT nCode = nKeyCode & 0x0FFF;
+ ULONG nSysCode2 = 0;
+ sal_Char* pReplace = NULL;
+ sal_Unicode cSVCode = 0;
+ sal_Char aFBuf[4];
+ nSysCode = 0;
+
+ if ( (nCode >= KEY_0) && (nCode <= KEY_9) )
+ cSVCode = '0' + (nCode - KEY_0);
+ else if ( (nCode >= KEY_A) && (nCode <= KEY_Z) )
+ cSVCode = 'A' + (nCode - KEY_A);
+ else if ( (nCode >= KEY_F1) && (nCode <= KEY_F26) )
+ {
+ nSysCode = VK_F1 + (nCode - KEY_F1);
+ aFBuf[0] = 'F';
+ if ( (nCode >= KEY_F1) && (nCode <= KEY_F9) )
+ {
+ aFBuf[1] = '1' + (nCode - KEY_F1);
+ aFBuf[2] = 0;
+ }
+ else if ( (nCode >= KEY_F10) && (nCode <= KEY_F19) )
+ {
+ aFBuf[1] = '1';
+ aFBuf[2] = '0' + (nCode - KEY_F10);
+ aFBuf[3] = 0;
+ }
+ else
+ {
+ aFBuf[1] = '2';
+ aFBuf[2] = '0' + (nCode - KEY_F20);
+ aFBuf[3] = 0;
+ }
+ pReplace = aFBuf;
+ }
+ else
+ {
+ switch ( nCode )
+ {
+ case KEY_DOWN:
+ nSysCode = VK_DOWN;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Down";
+ break;
+ case KEY_UP:
+ nSysCode = VK_UP;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Up";
+ break;
+ case KEY_LEFT:
+ nSysCode = VK_LEFT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Left";
+ break;
+ case KEY_RIGHT:
+ nSysCode = VK_RIGHT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Right";
+ break;
+ case KEY_HOME:
+ nSysCode = VK_HOME;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Home";
+ break;
+ case KEY_END:
+ nSysCode = VK_END;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "End";
+ break;
+ case KEY_PAGEUP:
+ nSysCode = VK_PRIOR;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Page Up";
+ break;
+ case KEY_PAGEDOWN:
+ nSysCode = VK_NEXT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Page Down";
+ break;
+ case KEY_RETURN:
+ nSysCode = VK_RETURN;
+ pReplace = "Enter";
+ break;
+ case KEY_ESCAPE:
+ nSysCode = VK_ESCAPE;
+ pReplace = "Escape";
+ break;
+ case KEY_TAB:
+ nSysCode = VK_TAB;
+ pReplace = "Tab";
+ break;
+ case KEY_BACKSPACE:
+ nSysCode = VK_BACK;
+ pReplace = "Backspace";
+ break;
+ case KEY_SPACE:
+ nSysCode = VK_SPACE;
+ pReplace = "Space";
+ break;
+ case KEY_INSERT:
+ nSysCode = VK_INSERT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Insert";
+ break;
+ case KEY_DELETE:
+ nSysCode = VK_DELETE;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Delete";
+ break;
+
+ case KEY_ADD:
+ cSVCode = '+';
+ break;
+ case KEY_SUBTRACT:
+ cSVCode = '-';
+ break;
+ case KEY_MULTIPLY:
+ cSVCode = '*';
+ break;
+ case KEY_DIVIDE:
+ cSVCode = '/';
+ break;
+ case KEY_POINT:
+ cSVCode = '.';
+ break;
+ case KEY_COMMA:
+ cSVCode = ',';
+ break;
+ case KEY_LESS:
+ cSVCode = '<';
+ break;
+ case KEY_GREATER:
+ cSVCode = '>';
+ break;
+ case KEY_EQUAL:
+ cSVCode = '=';
+ break;
+ }
+ }
+
+ if ( nSysCode )
+ {
+ nSysCode = MapVirtualKey( (UINT)nSysCode, 0 );
+ if ( nSysCode )
+ nSysCode = (nSysCode << 16) | nSysCode2;
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ pReplace );
+ }
+ else
+ {
+ if ( cSVCode )
+ {
+ if ( !nKeyBufLen )
+ {
+ aKeyBuf[0] = cSVCode;
+ nKeyBufLen = 1;
+ }
+ else
+ {
+ aKeyBuf[nKeyBufLen] = '+';
+ nKeyBufLen++;
+ aKeyBuf[nKeyBufLen] = cSVCode;
+ nKeyBufLen++;
+ }
+ }
+ }
+
+ if ( nKeyBufLen )
+ aKeyCode.Assign( (const sal_Unicode*)aKeyBuf, nKeyBufLen );
+#endif
+
+ return aKeyCode;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode )
+{
+ return GetKeyName( nKeyCode );
+}
+
+// -----------------------------------------------------------------------
+
+inline Color ImplWinColorToSal( COLORREF nColor )
+{
+#ifdef WIN
+ return Color( GetRValue( nColor ), GetGValue( nColor ), GetBValue( nColor ) );
+#else
+ return NULL;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+static void ImplSalUpdateStyleFontA( const LOGFONTA& rLogFont, Font& rFont,
+ BOOL bOverwriteSystemCharSet )
+{
+ ImplSalLogFontToFontA( rLogFont, rFont );
+ if ( bOverwriteSystemCharSet && (rFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL) )
+ rFont.SetCharSet( gsl_getSystemTextEncoding() );
+ // Da bei einigen Windows-Einstellungen 6 Punkt eingetragen ist,
+ // obwohl im Dialog 8 Punkt angezeigt werden (da MS Sans Serif
+ // nicht skalierbar ist) vergroessern wir hier das als Hack, da
+ // ansonsten in russisch Symbolunterschriften nicht lesbar sind
+ if ( (rFont.GetName().EqualsIgnoreCaseAscii( "MS Sans Serif" ) ) &&
+ (rFont.GetHeight() < 8) )
+ rFont.SetHeight( 8 );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+static void ImplSalUpdateStyleFontW( const LOGFONTW& rLogFont, Font& rFont,
+ BOOL bOverwriteSystemCharSet )
+{
+ ImplSalLogFontToFontW( rLogFont, rFont );
+ if ( bOverwriteSystemCharSet && (rFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL) )
+ rFont.SetCharSet( gsl_getSystemTextEncoding() );
+ // Da bei einigen Windows-Einstellungen 6 Punkt eingetragen ist,
+ // obwohl im Dialog 8 Punkt angezeigt werden (da MS Sans Serif
+ // nicht skalierbar ist) vergroessern wir hier das als Hack, da
+ // ansonsten in russisch Symbolunterschriften nicht lesbar sind
+ if ( (rFont.GetName().EqualsIgnoreCaseAscii( "MS Sans Serif" ) ) &&
+ (rFont.GetHeight() < 8) )
+ rFont.SetHeight( 8 );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+static long ImplA2I( const BYTE* pStr )
+{
+ long n = 0;
+ int nSign = 1;
+
+ if ( *pStr == '-' )
+ {
+ nSign = -1;
+ pStr++;
+ }
+
+ while( (*pStr >= 48) && (*pStr <= 57) )
+ {
+ n *= 10;
+ n += ((*pStr) - 48);
+ pStr++;
+ }
+
+ n *= nSign;
+
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::UpdateSettings( AllSettings& rSettings )
+{
+#ifdef WIN
+ MouseSettings aMouseSettings = rSettings.GetMouseSettings();
+ aMouseSettings.SetDoubleClickTime( GetDoubleClickTime() );
+ aMouseSettings.SetDoubleClickWidth( GetSystemMetrics( SM_CXDOUBLECLK ) );
+ aMouseSettings.SetDoubleClickHeight( GetSystemMetrics( SM_CYDOUBLECLK ) );
+ long nDragWidth = GetSystemMetrics( SM_CXDRAG );
+ long nDragHeight = GetSystemMetrics( SM_CYDRAG );
+ if ( nDragWidth )
+ aMouseSettings.SetStartDragWidth( nDragWidth );
+ if ( nDragHeight )
+ aMouseSettings.SetStartDragHeight( nDragHeight );
+ HKEY hRegKey;
+ if ( RegOpenKey( HKEY_CURRENT_USER,
+ "Control Panel\\Desktop",
+ &hRegKey ) == ERROR_SUCCESS )
+ {
+ BYTE aValueBuf[10];
+ DWORD nValueSize = sizeof( aValueBuf );
+ DWORD nType;
+ if ( RegQueryValueEx( hRegKey, "MenuShowDelay", 0,
+ &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS )
+ {
+ if ( nType == REG_SZ )
+ aMouseSettings.SetMenuDelay( (ULONG)ImplA2I( aValueBuf ) );
+ }
+
+ RegCloseKey( hRegKey );
+ }
+
+ StyleSettings aStyleSettings = rSettings.GetStyleSettings();
+ BOOL bCompBorder = (aStyleSettings.GetOptions() & (STYLE_OPTION_MACSTYLE | STYLE_OPTION_UNIXSTYLE)) == 0;
+ aStyleSettings.SetScrollBarSize( GetSystemMetrics( SM_CXVSCROLL ) );
+ aStyleSettings.SetSpinSize( GetSystemMetrics( SM_CXVSCROLL ) );
+ aStyleSettings.SetCursorBlinkTime( GetCaretBlinkTime() );
+ if ( bCompBorder )
+ {
+ aStyleSettings.SetFloatTitleHeight( GetSystemMetrics( SM_CYSMCAPTION ) );
+ aStyleSettings.SetTitleHeight( GetSystemMetrics( SM_CYCAPTION ) );
+ aStyleSettings.SetActiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVEBORDER ) ) );
+ aStyleSettings.SetDeactiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVEBORDER ) ) );
+ if ( aSalShlData.mnVersion >= 410 )
+ {
+ aStyleSettings.SetActiveColor2( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTACTIVECAPTION ) ) );
+ aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTINACTIVECAPTION ) ) );
+ }
+ aStyleSettings.SetFaceColor( ImplWinColorToSal( GetSysColor( COLOR_3DFACE ) ) );
+ aStyleSettings.SetLightColor( ImplWinColorToSal( GetSysColor( COLOR_3DHILIGHT ) ) );
+ aStyleSettings.SetLightBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DLIGHT ) ) );
+ aStyleSettings.SetShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) );
+ aStyleSettings.SetDarkShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DDKSHADOW ) ) );
+ }
+ aStyleSettings.SetHelpColor( ImplWinColorToSal( GetSysColor( COLOR_INFOBK ) ) );
+ aStyleSettings.SetHelpTextColor( ImplWinColorToSal( GetSysColor( COLOR_INFOTEXT ) ) );
+ aStyleSettings.SetDialogColor( aStyleSettings.GetFaceColor() );
+ aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() );
+ aStyleSettings.SetButtonTextColor( ImplWinColorToSal( GetSysColor( COLOR_BTNTEXT ) ) );
+ aStyleSettings.SetRadioCheckTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) );
+ aStyleSettings.SetGroupTextColor( aStyleSettings.GetRadioCheckTextColor() );
+ aStyleSettings.SetLabelTextColor( aStyleSettings.GetRadioCheckTextColor() );
+ aStyleSettings.SetInfoTextColor( aStyleSettings.GetRadioCheckTextColor() );
+ aStyleSettings.SetWindowColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOW ) ) );
+ aStyleSettings.SetWindowTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) );
+ aStyleSettings.SetFieldColor( aStyleSettings.GetWindowColor() );
+ aStyleSettings.SetFieldTextColor( aStyleSettings.GetWindowTextColor() );
+ aStyleSettings.SetHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHT ) ) );
+ aStyleSettings.SetHighlightTextColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHTTEXT ) ) );
+ aStyleSettings.SetMenuHighlightColor( aStyleSettings.GetHighlightColor() );
+ aStyleSettings.SetMenuHighlightTextColor( aStyleSettings.GetHighlightTextColor() );
+ if ( bCompBorder )
+ {
+ aStyleSettings.SetMenuColor( ImplWinColorToSal( GetSysColor( COLOR_MENU ) ) );
+ aStyleSettings.SetMenuTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) );
+ aStyleSettings.SetActiveColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVECAPTION ) ) );
+ aStyleSettings.SetActiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_CAPTIONTEXT ) ) );
+ aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTION ) ) );
+ aStyleSettings.SetDeactiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ) );
+ }
+ // Bei hellgrau geben wir die Farbe vor, damit es besser aussieht
+ if ( aStyleSettings.GetFaceColor() == COL_LIGHTGRAY )
+ aStyleSettings.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) );
+ else
+ {
+ // Checked-Color berechnen
+ Color aColor1 = aStyleSettings.GetFaceColor();
+ Color aColor2 = aStyleSettings.GetLightColor();
+ BYTE nRed = (BYTE)(((USHORT)aColor1.GetRed() + (USHORT)aColor2.GetRed())/2);
+ BYTE nGreen = (BYTE)(((USHORT)aColor1.GetGreen() + (USHORT)aColor2.GetGreen())/2);
+ BYTE nBlue = (BYTE)(((USHORT)aColor1.GetBlue() + (USHORT)aColor2.GetBlue())/2);
+ aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) );
+ }
+
+ // Query Fonts
+ int bOverwriteSystemCharSet = getenv("LC_CHARSET") != 0;
+ Font aMenuFont = aStyleSettings.GetMenuFont();
+ Font aTitleFont = aStyleSettings.GetTitleFont();
+ Font aFloatTitleFont = aStyleSettings.GetFloatTitleFont();
+ Font aHelpFont = aStyleSettings.GetHelpFont();
+ Font aAppFont = aStyleSettings.GetAppFont();
+ Font aIconFont = aStyleSettings.GetIconFont();
+ if ( aSalShlData.mbWNT )
+ {
+ NONCLIENTMETRICSW aNonClientMetrics;
+ aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
+ if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
+ {
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfMenuFont, aMenuFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfCaptionFont, aTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfSmCaptionFont, aFloatTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfStatusFont, aHelpFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfMessageFont, aAppFont, bOverwriteSystemCharSet );
+
+ LOGFONTW aLogFont;
+ if ( SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &aLogFont, 0 ) )
+ ImplSalUpdateStyleFontW( aLogFont, aIconFont, bOverwriteSystemCharSet );
+ }
+ }
+ else
+ {
+ NONCLIENTMETRICSA aNonClientMetrics;
+ aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
+ if ( SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
+ {
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfMenuFont, aMenuFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfCaptionFont, aTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfSmCaptionFont, aFloatTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfStatusFont, aHelpFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfMessageFont, aAppFont, bOverwriteSystemCharSet );
+
+ LOGFONTA aLogFont;
+ if ( SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, &aLogFont, 0 ) )
+ ImplSalUpdateStyleFontA( aLogFont, aIconFont, bOverwriteSystemCharSet );
+ }
+ }
+ aStyleSettings.SetMenuFont( aMenuFont );
+ aStyleSettings.SetTitleFont( aTitleFont );
+ aStyleSettings.SetFloatTitleFont( aFloatTitleFont );
+ aStyleSettings.SetHelpFont( aHelpFont );
+ aStyleSettings.SetIconFont( aIconFont );
+ // We prefer Arial in the russian version, because MS Sans Serif
+ // is to wide for the dialogs
+ if ( rSettings.GetInternational().GetLanguage() == LANGUAGE_RUSSIAN )
+ {
+ XubString aFontName = aAppFont.GetName();
+ XubString aFirstName = aFontName.GetToken( 0, ';' );
+ if ( aFirstName.EqualsIgnoreCaseAscii( "MS Sans Serif" ) )
+ {
+ aFontName.InsertAscii( "Arial;", 0 );
+ aAppFont.SetName( aFontName );
+ }
+ }
+ aStyleSettings.SetAppFont( aAppFont );
+ aStyleSettings.SetGroupFont( aAppFont );
+ aStyleSettings.SetLabelFont( aAppFont );
+ aStyleSettings.SetRadioCheckFont( aAppFont );
+ aStyleSettings.SetPushButtonFont( aAppFont );
+ aStyleSettings.SetFieldFont( aAppFont );
+ if ( aAppFont.GetWeight() > WEIGHT_NORMAL )
+ aAppFont.SetWeight( WEIGHT_NORMAL );
+ aStyleSettings.SetInfoFont( aAppFont );
+ aStyleSettings.SetToolFont( aAppFont );
+
+ WIN_BOOL bDragFull;
+ if ( SystemParametersInfo( SPI_GETDRAGFULLWINDOWS, 0, &bDragFull, 0 ) )
+ {
+ ULONG nDragFullOptions = aStyleSettings.GetDragFullOptions();
+ if ( bDragFull )
+ nDragFullOptions |= DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT;
+ else
+ nDragFullOptions &= ~(DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT);
+ aStyleSettings.SetDragFullOptions( nDragFullOptions );
+ }
+
+ aStyleSettings.SetIconHorzSpace( GetSystemMetrics( SM_CXICONSPACING ) );
+ aStyleSettings.SetIconVertSpace( GetSystemMetrics( SM_CYICONSPACING ) );
+ if ( RegOpenKey( HKEY_CURRENT_USER,
+ "Control Panel\\International\\Calendars\\TwoDigitYearMax",
+ &hRegKey ) == ERROR_SUCCESS )
+ {
+ BYTE aValueBuf[10];
+ DWORD nValue;
+ DWORD nValueSize = sizeof( aValueBuf );
+ DWORD nType;
+ if ( RegQueryValueEx( hRegKey, "1", 0,
+ &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS )
+ {
+ if ( nType == REG_SZ )
+ {
+ nValue = (ULONG)ImplA2I( aValueBuf );
+ if ( (nValue > 1000) && (nValue < 10000) )
+ {
+ MiscSettings aMiscSettings = rSettings.GetMiscSettings();
+ aMiscSettings.SetTwoDigitYearStart( (USHORT)(nValue-99) );
+ rSettings.SetMiscSettings( aMiscSettings );
+ }
+ }
+ }
+
+ RegCloseKey( hRegKey );
+ }
+
+ rSettings.SetMouseSettings( aMouseSettings );
+ rSettings.SetStyleSettings( aStyleSettings );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* SalFrame::GetSystemData() const
+{
+ return &maFrameData.maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Beep( SoundType eSoundType )
+{
+#ifdef WIN
+ static UINT aImplSoundTab[5] =
+ {
+ 0, // SOUND_DEFAULT
+ MB_ICONASTERISK, // SOUND_INFO
+ MB_ICONEXCLAMATION, // SOUND_WARNING
+ MB_ICONHAND, // SOUND_ERROR
+ MB_ICONQUESTION // SOUND_QUERY
+ };
+
+#if SOUND_COUNT != 5
+#error New Sound must be defined!
+#endif
+
+ MessageBeep( aImplSoundTab[eSoundType] );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetCallback( void* pInst, SALFRAMEPROC pProc )
+{
+ maFrameData.mpInst = pInst;
+ if ( pProc )
+ maFrameData.mpProc = pProc;
+ else
+ maFrameData.mpProc = ImplSalCallbackDummy;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleMouseMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ SalMouseEvent aMouseEvt;
+ long nRet;
+#ifdef WIN
+ USHORT nEvent;
+ BOOL bCall = TRUE;
+
+ aMouseEvt.mnX = (short)LOWORD( lParam );
+ aMouseEvt.mnY = (short)HIWORD( lParam );
+ aMouseEvt.mnCode = 0;
+ aMouseEvt.mnTime = GetMessageTime();
+
+ // Wegen (Logitech-)MouseTreiber ueber GetKeyState() gehen, die auf
+ // mittlerer Maustaste Doppelklick simulieren und den KeyStatus nicht
+ // beruecksichtigen
+
+ if ( GetKeyState( VK_LBUTTON ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_LEFT;
+ if ( GetKeyState( VK_MBUTTON ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_MIDDLE;
+ if ( GetKeyState( VK_RBUTTON ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_RIGHT;
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_MOD2;
+
+ switch ( nMsg )
+ {
+ case WM_MOUSEMOVE:
+ {
+ // Da bei Druecken von Modifier-Tasten die MouseEvents
+ // nicht zusammengefast werden (da diese durch KeyEvents
+ // unterbrochen werden), machen wir dieses hier selber
+ if ( aMouseEvt.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2) )
+ {
+ MSG aTempMsg;
+ if ( ImplPeekMessage( &aTempMsg, hWnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE | PM_NOYIELD ) )
+ {
+ if ( (aTempMsg.message == WM_MOUSEMOVE) &&
+ (aTempMsg.wParam == wParam) )
+ return 1;
+ }
+ }
+
+ SalData* pSalData = GetSalData();
+ // Test for MouseLeave
+ if ( pSalData->mhWantLeaveMsg && (pSalData->mhWantLeaveMsg != hWnd) )
+ ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, GetMessagePos() );
+ pSalData->mhWantLeaveMsg = hWnd;
+ // Start MouseLeave-Timer
+ if ( !pSalData->mpMouseLeaveTimer )
+ {
+ pSalData->mpMouseLeaveTimer = new AutoTimer;
+ pSalData->mpMouseLeaveTimer->SetTimeout( SAL_MOUSELEAVE_TIMEOUT );
+ pSalData->mpMouseLeaveTimer->Start();
+ // We dont need to set a timeout handler, because we test
+ // for mouseleave in the timeout callback
+ }
+ aMouseEvt.mnButton = 0;
+ nEvent = SALEVENT_MOUSEMOVE;
+ }
+ break;
+
+ case WM_NCMOUSEMOVE:
+ case SAL_MSG_MOUSELEAVE:
+ {
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mhWantLeaveMsg == hWnd )
+ {
+ pSalData->mhWantLeaveMsg = 0;
+ if ( pSalData->mpMouseLeaveTimer )
+ {
+ delete pSalData->mpMouseLeaveTimer;
+ pSalData->mpMouseLeaveTimer = NULL;
+ }
+ // Mouse-Coordinaates are relativ to the screen
+ POINT aPt;
+ aPt.x = (short)LOWORD( lParam );
+ aPt.y = (short)HIWORD( lParam );
+ ScreenToClient( hWnd, &aPt );
+ aMouseEvt.mnX = aPt.x;
+ aMouseEvt.mnY = aPt.y;
+ aMouseEvt.mnButton = 0;
+ nEvent = SALEVENT_MOUSELEAVE;
+ }
+ else
+ bCall = FALSE;
+ }
+ break;
+
+ case WM_LBUTTONDOWN:
+ aMouseEvt.mnButton = MOUSE_LEFT;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ break;
+
+ case WM_MBUTTONDOWN:
+ aMouseEvt.mnButton = MOUSE_MIDDLE;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ break;
+
+ case WM_RBUTTONDOWN:
+ aMouseEvt.mnButton = MOUSE_RIGHT;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ break;
+
+ case WM_LBUTTONUP:
+ aMouseEvt.mnButton = MOUSE_LEFT;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+
+ case WM_MBUTTONUP:
+ aMouseEvt.mnButton = MOUSE_MIDDLE;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+
+ case WM_RBUTTONUP:
+ aMouseEvt.mnButton = MOUSE_RIGHT;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+ }
+
+ if ( bCall )
+ {
+ if ( nEvent == SALEVENT_MOUSEBUTTONDOWN )
+ UpdateWindow( hWnd );
+
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aMouseEvt );
+ if ( nMsg == WM_MOUSEMOVE )
+ SetCursor( pFrame->maFrameData.mhCursor );
+ }
+ else
+ nRet = 0;
+
+ return nRet;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleMouseActivateMsg( HWND hWnd )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ SalMouseActivateEvent aMouseActivateEvt;
+ POINT aPt;
+#ifdef WIN
+ GetCursorPos( &aPt );
+ ScreenToClient( hWnd, &aPt );
+#endif
+ aMouseActivateEvt.mnX = aPt.x;
+ aMouseActivateEvt.mnY = aPt.y;
+ return pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_MOUSEACTIVATE, &aMouseActivateEvt );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleWheelMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ ImplSalYieldMutexAcquireWithWait();
+
+ long nRet = 0;
+#ifdef WIN
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ WORD nWinModCode = LOWORD( wParam );
+ POINT aWinPt;
+ aWinPt.x = (short)LOWORD( lParam );
+ aWinPt.y = (short)HIWORD( lParam );
+ ScreenToClient( hWnd, &aWinPt );
+
+ SalWheelMouseEvent aWheelEvt;
+ aWheelEvt.mnTime = GetMessageTime();
+ aWheelEvt.mnX = aWinPt.x;
+ aWheelEvt.mnY = aWinPt.y;
+ aWheelEvt.mnCode = 0;
+ aWheelEvt.mnDelta = (short)HIWORD( wParam );
+ aWheelEvt.mnNotchDelta = aWheelEvt.mnDelta/WHEEL_DELTA;
+ if ( aSalShlData.mnWheelScrollLines == WHEEL_PAGESCROLL )
+ aWheelEvt.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
+ else
+ aWheelEvt.mnScrollLines = aSalShlData.mnWheelScrollLines;
+ aWheelEvt.mbHorz = FALSE;
+
+ if ( nWinModCode & MK_SHIFT )
+ aWheelEvt.mnCode |= KEY_SHIFT;
+ if ( nWinModCode & MK_CONTROL )
+ aWheelEvt.mnCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ aWheelEvt.mnCode |= KEY_MOD2;
+
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_WHEELMOUSE, &aWheelEvt );
+ }
+
+ ImplSalYieldMutexRelease();
+#endif
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplSalGetKeyCode( WPARAM wParam )
+{
+ USHORT nKeyCode;
+
+ // convert KeyCode
+ if ( wParam < KEY_TAB_SIZE )
+ nKeyCode = aImplTranslateKeyTab[wParam];
+ else if ( wParam == aSalShlData.mnVKAdd )
+ nKeyCode = KEY_ADD;
+ else if ( wParam == aSalShlData.mnVKSubtract )
+ nKeyCode = KEY_SUBTRACT;
+ else if ( wParam == aSalShlData.mnVKMultiply )
+ nKeyCode = KEY_MULTIPLY;
+ else if ( wParam == aSalShlData.mnVKDivide )
+ nKeyCode = KEY_DIVIDE;
+ else if ( wParam == aSalShlData.mnVKPoint )
+ nKeyCode = KEY_POINT;
+ else if ( wParam == aSalShlData.mnVKComma )
+ nKeyCode = KEY_COMMA;
+ else if ( wParam == aSalShlData.mnVKLess )
+ nKeyCode = KEY_LESS;
+ else if ( wParam == aSalShlData.mnVKGreater )
+ nKeyCode = KEY_GREATER;
+ else if ( wParam == aSalShlData.mnVKEqual )
+ nKeyCode = KEY_EQUAL;
+ else
+ nKeyCode = 0;
+
+ return nKeyCode;
+}
+
+// -----------------------------------------------------------------------
+
+static UINT ImplStrToNum( const sal_Char* pStr )
+{
+ USHORT n = 0;
+
+ // Solange es sich um eine Ziffer handelt, String umwandeln
+ while( (*pStr >= 48) && (*pStr <= 57) )
+ {
+ n *= 10;
+ n += ((*pStr) - 48);
+ pStr++;
+ }
+
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Unicode ImplGetCharCode( SalFrame* pFrame, WPARAM nCharCode )
+{
+#ifdef WIN
+ UINT nLang = LOWORD( GetKeyboardLayout( 0 ) );
+ if ( !nLang )
+ {
+ pFrame->maFrameData.mnInputLang = 0;
+ pFrame->maFrameData.mnInputCodePage = GetACP();
+ }
+ else if ( nLang != pFrame->maFrameData.mnInputLang )
+ {
+ pFrame->maFrameData.mnInputLang = nLang;
+ sal_Char aBuf[10];
+ if ( GetLocaleInfoA( MAKELCID( nLang, SORT_DEFAULT ), LOCALE_IDEFAULTANSICODEPAGE,
+ aBuf, sizeof(aBuf) ) > 0 )
+ {
+ pFrame->maFrameData.mnInputCodePage = ImplStrToNum( aBuf );
+ if ( !pFrame->maFrameData.mnInputCodePage )
+ pFrame->maFrameData.mnInputCodePage = GetACP();
+ }
+ else
+ pFrame->maFrameData.mnInputCodePage = GetACP();
+ }
+
+ sal_Char aCharBuf[2];
+ int nCharLen;
+ wchar_t c;
+ if ( nCharCode > 0xFF )
+ {
+ aCharBuf[0] = (sal_Char)(nCharCode>>8);
+ aCharBuf[1] = (sal_Char)nCharCode;
+ nCharLen = 2;
+ }
+ else
+ {
+ aCharBuf[0] = (sal_Char)nCharCode;
+ nCharLen = 1;
+ }
+ if ( ::MultiByteToWideChar( pFrame->maFrameData.mnInputCodePage,
+ MB_PRECOMPOSED,
+ aCharBuf, nCharLen, &c, 1 ) )
+ return (sal_Unicode)c;
+ else
+#endif
+ return (sal_Unicode)nCharCode;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleKeyMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+#ifdef WIN
+ static BOOL bIgnoreCharMsg = FALSE;
+ static WPARAM nDeadChar = 0;
+ static WPARAM nLastVKChar = 0;
+ static USHORT nLastChar = 0;
+ USHORT nRepeat = LOWORD( lParam )-1;
+ USHORT nModCode = 0;
+
+ // Key wurde evtl. durch SysChild an uns weitergeleitet und
+ // darf somit dann nicht doppelt verarbeitet werden
+ GetSalData()->mnSalObjWantKeyEvt = 0;
+
+ if ( nMsg == WM_DEADCHAR )
+ {
+ nDeadChar = wParam;
+ return 0;
+ }
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ // Wir restaurieren den Background-Modus bei jeder Texteingabe,
+ // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
+ if ( pFrame->maFrameData.mpGraphics &&
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC )
+ SetBkMode( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC, TRANSPARENT );
+
+ // determine modifiers
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ {
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) &&
+ ((nMsg == WM_SYSKEYDOWN) || (nMsg == WM_SYSKEYUP)) )
+ nModCode |= KEY_CONTROLMOD;
+ }
+
+ if ( (nMsg == WM_CHAR) || (nMsg == WM_SYSCHAR) )
+ {
+ nDeadChar = 0;
+
+ if ( bIgnoreCharMsg )
+ {
+ bIgnoreCharMsg = FALSE;
+ return 0;
+ }
+
+ // Backspace ignorieren wir als eigenstaendige Taste,
+ // damit wir keine Probleme in Kombination mit einem
+ // DeadKey bekommen
+ if ( wParam == 0x08 ) // BACKSPACE
+ return 0;
+
+ // Hier kommen nur "freifliegende" WM_CHAR Message an, die durch
+ // eintippen einer ALT-NUMPAD Kombination erzeugt wurden
+ SalKeyEvent aKeyEvt;
+
+ if ( (wParam >= '0') && (wParam <= '9') )
+ aKeyEvt.mnCode = KEYGROUP_NUM + wParam - '0';
+ else if ( (wParam >= 'A') && (wParam <= 'Z') )
+ aKeyEvt.mnCode = KEYGROUP_ALPHA + wParam - 'A';
+ else if ( (wParam >= 'a') && (wParam <= 'z') )
+ aKeyEvt.mnCode = KEYGROUP_ALPHA + wParam - 'a';
+ else if ( wParam == 0x0D ) // RETURN
+ aKeyEvt.mnCode = KEY_RETURN;
+ else if ( wParam == 0x1B ) // ESCAPE
+ aKeyEvt.mnCode = KEY_ESCAPE;
+ else if ( wParam == 0x09 ) // TAB
+ aKeyEvt.mnCode = KEY_TAB;
+ else if ( wParam == 0x20 ) // SPACE
+ aKeyEvt.mnCode = KEY_SPACE;
+ else
+ aKeyEvt.mnCode = 0;
+
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, wParam );
+ aKeyEvt.mnRepeat = nRepeat;
+ nLastChar = 0;
+ nLastVKChar = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return nRet;
+ }
+ else
+ {
+ // Bei Shift, Control und Menu schicken wir einen KeyModChange-Event
+ if ( (wParam == VK_SHIFT) || (wParam == VK_CONTROL) || (wParam == VK_MENU) )
+ {
+ SalKeyModEvent aModEvt;
+ aModEvt.mnTime = GetMessageTime();
+ aModEvt.mnCode = nModCode;
+ return pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYMODCHANGE, &aModEvt );
+ }
+ else
+ {
+ SalKeyEvent aKeyEvt;
+ USHORT nEvent;
+ MSG aCharMsg;
+ WIN_BOOL bCharPeek = FALSE;
+ UINT nCharMsg = WM_CHAR;
+ BOOL bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP);
+
+ aKeyEvt.mnCode = ImplSalGetKeyCode( wParam );
+ if ( !bKeyUp )
+ {
+ // check for charcode
+ // Mit Hilfe von PeekMessage holen wir uns jetzt die
+ // zugehoerige WM_CHAR Message, wenn vorhanden.
+ // Diese WM_CHAR Message steht immer am Anfang der
+ // Messagequeue. Ausserdem ist sichergestellt, dass immer
+ // nur eine WM_CHAR Message in der Queue steht.
+ bCharPeek = ImplPeekMessage( &aCharMsg, hWnd,
+ WM_CHAR, WM_CHAR, PM_NOREMOVE | PM_NOYIELD );
+ if ( bCharPeek && (nDeadChar == aCharMsg.wParam) )
+ {
+ bCharPeek = FALSE;
+ nDeadChar = 0;
+
+ if ( wParam == VK_BACK )
+ {
+ ImplPeekMessage( &aCharMsg, hWnd,
+ nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD );
+ return 0;
+ }
+ }
+ else
+ {
+ if ( !bCharPeek )
+ {
+ bCharPeek = ImplPeekMessage( &aCharMsg, hWnd,
+ WM_SYSCHAR, WM_SYSCHAR, PM_NOREMOVE | PM_NOYIELD );
+ nCharMsg = WM_SYSCHAR;
+ }
+ }
+ if ( bCharPeek )
+ aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, aCharMsg.wParam );
+ else
+ aKeyEvt.mnCharCode = 0;
+
+ nLastChar = aKeyEvt.mnCharCode;
+ nLastVKChar = wParam;
+ }
+ else
+ {
+ if ( wParam == nLastVKChar )
+ {
+ aKeyEvt.mnCharCode = nLastChar;
+ nLastChar = 0;
+ nLastVKChar = 0;
+ }
+ }
+
+ if ( aKeyEvt.mnCode || aKeyEvt.mnCharCode )
+ {
+ if ( bKeyUp )
+ nEvent = SALEVENT_KEYUP;
+ else
+ nEvent = SALEVENT_KEYINPUT;
+
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnRepeat = nRepeat;
+ bIgnoreCharMsg = bCharPeek;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aKeyEvt );
+ bIgnoreCharMsg = FALSE;
+
+ // char-message, than remove or ignore
+ if ( bCharPeek )
+ {
+ nDeadChar = 0;
+ if ( nRet )
+ {
+ ImplPeekMessage( &aCharMsg, hWnd,
+ nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD );
+ }
+ else
+ bIgnoreCharMsg = TRUE;
+ }
+
+ return nRet;
+ }
+ else
+ return 0;
+ }
+ }
+#else
+ return 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleSalObjKeyMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+#ifdef WIN
+ if ( (nMsg == WM_KEYDOWN) || (nMsg == WM_KEYUP) )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ USHORT nRepeat = LOWORD( lParam )-1;
+ USHORT nModCode = 0;
+
+ // determine modifiers
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ {
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+ }
+
+ if ( (wParam != VK_SHIFT) && (wParam != VK_CONTROL) && (wParam != VK_MENU) )
+ {
+ SalKeyEvent aKeyEvt;
+ USHORT nEvent;
+ BOOL bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP);
+
+ // convert KeyCode
+ aKeyEvt.mnCode = ImplSalGetKeyCode( wParam );
+ aKeyEvt.mnCharCode = 0;
+
+ if ( aKeyEvt.mnCode )
+ {
+ if ( bKeyUp )
+ nEvent = SALEVENT_KEYUP;
+ else
+ nEvent = SALEVENT_KEYINPUT;
+
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnRepeat = nRepeat;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aKeyEvt );
+ return nRet;
+ }
+ else
+ return 0;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleSalObjSysCharMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+#ifdef WIN
+ USHORT nRepeat = LOWORD( lParam )-1;
+ USHORT nModCode = 0;
+ USHORT cKeyCode = (USHORT)wParam;
+
+ // determine modifiers
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+
+ // KeyEvent zusammenbauen
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = GetMessageTime();
+ if ( (cKeyCode >= 48) && (cKeyCode <= 57) )
+ aKeyEvt.mnCode = KEY_0+(cKeyCode-48);
+ else if ( (cKeyCode >= 65) && (cKeyCode <= 90) )
+ aKeyEvt.mnCode = KEY_A+(cKeyCode-65);
+ else if ( (cKeyCode >= 97) && (cKeyCode <= 122) )
+ aKeyEvt.mnCode = KEY_A+(cKeyCode-97);
+ else
+ aKeyEvt.mnCode = 0;
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, cKeyCode );
+ aKeyEvt.mnRepeat = nRepeat;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return nRet;
+#else
+ return 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandlePaintMsg( HWND hWnd )
+{
+ // Clip-Region muss zurueckgesetzt werden, da wir sonst kein
+ // ordentliches Bounding-Rectangle bekommen
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mpGraphics )
+ {
+#ifdef WIN
+ if ( pFrame->maFrameData.mpGraphics->maGraphicsData.mhRegion )
+ SelectClipRgn( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC, 0 );
+#endif
+ }
+ ImplSalYieldMutexRelease();
+ }
+
+#ifdef WIN
+ // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine
+ // Paint-Region anliegt
+ if ( !GetUpdateRect( hWnd, NULL, FALSE ) )
+ return;
+
+ // BeginPaint
+ PAINTSTRUCT aPs;
+ BeginPaint( hWnd, &aPs );
+
+ // Paint
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ // ClipRegion wieder herstellen
+ if ( pFrame->maFrameData.mpGraphics )
+ {
+ if ( pFrame->maFrameData.mpGraphics->maGraphicsData.mhRegion )
+ {
+#ifdef WIN
+ SelectClipRgn( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC,
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mhRegion );
+#endif
+ }
+ }
+
+ SalPaintEvent aPEvt;
+ aPEvt.mnBoundX = aPs.rcPaint.left;
+ aPEvt.mnBoundY = aPs.rcPaint.top;
+ aPEvt.mnBoundWidth = aPs.rcPaint.right-aPs.rcPaint.left;
+ aPEvt.mnBoundHeight = aPs.rcPaint.bottom-aPs.rcPaint.top;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_PAINT, &aPEvt );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ {
+ RECT* pRect = new RECT;
+ *pRect = aPs.rcPaint;
+ ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 );
+ }
+
+ // EndPaint
+ EndPaint( hWnd, &aPs );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandlePaintMsg2( HWND hWnd, RECT* pRect )
+{
+ // Paint
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ SalPaintEvent aPEvt;
+ aPEvt.mnBoundX = pRect->left;
+ aPEvt.mnBoundY = pRect->top;
+ aPEvt.mnBoundWidth = pRect->right-pRect->left;
+ aPEvt.mnBoundHeight = pRect->bottom-pRect->top;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_PAINT, &aPEvt );
+ }
+ ImplSalYieldMutexRelease();
+ delete pRect;
+ }
+#ifdef WIN
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleMoveMsg( HWND hWnd )
+{
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+#ifdef WIN
+ if ( GetWindowStyle( hWnd ) & WS_VISIBLE )
+ pFrame->maFrameData.mbDefPos = FALSE;
+#endif
+
+ // Gegen moegliche Rekursionen sichern
+ if ( !pFrame->maFrameData.mbInMoveMsg )
+ {
+ // Fenster im FullScreenModus wieder einpassen
+ pFrame->maFrameData.mbInMoveMsg = TRUE;
+ if ( pFrame->maFrameData.mbFullScreen )
+ ImplSalFrameFullScreenPos( pFrame );
+ pFrame->maFrameData.mbInMoveMsg = FALSE;
+ }
+
+ // Status merken
+ ImplSaveFrameState( pFrame );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+#ifdef WIN
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTMOVE, 0, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCallSizeHdl( HWND hWnd )
+{
+ // Da Windows diese Messages auch senden kann, muss hier auch die
+ // Solar-Semaphore beruecksichtigt werden
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_RESIZE, 0 );
+#ifdef WIN
+ // Um doppelte Paints von VCL und SAL zu vermeiden
+ if ( IsWindowVisible( hWnd ) && !pFrame->maFrameData.mbInShow )
+ UpdateWindow( hWnd );
+#endif
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+#ifdef WIN
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTCALLSIZE, 0, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSizeMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+#ifdef WIN
+ if ( (wParam != SIZE_MAXSHOW) && (wParam != SIZE_MAXHIDE) )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mnWidth = (int)LOWORD(lParam);
+ pFrame->maFrameData.mnHeight = (int)HIWORD(lParam);
+ // Status merken
+ ImplSaveFrameState( pFrame );
+ // Call Hdl
+ ImplCallSizeHdl( hWnd );
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleFocusMsg( HWND hWnd )
+{
+#ifdef WIN
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ // Query the actual status
+ if ( ::GetFocus() == hWnd )
+ {
+ if ( IsWindowVisible( hWnd ) && !pFrame->maFrameData.mbInShow )
+ UpdateWindow( hWnd );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_GETFOCUS, 0 );
+ }
+ else
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_LOSEFOCUS, 0 );
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTFOCUS, 0, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleCloseMsg( HWND hWnd )
+{
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_CLOSE, 0 );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+#ifdef WIN
+ else
+ ImplPostMessage( hWnd, WM_CLOSE, 0, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleShutDownMsg( HWND hWnd )
+{
+ ImplSalYieldMutexAcquireWithWait();
+ long nRet = 0;
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_SHUTDOWN, 0 );
+ }
+ ImplSalYieldMutexRelease();
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSettingsChangeMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+#ifdef WIN
+ USHORT nSalEvent = SALEVENT_SETTINGSCHANGED;
+
+ if ( nMsg == WM_DEVMODECHANGE )
+ nSalEvent = SALEVENT_PRINTERCHANGED;
+ else if ( nMsg == WM_DISPLAYCHANGE )
+ nSalEvent = SALEVENT_DISPLAYCHANGED;
+ else if ( nMsg == WM_FONTCHANGE )
+ nSalEvent = SALEVENT_FONTCHANGED;
+ else if ( nMsg == WM_TIMECHANGE )
+ nSalEvent = SALEVENT_DATETIMECHANGED;
+ else if ( nMsg == WM_WININICHANGE )
+ {
+ if ( lParam )
+ {
+ if ( aSalShlData.mbWNT )
+ {
+ if ( ImplSalWICompareAscii( (const wchar_t*)lParam, "devices" ) == 0 )
+ nSalEvent = SALEVENT_PRINTERCHANGED;
+ }
+ else
+ {
+ if ( stricmp( (const char*)lParam, "devices" ) == 0 )
+ nSalEvent = SALEVENT_PRINTERCHANGED;
+ }
+ }
+ }
+
+ if ( nMsg == WM_SETTINGCHANGE )
+ {
+ if ( wParam == SPI_SETWHEELSCROLLLINES )
+ aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines();
+ }
+
+ if ( WM_SYSCOLORCHANGE == nMsg && GetSalData()->mhDitherPal )
+ ImplUpdateSysColorEntries();
+
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( (nMsg == WM_DISPLAYCHANGE) || (nMsg == WM_WININICHANGE) )
+ {
+ if ( pFrame->maFrameData.mbFullScreen )
+ ImplSalFrameFullScreenPos( pFrame );
+ }
+
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nSalEvent, 0 );
+ }
+
+ ImplSalYieldMutexRelease();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleUserEvent( HWND hWnd, LPARAM lParam )
+{
+ ImplSalYieldMutexAcquireWithWait();
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_USEREVENT, (void*)lParam );
+ }
+ ImplSalYieldMutexRelease();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleForcePalette( HWND hWnd )
+{
+ SalData* pSalData = GetSalData();
+ HPALETTE hPal = pSalData->mhDitherPal;
+ if ( hPal )
+ {
+ if ( !ImplSalYieldMutexTryToAcquire() )
+ {
+#ifdef WIN
+ ImplPostMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 );
+#endif
+ return;
+ }
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mpGraphics )
+ {
+ SalGraphics* pGraphics = pFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+#ifdef WIN
+ SelectPalette( pGraphics->maGraphicsData.mhDC, hPal, FALSE );
+ if ( RealizePalette( pGraphics->maGraphicsData.mhDC ) )
+ {
+ InvalidateRect( hWnd, NULL, FALSE );
+ UpdateWindow( hWnd );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_DISPLAYCHANGED, 0 );
+ }
+#endif
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static LRESULT ImplHandlePalette( BOOL bFrame, HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ SalData* pSalData = GetSalData();
+ HPALETTE hPal = pSalData->mhDitherPal;
+ if ( !hPal )
+ return 0;
+
+ rDef = FALSE;
+ if ( pSalData->mbInPalChange )
+ return 0;
+#ifdef WIN
+ if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) )
+ {
+ if ( (HWND)wParam == hWnd )
+ return 0;
+ }
+
+ BOOL bReleaseMutex = FALSE;
+ if ( (nMsg == WM_QUERYNEWPALETTE) || (nMsg == WM_PALETTECHANGED) )
+ {
+ // Da Windows diese Messages auch sendet, muss hier auch die
+ // Solar-Semaphore beruecksichtigt werden
+ if ( ImplSalYieldMutexTryToAcquire() )
+ bReleaseMutex = TRUE;
+ else if ( nMsg == WM_QUERYNEWPALETTE )
+ ImplPostMessage( hWnd, SAL_MSG_POSTQUERYNEWPAL, wParam, lParam );
+ else /* ( nMsg == WM_PALETTECHANGED ) */
+ ImplPostMessage( hWnd, SAL_MSG_POSTPALCHANGED, wParam, lParam );
+ }
+
+ SalVirtualDevice* pTempVD;
+ SalFrame* pTempFrame;
+ SalGraphics* pGraphics;
+ HDC hDC;
+ HPALETTE hOldPal;
+ UINT nCols;
+ BOOL bStdDC;
+ BOOL bUpdate;
+
+ pSalData->mbInPalChange = TRUE;
+
+ // Alle Paletten in VirDevs und Frames zuruecksetzen
+ pTempVD = pSalData->mpFirstVD;
+ while ( pTempVD )
+ {
+ pGraphics = pTempVD->maVirDevData.mpGraphics;
+ if ( pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC,
+ pGraphics->maGraphicsData.mhDefPal,
+ TRUE );
+ }
+ pTempVD = pTempVD->maVirDevData.mpNext;
+ }
+ pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame )
+ {
+ pGraphics = pTempFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC,
+ pGraphics->maGraphicsData.mhDefPal,
+ TRUE );
+ }
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+ }
+
+ // Palette neu realizen
+ SalFrame* pFrame = NULL;
+ if ( bFrame )
+ pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mpGraphics )
+ {
+ hDC = pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC;
+ bStdDC = TRUE;
+ }
+ else
+ {
+ hDC = GetDC( hWnd );
+ bStdDC = FALSE;
+ }
+ UnrealizeObject( hPal );
+ hOldPal = SelectPalette( hDC, hPal, TRUE );
+ nCols = RealizePalette( hDC );
+ bUpdate = nCols != 0;
+ if ( !bStdDC )
+ {
+ SelectPalette( hDC, hOldPal, TRUE );
+ ReleaseDC( hWnd, hDC );
+ }
+
+ // Alle Paletten in VirDevs und Frames neu setzen
+ pTempVD = pSalData->mpFirstVD;
+ while ( pTempVD )
+ {
+ pGraphics = pTempVD->maVirDevData.mpGraphics;
+ if ( pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC, hPal, TRUE );
+ RealizePalette( pGraphics->maGraphicsData.mhDC );
+ }
+ pTempVD = pTempVD->maVirDevData.mpNext;
+ }
+ pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame )
+ {
+ if ( pTempFrame != pFrame )
+ {
+ pGraphics = pTempFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC, hPal, TRUE );
+ if ( RealizePalette( pGraphics->maGraphicsData.mhDC ) )
+ bUpdate = TRUE;
+ }
+ }
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+ }
+
+ // Wenn sich Farben geaendert haben, dann die Fenster updaten
+ if ( bUpdate )
+ {
+ pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame )
+ {
+ pGraphics = pTempFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ InvalidateRect( pTempFrame->maFrameData.mhWnd, NULL, FALSE );
+ UpdateWindow( pTempFrame->maFrameData.mhWnd );
+ pTempFrame->maFrameData.mpProc( pTempFrame->maFrameData.mpInst, pTempFrame,
+ SALEVENT_DISPLAYCHANGED, 0 );
+ }
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+ }
+ }
+
+ pSalData->mbInPalChange = FALSE;
+
+ if ( bReleaseMutex )
+ ImplSalYieldMutexRelease();
+
+ if ( nMsg == WM_PALETTECHANGED )
+ return 0;
+ else
+ return nCols;
+#else
+ return 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplHandleMinMax( HWND hWnd, LPARAM lParam )
+{
+ int bRet = FALSE;
+
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( pFrame->maFrameData.mbFullScreen )
+ {
+#ifdef WIN
+ MINMAXINFO* pMinMax = (MINMAXINFO*)lParam;
+ int nX;
+ int nY;
+ int nDX;
+ int nDY;
+ ImplSalCalcFullScreenSize( pFrame, nX, nY, nDX, nDY );
+
+ if ( pMinMax->ptMaxPosition.x > nX )
+ pMinMax->ptMaxPosition.x = nX;
+ if ( pMinMax->ptMaxPosition.y > nY )
+ pMinMax->ptMaxPosition.y = nY;
+
+ if ( pMinMax->ptMaxSize.x < nDX )
+ pMinMax->ptMaxSize.x = nDX;
+ if ( pMinMax->ptMaxSize.y < nDY )
+ pMinMax->ptMaxSize.y = nDY;
+ if ( pMinMax->ptMaxTrackSize.x < nDX )
+ pMinMax->ptMaxTrackSize.x = nDX;
+ if ( pMinMax->ptMaxTrackSize.y < nDY )
+ pMinMax->ptMaxTrackSize.y = nDY;
+
+ pMinMax->ptMinTrackSize.x = nDX;
+ pMinMax->ptMinTrackSize.y = nDY;
+
+ bRet = TRUE;
+#endif
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplHandleSysCommand( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ WPARAM nCommand = wParam & 0xFFF0;
+
+#ifdef WIN
+ if ( pFrame->maFrameData.mbFullScreen )
+ {
+ WIN_BOOL bMaximize = IsZoomed( pFrame->maFrameData.mhWnd );
+ WIN_BOOL bMinimize = IsIconic( pFrame->maFrameData.mhWnd );
+ if ( (nCommand == SC_SIZE) ||
+ (!bMinimize && (nCommand == SC_MOVE)) ||
+ (!bMaximize && (nCommand == SC_MAXIMIZE)) ||
+ (bMaximize && (nCommand == SC_RESTORE)) )
+ {
+ MessageBeep( 0 );
+ return TRUE;
+ }
+ }
+
+ if ( nCommand == SC_KEYMENU )
+ {
+ // Hier verarbeiten wir nur KeyMenu-Events fuer Alt um
+ // den MenuBar zu aktivieren, oder wenn ein SysChild-Fenster
+ // den Focus hat, da diese Alt+Tasten-Kombinationen nur
+ // ueber diesen Event verarbeitet werden
+ if ( !LOWORD( lParam ) )
+ {
+ // Nur ausloesen, wenn keine weitere Taste gedrueckt ist. Im
+ // Gegensatz zur Doku wird in der X-Koordinaate der CharCode
+ // geliefert, der zusaetzlich gedrueckt ist
+ // Also 32 fuer Space, 99 fuer c, 100 fuer d, ...
+ // Da dies nicht dokumentiert ist, fragen wir vorsichtshalber
+ // auch den Status der Space-Taste ab
+ if ( GetKeyState( VK_SPACE ) & 0x8000 )
+ return 0;
+
+ // Damit nicht bei Alt+Maustaste auch der MenuBar aktiviert wird
+ if ( (GetKeyState( VK_LBUTTON ) & 0x8000) ||
+ (GetKeyState( VK_RBUTTON ) & 0x8000) ||
+ (GetKeyState( VK_MBUTTON ) & 0x8000) )
+ return 1;
+
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode = KEY_MENU;
+ aKeyEvt.mnCharCode = 0;
+ aKeyEvt.mnRepeat = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return (nRet != 0);
+ }
+ else
+ {
+ // Testen, ob ein SysChild den Focus hat
+ HWND hFocusWnd = ::GetFocus();
+ if ( hFocusWnd && ImplFindSalObject( hFocusWnd ) )
+ {
+ char cKeyCode = (char)(unsigned char)LOWORD( lParam );
+ // LowerCase
+ if ( (cKeyCode >= 65) && (cKeyCode <= 90) )
+ cKeyCode += 32;
+ // Wir nehmen nur 0-9 und A-Z, alle anderen Tasten muessen durch
+ // den Hook vom SalObj verarbeitet werden
+ if ( ((cKeyCode >= 48) && (cKeyCode <= 57)) ||
+ ((cKeyCode >= 97) && (cKeyCode <= 122)) )
+ {
+ USHORT nModCode = 0;
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = GetMessageTime();
+ if ( (cKeyCode >= 48) && (cKeyCode <= 57) )
+ aKeyEvt.mnCode = KEY_0+(cKeyCode-48);
+ else
+ aKeyEvt.mnCode = KEY_A+(cKeyCode-97);
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = cKeyCode;
+ aKeyEvt.mnRepeat = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return (nRet != 0);
+ }
+ }
+ }
+ }
+#endif
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleInputLangChange( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ ImplSalYieldMutexAcquireWithWait();
+
+ // Feststellen, ob wir IME unterstuetzen
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbIME && pFrame->maFrameData.mhDefIMEContext )
+ {
+#ifdef WIN
+ HWND hWnd = pFrame->maFrameData.mhWnd;
+ HKL hKL = (HKL)lParam;
+ UINT nImeProps = ImmGetProperty( hKL, IGP_PROPERTY );
+
+ pFrame->maFrameData.mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
+ pFrame->maFrameData.mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
+ pFrame->maFrameData.mbHandleIME = !pFrame->maFrameData.mbSpezIME;
+#endif
+ }
+
+ ImplSalYieldMutexRelease();
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplHandleIMEStartComposition( HWND hWnd )
+{
+ BOOL bDef = TRUE;
+
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( pFrame->maFrameData.mbHandleIME )
+ {
+#ifdef WIN
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ // Cursor-Position ermitteln und aus der die Default-Position fuer
+ // das Composition-Fenster berechnen
+ SalCursorPosEvent aCursorPosEvt;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame, SALEVENT_CURSORPOS, (void*)&aCursorPosEvt );
+ COMPOSITIONFORM aForm;
+ memset( &aForm, 0, sizeof( aForm ) );
+ if ( !aCursorPosEvt.mnWidth || !aCursorPosEvt.mnHeight )
+ aForm.dwStyle |= CFS_DEFAULT;
+ else
+ {
+ aForm.dwStyle |= CFS_POINT;
+ aForm.ptCurrentPos.x = aCursorPosEvt.mnX;
+ aForm.ptCurrentPos.y = aCursorPosEvt.mnY;
+ }
+ ImmSetCompositionWindow( hIMC, &aForm );
+
+ // Den InputContect-Font ermitteln und diesem dem Composition-Fenster
+ // bekannt machen
+
+ ImmReleaseContext( hWnd, hIMC );
+ }
+
+ pFrame->maFrameData.mbCompositionMode = TRUE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_STARTEXTTEXTINPUT, (void*)NULL );
+ if ( pFrame->maFrameData.mbAtCursorIME )
+ bDef = FALSE;
+#endif
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+
+ return bDef;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplHandleIMEComposition( HWND hWnd, LPARAM lParam )
+{
+ BOOL bDef = TRUE;
+#ifdef WIN
+ if ( lParam & (GCS_RESULTSTR | GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS) )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbHandleIME &&
+ (pFrame->maFrameData.mbCompositionMode || !(lParam & GCS_RESULTSTR)) )
+ {
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ SalExtTextInputEvent aEvt;
+ aEvt.mnTime = GetMessageTime();
+ aEvt.mpTextAttr = NULL;
+ aEvt.mnCursorPos = 0;
+ aEvt.mnDeltaStart = 0;
+ aEvt.mbOnlyCursor = FALSE;
+ aEvt.mbCursorVisible = !pFrame->maFrameData.mbCandidateMode;
+
+ LONG nTextLen;
+ xub_Unicode* pTextBuf = NULL;
+ LONG nAttrLen;
+ WIN_BYTE* pAttrBuf = NULL;
+ BOOL bLastCursor = FALSE;
+ if ( lParam & GCS_RESULTSTR )
+ {
+ nTextLen = ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, 0, 0 ) / sizeof( wchar_t );
+ if ( nTextLen >= 0 )
+ {
+ pTextBuf = new xub_Unicode[nTextLen];
+ ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, pTextBuf, nTextLen*sizeof( wchar_t ) );
+ }
+
+ bLastCursor = TRUE;
+ aEvt.mbCursorVisible = TRUE;
+ bDef = FALSE;
+ }
+ else if ( pFrame->maFrameData.mbAtCursorIME )
+ {
+ bDef = FALSE;
+ if ( lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS) )
+ {
+ nTextLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 ) / sizeof( wchar_t );
+ if ( nTextLen >= 0 )
+ {
+ pTextBuf = new xub_Unicode[nTextLen];
+ ImmGetCompositionStringW( hIMC, GCS_COMPSTR, pTextBuf, nTextLen*sizeof( wchar_t ) );
+ }
+
+ nAttrLen = ImmGetCompositionStringW( hIMC, GCS_COMPATTR, 0, 0 );
+ if ( nAttrLen >= 0 )
+ {
+ pAttrBuf = new WIN_BYTE[nAttrLen];
+ ImmGetCompositionStringW( hIMC, GCS_COMPATTR, pAttrBuf, nAttrLen );
+ }
+
+ aEvt.mnCursorPos = LOWORD( ImmGetCompositionStringW( hIMC, GCS_CURSORPOS, 0, 0 ) );
+ aEvt.mnDeltaStart = LOWORD( ImmGetCompositionStringW( hIMC, GCS_DELTASTART, 0, 0 ) );
+
+ if ( lParam == GCS_CURSORPOS )
+ aEvt.mbOnlyCursor = TRUE;
+ }
+ }
+
+ USHORT* pSalAttrAry = NULL;
+ if ( pTextBuf )
+ {
+ aEvt.maText = XubString( pTextBuf, (USHORT)nTextLen );
+ delete pTextBuf;
+ if ( pAttrBuf )
+ {
+ xub_StrLen nTextLen = aEvt.maText.Len();
+ if ( nTextLen )
+ {
+ pSalAttrAry = new USHORT[nTextLen];
+ memset( pSalAttrAry, 0, nTextLen*sizeof( USHORT ) );
+ for ( xub_StrLen i = 0; (i < nTextLen) && (i < nAttrLen); i++ )
+ {
+ WIN_BYTE nWinAttr = pAttrBuf[i];
+ USHORT nSalAttr;
+ if ( nWinAttr == ATTR_TARGET_CONVERTED )
+ {
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETCONVERTED | SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
+ aEvt.mbCursorVisible = FALSE;
+ }
+ else if ( nWinAttr == ATTR_CONVERTED )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_CONVERTED | SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE;
+ else if ( nWinAttr == ATTR_TARGET_NOTCONVERTED )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETNOTCONVERTED | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ else if ( nWinAttr == ATTR_INPUT_ERROR )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUTERROR | SAL_EXTTEXTINPUT_ATTR_REDTEXT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ else /* ( nWinAttr == ATTR_INPUT ) */
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ pSalAttrAry[i] = nSalAttr;
+ }
+ aEvt.mpTextAttr = pSalAttrAry;
+ }
+ delete pAttrBuf;
+ }
+ if ( bLastCursor )
+ aEvt.mnCursorPos = aEvt.maText.Len();
+ }
+
+ ImmReleaseContext( hWnd, hIMC );
+
+ // Handler rufen und wenn wir ein Attribute-Array haben, danach
+ // wieder zerstoeren
+ if ( !bDef )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_EXTTEXTINPUT, (void*)&aEvt );
+ }
+ if ( pSalAttrAry )
+ delete pSalAttrAry;
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ }
+#endif
+
+ return bDef;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplHandleIMEEndComposition( HWND hWnd )
+{
+ BOOL bDef = TRUE;
+
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbHandleIME )
+ {
+#ifdef WIN
+ // Wir restaurieren den Background-Modus bei jeder Texteingabe,
+ // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
+ if ( pFrame->maFrameData.mpGraphics &&
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC )
+ SetBkMode( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC, TRANSPARENT );
+
+ pFrame->maFrameData.mbCompositionMode = FALSE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_ENDEXTTEXTINPUT, (void*)NULL );
+ if ( pFrame->maFrameData.mbAtCursorIME )
+ bDef = FALSE;
+#endif
+ }
+
+ ImplSalYieldMutexRelease();
+
+ return bDef;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleIMENotify( HWND hWnd, WPARAM wParam )
+{
+ if ( wParam == (WPARAM)IMN_OPENCANDIDATE )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbHandleIME &&
+ pFrame->maFrameData.mbAtCursorIME )
+ {
+#ifdef WIN
+ // Wir wollen den Cursor hiden
+ pFrame->maFrameData.mbCandidateMode = TRUE;
+ ImplHandleIMEComposition( hWnd, GCS_CURSORPOS );
+
+ HWND hWnd = pFrame->maFrameData.mhWnd;
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ LONG nBufLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 );
+ if ( nBufLen >= 1 )
+ {
+ USHORT nCursorPos = LOWORD( ImmGetCompositionStringW( hIMC, GCS_CURSORPOS, 0, 0 ) );
+ SalExtTextInputPosEvent aEvt;
+ aEvt.mnTime = GetMessageTime();
+ aEvt.mnFirstPos = nCursorPos;
+ aEvt.mnChars = nBufLen/sizeof(sal_Unicode) - nCursorPos;
+ aEvt.mpPosAry = new SalExtCharPos[aEvt.mnChars];
+ memset( aEvt.mpPosAry, 0, aEvt.mnChars*sizeof(SalExtCharPos) );
+
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_EXTTEXTINPUTPOS, (void*)&aEvt );
+
+ long nMinLeft = aEvt.mpPosAry[0].mnX;
+ long nMinTop = aEvt.mpPosAry[0].mnY;
+ long nMaxBottom = aEvt.mpPosAry[0].mnY+aEvt.mpPosAry[0].mnHeight;
+ long nMaxRight = nMinLeft;
+ USHORT i = 0;
+ while ( i < aEvt.mnChars )
+ {
+ // Solange wir uns auf der gleichen Zeile bewegen,
+ // ermitteln wir die Rechteck-Grenzen
+ if ( !aEvt.mpPosAry[i].mnHeight ||
+ (aEvt.mpPosAry[i].mnY < nMaxBottom-1) )
+ {
+ if ( aEvt.mpPosAry[i].mnX < nMinLeft )
+ nMinLeft = aEvt.mpPosAry[i].mnX;
+ if ( aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth > nMaxRight )
+ nMaxRight = aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth;
+ if ( aEvt.mpPosAry[i].mnY < nMinTop )
+ nMinTop = aEvt.mpPosAry[i].mnY;
+ i++;
+ }
+ else
+ break;
+ }
+
+ CANDIDATEFORM aForm;
+ aForm.dwIndex = 0;
+ aForm.dwStyle = CFS_EXCLUDE;
+ aForm.ptCurrentPos.x = aEvt.mpPosAry[0].mnX;
+ aForm.ptCurrentPos.y = nMaxBottom+1;
+ aForm.rcArea.left = nMinLeft;
+ aForm.rcArea.top = nMinTop;
+ aForm.rcArea.right = nMaxRight+1;
+ aForm.rcArea.bottom = nMaxBottom+1;
+ ImmSetCandidateWindow( hIMC, &aForm );
+
+ delete aEvt.mpPosAry;
+ }
+
+ ImmReleaseContext( hWnd, hIMC );
+ }
+#endif
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else if ( wParam == (WPARAM)IMN_CLOSECANDIDATE )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ pFrame->maFrameData.mbCandidateMode = FALSE;
+ ImplSalYieldMutexRelease();
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+void SalTestMouseLeave()
+{
+ SalData* pSalData = GetSalData();
+
+#ifdef WIN
+ if ( pSalData->mhWantLeaveMsg && !::GetCapture() )
+ {
+ POINT aPt;
+ GetCursorPos( &aPt );
+ if ( pSalData->mhWantLeaveMsg != WindowFromPoint( aPt ) )
+ ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MAKELPARAM( aPt.x, aPt.y ) );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplSalWheelMousePos( HWND hWnd, UINT nMsg, WPARAM wParam,
+ LPARAM lParam, LRESULT& rResult )
+{
+#ifdef WIN
+ POINT aPt;
+ POINT aScreenPt;
+ aScreenPt.x = (short)LOWORD( lParam );
+ aScreenPt.y = (short)HIWORD( lParam );
+ // Child-Fenster suchen, welches an der entsprechenden
+ // Position liegt
+ HWND hChildWnd;
+ HWND hWheelWnd = hWnd;
+ do
+ {
+ hChildWnd = hWheelWnd;
+ aPt = aScreenPt;
+ ScreenToClient( hChildWnd, &aPt );
+ hWheelWnd = ChildWindowFromPointEx( hChildWnd, aPt, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT );
+ }
+ while ( hWheelWnd && (hWheelWnd != hChildWnd) );
+ if ( hWheelWnd && (hWheelWnd != hWnd) &&
+ (hWheelWnd != ::GetFocus()) && IsWindowEnabled( hWheelWnd ) )
+ {
+ rResult = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam );
+ return FALSE;
+ }
+#endif
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ LRESULT nRet = 0;
+#ifdef WIN
+ static int bInWheelMsg = FALSE;
+
+ // By WM_CRETAE we connect the frame with the window handle
+ if ( nMsg == WM_CREATE )
+ {
+ // Window-Instanz am Windowhandle speichern
+ // Can also be used for the W-Version, because the struct
+ // to access lpCreateParams is the same structure
+ CREATESTRUCTA* pStruct = (CREATESTRUCTA*)lParam;
+ SalFrame* pFrame = (SalFrame*)pStruct->lpCreateParams;
+ SetWindowPtr( hWnd, pFrame );
+ // HWND schon hier setzen, da schon auf den Instanzdaten
+ // gearbeitet werden kann, wenn Messages waehrend
+ // CreateWindow() gesendet werden
+ pFrame->maFrameData.mhWnd = hWnd;
+ pFrame->maFrameData.maSysData.hWnd = hWnd;
+ return 0;
+ }
+
+ switch( nMsg )
+ {
+ case WM_MOUSEMOVE:
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_MBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_NCMOUSEMOVE:
+ case SAL_MSG_MOUSELEAVE:
+ ImplSalYieldMutexAcquireWithWait();
+ rDef = !ImplHandleMouseMsg( hWnd, nMsg, wParam, lParam );
+ ImplSalYieldMutexRelease();
+ break;
+
+ case WM_MOUSEACTIVATE:
+ if ( LOWORD( lParam ) == HTCLIENT )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ nRet = ImplHandleMouseActivateMsg( hWnd );
+ ImplSalYieldMutexRelease();
+ if ( nRet )
+ {
+ nRet = MA_NOACTIVATE;
+ rDef = FALSE;
+ }
+ }
+ break;
+
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_DEADCHAR:
+ case WM_CHAR:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_SYSCHAR:
+ ImplSalYieldMutexAcquireWithWait();
+ rDef = !ImplHandleKeyMsg( hWnd, nMsg, wParam, lParam );
+ ImplSalYieldMutexRelease();
+ break;
+
+ case WM_MOUSEWHEEL:
+ // Gegen Rekursion absichern, falls wir vom IE oder dem externen
+ // Fenster die Message wieder zurueckbekommen
+ if ( !bInWheelMsg )
+ {
+ bInWheelMsg++;
+ rDef = !ImplHandleWheelMsg( hWnd, wParam, lParam );
+ // Wenn wir die Message nicht ausgewertet haben, schauen wir
+ // noch einmal nach, ob dort ein geplugtes Fenster steht,
+ // welches wir dann benachrichtigen
+ if ( rDef )
+ rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet );
+ bInWheelMsg--;
+ }
+ break;
+
+ case WM_SYSCOMMAND:
+ ImplSalYieldMutexAcquireWithWait();
+ nRet = ImplHandleSysCommand( hWnd, wParam, lParam );
+ ImplSalYieldMutexRelease();
+ if ( nRet )
+ rDef = FALSE;
+ break;
+
+ case WM_MOVE:
+ case SAL_MSG_POSTMOVE:
+ ImplHandleMoveMsg( hWnd );
+ rDef = FALSE;
+ break;
+ case WM_SIZE:
+ ImplHandleSizeMsg( hWnd, wParam, lParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_POSTCALLSIZE:
+ ImplCallSizeHdl( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_GETMINMAXINFO:
+ if ( ImplHandleMinMax( hWnd, lParam ) )
+ rDef = FALSE;
+ break;
+
+ case WM_ERASEBKGND:
+ nRet = 1;
+ rDef = FALSE;
+ break;
+ case WM_PAINT:
+ ImplHandlePaintMsg( hWnd );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_POSTPAINT:
+ ImplHandlePaintMsg2( hWnd, (RECT*)wParam );
+ rDef = FALSE;
+ break;
+
+ case SAL_MSG_FORCEPALETTE:
+ ImplHandleForcePalette( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_QUERYNEWPALETTE:
+ case SAL_MSG_POSTQUERYNEWPAL:
+ nRet = ImplHandlePalette( TRUE, hWnd, nMsg, wParam, lParam, rDef );
+ break;
+
+ case WM_ACTIVATE:
+ // Wenn wir aktiviert werden, dann wollen wir auch unsere
+ // Palette setzen. Wir machen dieses in Activate,
+ // damit andere externe Child-Fenster auch unsere Palette
+ // ueberschreiben koennen. So wird unsere jedenfalls nur einmal
+ // gesetzt und nicht immer rekursiv, da an allen anderen Stellen
+ // diese nur als Background-Palette gesetzt wird
+ if ( LOWORD( wParam ) != WA_INACTIVE )
+ ImplSendMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 );
+ break;
+
+ case WM_SETFOCUS:
+ case WM_KILLFOCUS:
+ case SAL_MSG_POSTFOCUS:
+ ImplHandleFocusMsg( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_CLOSE:
+ ImplHandleCloseMsg( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_QUERYENDSESSION:
+ nRet = !ImplHandleShutDownMsg( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_DISPLAYCHANGE:
+ case WM_SETTINGCHANGE:
+ case WM_DEVMODECHANGE:
+ case WM_FONTCHANGE:
+ case WM_SYSCOLORCHANGE:
+ case WM_TIMECHANGE:
+ ImplHandleSettingsChangeMsg( hWnd, nMsg, wParam, lParam );
+ break;
+
+ case SAL_MSG_USEREVENT:
+ ImplHandleUserEvent( hWnd, lParam );
+ rDef = FALSE;
+ break;
+
+ case SAL_MSG_CAPTUREMOUSE:
+ SetCapture( hWnd );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_RELEASEMOUSE:
+ if ( ::GetCapture() == hWnd )
+ ReleaseCapture();
+ rDef = FALSE;
+ break;
+ case SAL_MSG_TOTOP:
+ ImplSalToTop( hWnd, (USHORT)wParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_SHOW:
+ ImplSalShow( hWnd, (BOOL)wParam );
+ rDef = FALSE;
+ break;
+
+ case WM_INPUTLANGCHANGE:
+ ImplHandleInputLangChange( hWnd, wParam, lParam );
+ break;
+
+ case WM_IME_STARTCOMPOSITION:
+ rDef = ImplHandleIMEStartComposition( hWnd );
+ break;
+
+ case WM_IME_COMPOSITION:
+ rDef = ImplHandleIMEComposition( hWnd, lParam );
+ break;
+
+ case WM_IME_ENDCOMPOSITION:
+ rDef = ImplHandleIMEEndComposition( hWnd );
+ break;
+
+ case WM_IME_NOTIFY:
+ ImplHandleIMENotify( hWnd, wParam );
+ break;
+ }
+
+ // WheelMouse-Message abfangen
+ if ( rDef && (nMsg == aSalShlData.mnWheelMsgId) && aSalShlData.mnWheelMsgId )
+ {
+ // Gegen Rekursion absichern, falls wir vom IE oder dem externen
+ // Fenster die Message wieder zurueckbekommen
+ if ( !bInWheelMsg )
+ {
+ bInWheelMsg++;
+ // Zuerst wollen wir die Message dispatchen und dann darf auch
+ // das SystemWindow drankommen
+ WORD nKeyState = 0;
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nKeyState |= MK_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nKeyState |= MK_CONTROL;
+ // Mutex handling is inside from this call
+ rDef = !ImplHandleWheelMsg( hWnd, MAKEWPARAM( nKeyState, (WORD)wParam ), lParam );
+ if ( rDef )
+ {
+ HWND hWheelWnd = ::GetFocus();
+ if ( hWheelWnd && (hWheelWnd != hWnd) )
+ {
+ nRet = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam );
+ rDef = FALSE;
+ }
+ else
+ rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet );
+ }
+ bInWheelMsg--;
+ }
+ }
+#endif
+
+ return nRet;
+}
+
+#ifdef WIN
+LRESULT CALLBACK SalFrameWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+#endif
+
+#ifdef WIN
+LRESULT CALLBACK SalFrameWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+BOOL ImplHandleGlobalMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT& rlResult )
+{
+#ifdef WIN
+ // Hier verarbeiten wir alle Messages, die fuer alle Frame-Fenster gelten,
+ // damit diese nur einmal verarbeitet werden
+ // Must work for Unicode and none Unicode
+ if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) )
+ {
+ int bDef = TRUE;
+ rlResult = ImplHandlePalette( FALSE, hWnd, nMsg, wParam, lParam, bDef );
+ return (bDef != 0);
+ }
+ else
+#endif
+ return FALSE;
+}
diff --git a/vcl/aqua/source/window/salobj.cxx b/vcl/aqua/source/window/salobj.cxx
new file mode 100644
index 000000000000..69d98b87bbd2
--- /dev/null
+++ b/vcl/aqua/source/window/salobj.cxx
@@ -0,0 +1,858 @@
+/*************************************************************************
+ *
+ * $RCSfile: salobj.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#ifndef _SVWIN_HXX
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALOBJ_CXX
+
+#ifndef _SV_SALAQUA_HXX
+#include <salaqua.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// =======================================================================
+
+static BOOL ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild )
+{
+ if ( hWndParent == hWndChild )
+ return TRUE;
+
+#ifdef WIN
+ HWND hTempWnd = ::GetParent( hWndChild );
+ while ( hTempWnd )
+ {
+ // Ab nicht Child-Fenstern hoeren wir auf zu suchen
+ if ( !(GetWindowStyle( hTempWnd ) & WS_CHILD) )
+ return FALSE;
+ if ( hTempWnd == hWndParent )
+ return TRUE;
+ hTempWnd = ::GetParent( hTempWnd );
+ }
+#endif
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SalObject* ImplFindSalObject( HWND hWndChild )
+{
+ SalData* pSalData = GetSalData();
+ SalObject* pObject = pSalData->mpFirstObject;
+ while ( pObject )
+ {
+ if ( ImplIsSysWindowOrChild( pObject->maObjectData.mhWndChild, hWndChild ) )
+ return pObject;
+
+ pObject = pObject->maObjectData.mpNextObject;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* ImplFindSalObjectFrame( HWND hWnd )
+{
+ SalFrame* pFrame = NULL;
+ SalObject* pObject = ImplFindSalObject( hWnd );
+ if ( pObject )
+ {
+#ifdef WIN
+ // Dazugehoerenden Frame suchen
+ HWND hWnd = ::GetParent( pObject->maObjectData.mhWnd );
+ pFrame = GetSalData()->mpFirstFrame;
+ while ( pFrame )
+ {
+ if ( pFrame->maFrameData.mhWnd == hWnd )
+ break;
+
+ pFrame = pFrame->maFrameData.mpNextFrame;
+ }
+#endif
+ }
+
+ return pFrame;
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalSysMsgProc( int nCode, WPARAM wParam, LPARAM lParam )
+{
+ // Used for Unicode and none Unicode
+ SalData* pSalData = GetSalData();
+
+#ifdef WIN
+ if ( (nCode >= 0) && lParam )
+ {
+ CWPSTRUCT* pData = (CWPSTRUCT*)lParam;
+ if ( (pData->message != WM_KEYDOWN) &&
+ (pData->message != WM_KEYUP) )
+ pSalData->mnSalObjWantKeyEvt = 0;
+
+ // Testen, ob wir Daten fuer ein SalObject-Fenster behandeln
+ // muessen
+ SalObject* pObject;
+ if ( pData->message == WM_SETFOCUS )
+ {
+ pObject = ImplFindSalObject( pData->hwnd );
+ if ( pObject )
+ {
+ pObject->maObjectData.mhLastFocusWnd = pData->hwnd;
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pObject->maObjectData.mpProc( pObject->maObjectData.mpInst, pObject,
+ SALOBJ_EVENT_GETFOCUS, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( pObject->maObjectData.mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
+ }
+ }
+ else if ( pData->message == WM_KILLFOCUS )
+ {
+ pObject = ImplFindSalObject( pData->hwnd );
+ if ( pObject && !ImplFindSalObject( (HWND)pData->wParam ) )
+ {
+ // LoseFocus nur rufen, wenn wirklich kein ChildFenster
+ // den Focus bekommt
+ if ( !pData->wParam || !ImplFindSalObject( (HWND)pData->wParam ) )
+ {
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pObject->maObjectData.mpProc( pObject->maObjectData.mpInst, pObject,
+ SALOBJ_EVENT_LOSEFOCUS, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( pObject->maObjectData.mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
+ }
+ else
+ pObject->maObjectData.mhLastFocusWnd = (HWND)pData->wParam;
+ }
+ }
+ }
+
+ return CallNextHookEx( pSalData->mhSalObjMsgHook, nCode, wParam, lParam );
+#else
+ return 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+BOOL ImplSalPreDispatchMsg( MSG* pMsg )
+{
+ // Used for Unicode and none Unicode
+ SalData* pSalData = GetSalData();
+ SalObject* pObject;
+
+ if ( (pMsg->message == WM_LBUTTONDOWN) ||
+ (pMsg->message == WM_RBUTTONDOWN) ||
+ (pMsg->message == WM_MBUTTONDOWN) )
+
+ ImplSalYieldMutexAcquireWithWait();
+ pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ ImplPostMessage( pObject->maObjectData.mhWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ ImplSalYieldMutexRelease();
+ }
+
+ if ( (pMsg->message == WM_KEYDOWN) ||
+ (pMsg->message == WM_KEYUP) )
+ {
+ // KeyEvents wollen wir nach Moeglichkeit auch abarbeiten,
+ // wenn das Control diese nicht selber auswertet
+ // SysKeys werden als WM_SYSCOMMAND verarbeitet
+ // Char-Events verarbeiten wir nicht, da wir nur
+ // Accelerator relevante Keys verarbeiten wollen
+ BOOL bWantedKeyCode = FALSE;
+ // A-Z, 0-9 nur in Verbindung mit Control-Taste
+ if ( ((pMsg->wParam >= 65) && (pMsg->wParam <= 90)) ||
+ ((pMsg->wParam >= 48) && (pMsg->wParam <= 57)) )
+ {
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ bWantedKeyCode = TRUE;
+ }
+ else if ( ((pMsg->wParam >= VK_F1) && (pMsg->wParam <= VK_F24)) ||
+ ((pMsg->wParam >= VK_SPACE) && (pMsg->wParam <= VK_HELP)) ||
+ (pMsg->wParam == VK_BACK) || (pMsg->wParam == VK_TAB) ||
+ (pMsg->wParam == VK_CLEAR) || (pMsg->wParam == VK_RETURN) ||
+ (pMsg->wParam == VK_ESCAPE) )
+ bWantedKeyCode = TRUE;
+ if ( bWantedKeyCode )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ pSalData->mnSalObjWantKeyEvt = pMsg->wParam;
+ ImplSalYieldMutexRelease();
+ }
+ }
+ // Hier WM_SYSCHAR abfangen, um mit Alt+Taste evtl. Menu zu aktivieren
+ else if ( pMsg->message == WM_SYSCHAR )
+ {
+ pSalData->mnSalObjWantKeyEvt = 0;
+
+ USHORT nKeyCode = LOWORD( pMsg->wParam );
+ // Nur 0-9 und A-Z
+ if ( ((nKeyCode >= 48) && (nKeyCode <= 57)) ||
+ ((nKeyCode >= 65) && (nKeyCode <= 90)) ||
+ ((nKeyCode >= 97) && (nKeyCode <= 122)) )
+ {
+ BOOL bRet = FALSE;
+ ImplSalYieldMutexAcquireWithWait();
+ pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ {
+ if ( pMsg->hwnd == ::GetFocus() )
+ {
+ SalFrame* pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
+ if ( pFrame )
+ {
+ if ( ImplHandleSalObjSysCharMsg( pFrame->maFrameData.mhWnd, pMsg->wParam, pMsg->lParam ) )
+ bRet = TRUE;
+ }
+ }
+ }
+ ImplSalYieldMutexRelease();
+ if ( bRet )
+ return TRUE;
+ }
+ }
+ else
+ pSalData->mnSalObjWantKeyEvt = 0;
+
+ return FALSE;
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+#ifdef WIN
+void ImplSalPostDispatchMsg( MSG* pMsg, LRESULT /* nDispatchResult */ )
+{
+ // Used for Unicode and none Unicode
+ SalData* pSalData = GetSalData();
+ SalFrame* pFrame;
+
+ if ( (pMsg->message == WM_KEYDOWN) || (pMsg->message == WM_KEYUP) )
+ {
+ if ( pSalData->mnSalObjWantKeyEvt == pMsg->wParam )
+ {
+ pSalData->mnSalObjWantKeyEvt = 0;
+ if ( pMsg->hwnd == ::GetFocus() )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
+ if ( pFrame )
+ ImplHandleSalObjKeyMsg( pFrame->maFrameData.mhWnd, pMsg->message, pMsg->wParam, pMsg->lParam );
+ ImplSalYieldMutexRelease();
+ }
+ }
+ }
+
+ pSalData->mnSalObjWantKeyEvt = 0;
+}
+#endif
+
+// =======================================================================
+
+LRESULT CALLBACK SalSysObjWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ SalObject* pSysObj;
+ LRESULT nRet = 0;
+
+#ifdef WIN
+ switch( nMsg )
+ {
+ case WM_ERASEBKGND:
+ nRet = 1;
+ rDef = FALSE;
+ break;
+ case WM_PAINT:
+ {
+ PAINTSTRUCT aPs;
+ BeginPaint( hWnd, &aPs );
+ EndPaint( hWnd, &aPs );
+ rDef = FALSE;
+ }
+ break;
+
+ case WM_PARENTNOTIFY:
+ {
+ UINT nNotifyMsg = LOWORD( wParam );
+ if ( (nNotifyMsg == WM_LBUTTONDOWN) ||
+ (nNotifyMsg == WM_RBUTTONDOWN) ||
+ (nNotifyMsg == WM_MBUTTONDOWN) )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ if ( pSysObj )
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj, SALOBJ_EVENT_TOTOP, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ }
+ break;
+
+ case WM_MOUSEACTIVATE:
+ ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ break;
+
+ case SALOBJ_MSG_TOTOP:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj,
+ SALOBJ_EVENT_TOTOP, 0 );
+ ImplSalYieldMutexRelease();
+ rDef = FALSE;
+ }
+ else
+ ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ break;
+
+ case SALOBJ_MSG_POSTFOCUS:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ HWND hFocusWnd = ::GetFocus();
+ USHORT nEvent;
+ if ( hFocusWnd && ImplIsSysWindowOrChild( hWnd, hFocusWnd ) )
+ nEvent = SALOBJ_EVENT_GETFOCUS;
+ else
+ nEvent = SALOBJ_EVENT_LOSEFOCUS;
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj,
+ nEvent, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
+ rDef = FALSE;
+ break;
+
+ case WM_SIZE:
+ {
+ HWND hWndChild = GetWindow( hWnd, GW_CHILD );
+ if ( hWndChild )
+ {
+ SetWindowPos( hWndChild,
+ 0, 0, 0, (int)LOWORD( lParam ), (int)HIWORD( lParam ),
+ SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+ }
+ rDef = FALSE;
+ break;
+
+ case WM_CREATE:
+ {
+ // Window-Instanz am Windowhandle speichern
+ // Can also be used for the W-Version, because the struct
+ // to access lpCreateParams is the same structure
+ CREATESTRUCTA* pStruct = (CREATESTRUCTA*)lParam;
+ pSysObj = (SalObject*)pStruct->lpCreateParams;
+ SetSalObjWindowPtr( hWnd, pSysObj );
+ // HWND schon hier setzen, da schon auf den Instanzdaten
+ // gearbeitet werden kann, wenn Messages waehrend
+ // CreateWindow() gesendet werden
+ pSysObj->maObjectData.mhWnd = hWnd;
+ rDef = FALSE;
+ }
+ break;
+ }
+#endif
+
+ return nRet;
+}
+
+#ifdef WIN
+LRESULT CALLBACK SalSysObjWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+#endif
+
+#ifdef WIN
+LRESULT CALLBACK SalSysObjWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalSysObjChildWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ LRESULT nRet = 0;
+
+#ifdef WIN
+ switch( nMsg )
+ {
+ // Wegen PlugIn's loeschen wir erstmal den Hintergrund
+ case WM_ERASEBKGND:
+ nRet = 1;
+ rDef = FALSE;
+ break;
+ case WM_PAINT:
+ {
+ PAINTSTRUCT aPs;
+ BeginPaint( hWnd, &aPs );
+ EndPaint( hWnd, &aPs );
+ rDef = FALSE;
+ }
+ break;
+ }
+#endif
+
+ return nRet;
+}
+
+#ifdef WIN
+LRESULT CALLBACK SalSysObjChildWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjChildWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+#endif
+
+#ifdef WIN
+LRESULT CALLBACK SalSysObjChildWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjChildWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+#endif
+
+// =======================================================================
+
+SalObject* ImplSalCreateObject( SalInstance* pInst, SalFrame* pParent )
+{
+ SalData* pSalData = GetSalData();
+
+#ifdef WIN
+ // Hook installieren, wenn es das erste SalObject ist
+ if ( !pSalData->mpFirstObject )
+ {
+ pSalData->mhSalObjMsgHook = SetWindowsHookExA( WH_CALLWNDPROC,
+ SalSysMsgProc,
+ pSalData->mhInst,
+ pSalData->mnAppThreadId );
+ }
+
+ if ( !pSalData->mbObjClassInit )
+ {
+ WNDCLASSEXA aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalSysObjWndProcA;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_OBJECT_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.hCursor = LoadCursor( 0, IDC_ARROW );
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CLASSNAMEA;
+ if ( RegisterClassExA( &aWndClassEx ) )
+ {
+ // Wegen PlugIn's loeschen wir erstmal den Hintergrund
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ aWndClassEx.lpfnWndProc = SalSysObjChildWndProcA;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CHILDCLASSNAMEA;
+ if ( RegisterClassExA( &aWndClassEx ) )
+ pSalData->mbObjClassInit = TRUE;
+ }
+ }
+#endif
+
+ if ( pSalData->mbObjClassInit )
+ {
+#ifdef WIN
+ SalObject* pObject = new SalObject;
+ HWND hWnd;
+ HWND hWndChild = 0;
+ hWnd = CreateWindowExA( 0, SAL_OBJECT_CLASSNAMEA, "", WS_CHILD, 0, 0, 0, 0, pParent->maFrameData.mhWnd, 0, pInst->maInstData.mhInst, (void*)pObject );
+ if ( hWnd )
+ {
+ hWndChild = CreateWindowExA( 0, SAL_OBJECT_CHILDCLASSNAMEA, "", WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE, 0, 0, 0, 0, hWnd, 0, pInst->maInstData.mhInst, NULL );
+ }
+ }
+ if ( !hWndChild )
+ {
+ delete pObject;
+ return NULL;
+ }
+
+ if ( hWnd )
+ {
+ pObject->maObjectData.mhWnd = hWnd;
+ pObject->maObjectData.mhWndChild = hWndChild;
+ pObject->maObjectData.maSysData.hWnd = hWndChild;
+ return pObject;
+ }
+#endif
+ }
+
+ return NULL;
+}
+
+// =======================================================================
+
+long ImplSalObjCallbackDummy( void*, SalObject*, USHORT, const void* )
+{
+ return 0;
+}
+
+// =======================================================================
+
+SalObject::SalObject()
+{
+ SalData* pSalData = GetSalData();
+
+ maObjectData.mhWnd = 0;
+ maObjectData.mhWndChild = 0;
+ maObjectData.mhLastFocusWnd = 0;
+ maObjectData.maSysData.nSize = sizeof( SystemEnvData );
+ maObjectData.mpInst = NULL;
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+#ifdef WIN
+ maObjectData.mpStdClipRgnData = NULL;
+#endif
+
+ // Insert object in objectlist
+ maObjectData.mpNextObject = pSalData->mpFirstObject;
+ pSalData->mpFirstObject = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalObject::~SalObject()
+{
+ SalData* pSalData = GetSalData();
+
+ // remove frame from framelist
+ if ( this == pSalData->mpFirstObject )
+ {
+ pSalData->mpFirstObject = maObjectData.mpNextObject;
+
+#ifdef WIN
+ // Wenn letztes SalObject, dann Hook wieder entfernen
+ if ( !pSalData->mpFirstObject )
+ UnhookWindowsHookEx( pSalData->mhSalObjMsgHook );
+#endif
+ }
+ else
+ {
+ SalObject* pTempObject = pSalData->mpFirstObject;
+ while ( pTempObject->maObjectData.mpNextObject != this )
+ pTempObject = pTempObject->maObjectData.mpNextObject;
+
+ pTempObject->maObjectData.mpNextObject = maObjectData.mpNextObject;
+ }
+
+#ifdef WIN
+ // Cache-Daten zerstoeren
+ if ( maObjectData.mpStdClipRgnData )
+ delete maObjectData.mpStdClipRgnData;
+
+ HWND hWndParent = ::GetParent( maObjectData.mhWnd );
+
+ if ( maObjectData.mhWndChild )
+ DestroyWindow( maObjectData.mhWndChild );
+ if ( maObjectData.mhWnd )
+ DestroyWindow( maObjectData.mhWnd );
+
+ // Palette wieder zuruecksetzen, wenn kein externes Child-Fenster
+ // mehr vorhanden ist, da diese unsere Palette ueberschrieben haben
+ // koennen
+ if ( hWndParent &&
+ ::GetActiveWindow() == hWndParent &&
+ !GetWindow( hWndParent, GW_CHILD ) )
+ ImplSendMessage( hWndParent, SAL_MSG_FORCEPALETTE, 0, 0 );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::ResetClipRegion()
+{
+#ifdef WIN
+ SetWindowRgn( maObjectData.mhWnd, 0, TRUE );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalObject::GetClipRegionType()
+{
+ return SAL_OBJECT_CLIP_INCLUDERECTS;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::BeginSetClipRegion( ULONG nRectCount )
+{
+#ifdef WIN
+ ULONG nRectBufSize = sizeof(RECT)*nRectCount;
+ if ( nRectCount < SAL_CLIPRECT_COUNT )
+ {
+ if ( !maObjectData.mpStdClipRgnData )
+ maObjectData.mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
+ maObjectData.mpClipRgnData = maObjectData.mpStdClipRgnData;
+ }
+ else
+ maObjectData.mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
+ maObjectData.mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
+ maObjectData.mpClipRgnData->rdh.iType = RDH_RECTANGLES;
+ maObjectData.mpClipRgnData->rdh.nCount = nRectCount;
+ maObjectData.mpClipRgnData->rdh.nRgnSize = nRectBufSize;
+ SetRectEmpty( &(maObjectData.mpClipRgnData->rdh.rcBound) );
+ maObjectData.mpNextClipRect = (RECT*)(&(maObjectData.mpClipRgnData->Buffer));
+ maObjectData.mbFirstClipRect = TRUE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+#ifdef WIN
+ RECT* pRect = maObjectData.mpNextClipRect;
+ RECT* pBoundRect = &(maObjectData.mpClipRgnData->rdh.rcBound);
+ long nRight = nX + nWidth;
+ long nBottom = nY + nHeight;
+
+ if ( maObjectData.mbFirstClipRect )
+ {
+ pBoundRect->left = nX;
+ pBoundRect->top = nY;
+ pBoundRect->right = nRight;
+ pBoundRect->bottom = nBottom;
+ maObjectData.mbFirstClipRect = FALSE;
+ }
+ else
+ {
+ if ( nX < pBoundRect->left )
+ pBoundRect->left = (int)nX;
+
+ if ( nY < pBoundRect->top )
+ pBoundRect->top = (int)nY;
+
+ if ( nRight > pBoundRect->right )
+ pBoundRect->right = (int)nRight;
+
+ if ( nBottom > pBoundRect->bottom )
+ pBoundRect->bottom = (int)nBottom;
+ }
+
+ pRect->left = (int)nX;
+ pRect->top = (int)nY;
+ pRect->right = (int)nRight;
+ pRect->bottom = (int)nBottom;
+ maObjectData.mpNextClipRect++;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::EndSetClipRegion()
+{
+#ifdef WIN
+ HRGN hRegion;
+
+ // Aus den Region-Daten muessen wir jetzt eine ClipRegion erzeugen
+ if ( maObjectData.mpClipRgnData->rdh.nCount == 1 )
+ {
+ RECT* pRect = &(maObjectData.mpClipRgnData->rdh.rcBound);
+ hRegion = CreateRectRgn( pRect->left, pRect->top,
+ pRect->right, pRect->bottom );
+ }
+ else
+ {
+ ULONG nSize = maObjectData.mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
+ hRegion = ExtCreateRegion( NULL, nSize, maObjectData.mpClipRgnData );
+ if ( maObjectData.mpClipRgnData != maObjectData.mpStdClipRgnData )
+ delete maObjectData.mpClipRgnData;
+ }
+
+ DBG_ASSERT( hRegion, "SalObject::EndSetClipRegion() - Can't create ClipRegion" );
+ SetWindowRgn( maObjectData.mhWnd, hRegion, TRUE );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
+{
+#ifdef WIN
+ ULONG nStyle = 0;
+ BOOL bVisible = (GetWindowStyle( maObjectData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( bVisible )
+ {
+ ShowWindow( maObjectData.mhWnd, SW_HIDE );
+ nStyle |= SWP_SHOWWINDOW;
+ }
+ SetWindowPos( maObjectData.mhWnd, 0,
+ (int)nX, (int)nY, (int)nWidth, (int)nHeight,
+ SWP_NOZORDER | SWP_NOACTIVATE | nStyle );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::Show( BOOL bVisible )
+{
+#ifdef WIN
+ if ( bVisible )
+ ShowWindow( maObjectData.mhWnd, SW_SHOWNORMAL );
+ else
+ ShowWindow( maObjectData.mhWnd, SW_HIDE );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::Enable( BOOL bEnable )
+{
+#ifdef WIN
+ EnableWindow( maObjectData.mhWnd, bEnable );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::GrabFocus()
+{
+#ifdef WIN
+ if ( maObjectData.mhLastFocusWnd &&
+ IsWindow( maObjectData.mhLastFocusWnd ) &&
+ ImplIsSysWindowOrChild( maObjectData.mhWndChild, maObjectData.mhLastFocusWnd ) )
+ ::SetFocus( maObjectData.mhLastFocusWnd );
+ else
+ ::SetFocus( maObjectData.mhWndChild );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground( SalColor nSalColor )
+{
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* SalObject::GetSystemData() const
+{
+ return &maObjectData.maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc )
+{
+ maObjectData.mpInst = pInst;
+ if ( pProc )
+ maObjectData.mpProc = pProc;
+ else
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+}
diff --git a/vcl/os2/inc/saldata.hxx b/vcl/os2/inc/saldata.hxx
new file mode 100644
index 000000000000..fb835f8a45cd
--- /dev/null
+++ b/vcl/os2/inc/saldata.hxx
@@ -0,0 +1,278 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldata.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALDATA_HXX
+#define _SV_SALDATA_HXX
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SALWTYPE_HXX
+#include <salwtype.hxx>
+#endif
+
+class SalFrame;
+class SalObject;
+
+// --------------
+// - SalIMEData -
+// --------------
+
+#define ENABLE_IME
+
+#ifdef ENABLE_IME
+
+struct SalIMEData;
+
+#ifdef OS2IM_INCLUDED
+
+typedef APIRET (APIENTRY ImAssociateInstanceFunc)( HWND hwnd, HIMI himi, PHIMI phimiPrev );
+typedef APIRET (APIENTRY ImGetInstanceFunc)( HWND hwnd, PHIMI phimi );
+typedef APIRET (APIENTRY ImReleaseInstanceFunc)( HWND hwnd, HIMI himi );
+typedef APIRET (APIENTRY ImSetConversionFontFunc)( HIMI himi, PFATTRS pFontAttrs );
+typedef APIRET (APIENTRY ImSetConversionFontSizeFunc)( HIMI himi, PSIZEF psizfxBox );
+typedef APIRET (APIENTRY ImGetConversionStringFunc)( HIMI himi, ULONG ulIndex, PVOID pBuf, PULONG pulBufLen );
+typedef APIRET (APIENTRY ImGetResultStringFunc)( HIMI himi, ULONG ulIndex, PVOID pBuf, PULONG pulBufLen );
+typedef APIRET (APIENTRY ImSetCandidateWindowPosFunc)( HIMI himi, PCANDIDATEPOS pCandidatePos );
+typedef APIRET (APIENTRY ImQueryIMEPropertyFunc)( HIMI himi, ULONG ulIndex, PULONG pulProp );
+typedef APIRET (APIENTRY ImRequestIMEFunc)( HIMI himi, ULONG ulAction, ULONG ulIndex, ULONG ulValue );
+typedef APIRET (APIENTRY ImSetIMModeFunc)( HIMI himi, ULONG ulInputMode, ULONG ulConversionMode );
+typedef APIRET (APIENTRY ImQueryIMModeFunc)( HIMI himi, PULONG pulInputMode, PULONG pulConversionMode );
+
+struct SalIMEData
+{
+ HMODULE mhModIME;
+ ImAssociateInstanceFunc* mpAssocIME;
+ ImGetInstanceFunc* mpGetIME;
+ ImReleaseInstanceFunc* mpReleaseIME;
+ ImSetConversionFontFunc* mpSetConversionFont;
+ ImSetConversionFontSizeFunc* mpSetConversionFontSize;
+ ImGetConversionStringFunc* mpGetConversionString;
+ ImGetResultStringFunc* mpGetResultString;
+ ImSetCandidateWindowPosFunc* mpSetCandidateWin;
+ ImQueryIMEPropertyFunc* mpQueryIMEProperty;
+ ImRequestIMEFunc* mpRequestIME;
+ ImSetIMModeFunc* mpSetIMEMode;
+ ImQueryIMModeFunc* mpQueryIMEMode;
+};
+
+#endif
+
+#endif
+
+// -----------
+// - SalData -
+// -----------
+
+struct SalData
+{
+ HAB mhAB; // anchor block handle
+ HMQ mhMQ; // handle of os2 message queue
+ int mnArgc; // commandline param count
+ char** mpArgv; // commandline
+ ULONG mnNewTimerMS; // Neue Zeit, mit dem der Timer gestartet werden soll
+ PM_ULONG mnTimerId; // os2 timer id
+ SALTIMERPROC mpTimerProc; // timer callback proc
+ HWND mhWantLeaveMsg; // window handle, that want a MOUSELEAVE message
+ AutoTimer* mpMouseLeaveTimer; // Timer for MouseLeave Test
+ SalInstance* mpFirstInstance; // pointer of first instance
+ SalFrame* mpFirstFrame; // pointer of first frame
+ SalFrame* mpDummyFrame; // Dummy-Frame
+ SalFrame* mpCreateFrame; // Create-Frame for WM_CREATE
+ SalFrame* mpDefaultFrame; // Default-Frame (App-Fenster)
+ SalObject* mpFirstObject; // pointer of first object window
+ ULONG mnAppThreadId; // Id from Applikation-Thread
+ ULONG mnFontMetricCount; // number of entries in the font list
+ PFONTMETRICS mpFontMetrics; // cached font list
+ BOOL mbObjClassInit; // Ist SALOBJECTCLASS initialised
+#ifdef ENABLE_IME
+ SalIMEData* mpIMEData; // SalIME-Data
+ BOOL mbIMEInit; // SalIME-Data-Init
+#endif
+};
+
+inline void SetSalData( SalData* pData ) { ImplGetSVData()->mpSalData = (void*)pData; }
+inline SalData* GetSalData() { return (SalData*)ImplGetSVData()->mpSalData; }
+inline SalData* GetAppSalData() { return (SalData*)ImplGetAppSVData()->mpSalData; }
+
+// --------------
+// - SalShlData -
+// --------------
+
+#define OS2_VER_211 211
+#define OS2_VER_WARP3 230
+#define OS2_VER_WARP4 240
+
+struct SalShlData
+{
+ HMODULE mhMod; // Module handle of SAL-DLL
+ USHORT mnVersion; // 211 = OS2 2.11; 230 = OS2 3.0; 240 = OS2 4.0
+ PFNWP mpOldFrameProc; // old frame proc
+};
+
+extern SalShlData aSalShlData;
+
+BOOL SalImplHandleProcessMenu( HWND hWnd, PM_ULONG nMsg, MPARAM nMP1, MPARAM nMP2 );
+
+// SALSHL.CXX - Funktionen fuer DLL-Resource-Zugriffe
+HPOINTER ImplLoadPointer( ULONG nId );
+
+// --------------
+// - Prototypes -
+// --------------
+
+// \\OS2\SOURCE\APP\SALINST.CXX
+ULONG ImplSalGetCurrentThreadId();
+BOOL ImplSalYieldMutexTryToAcquire();
+void ImplSalYieldMutexAcquire();
+void ImplSalYieldMutexRelease();
+
+// \\OS2\SOURCE\WINDOW\SALFRAME.CXX
+MRESULT EXPENTRY SalFrameWndProc( HWND hWnd, PM_ULONG nMsg, MPARAM nMP1, MPARAM nMP2 );
+MRESULT EXPENTRY SalFrameFrameProc( HWND hWnd, PM_ULONG nMsg, MPARAM nMP1, MPARAM nMP2 );
+
+// \\OS2\SOURCE\WINDOW\SALFRAME.CXX
+// return Frame for Message-Handling
+SalFrame* GetSalDefaultFrame();
+
+// \\OS2\SOURCE\WINDOW\SALFRAME.CXX
+// IME-Daten wieder freigeben
+#ifdef ENABLE_IME
+void ImplReleaseSALIMEData();
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define SAL_PROFILE_APPNAME ((PSZ)"StarOffice")
+#define SAL_PROFILE_USEDJP ((PSZ)"UseDJP")
+#define SAL_PROFILE_PRINTDJP ((PSZ)"PrintDJP")
+#define SAL_PROFILE_PRINTRAW ((PSZ)"PrintRAW")
+
+#define SAL_FRAME_WNDEXTRA sizeof(PM_ULONG)
+#define SAL_FRAME_THIS 0
+#define SAL_FRAME_CLASSNAME "SALFRAME"
+#define SAL_OBJECT_WNDEXTRA sizeof(PM_ULONG)
+#define SAL_OBJECT_THIS 0
+#define SAL_OBJECT_CLASSNAME "SALOBJECT"
+#define SAL_OBJECT_CHILDCLASSNAME "SALOBJECTCHILD"
+#define SAL_OBJECT_CLIPCLASSNAME "SALOBJECTCLIP"
+#define SAL_COM_CLASSNAME "SALCOMWND"
+
+#define SAL_MOUSELEAVE_TIMEOUT 300
+
+// MP1 == 0; MP2 == pData
+#define SAL_MSG_USEREVENT (WM_USER+111)
+// MP1 == 0; MP2 == MousePosition relativ to upper left of screen
+#define SAL_MSG_MOUSELEAVE (WM_USER+112)
+// MP1 == hDC; MP2 == 0
+#define SAL_MSG_PRINTABORTJOB (WM_USER+113)
+// MP1 == 0; MP2 == 0
+#define SAL_MSG_STARTTIMER (WM_USER+114)
+// MP1 == nFrameStyle; MP2 == pParent; lResult pFrame
+#define SAL_MSG_CREATEFRAME (WM_USER+115)
+// MP1 == 0; MP2 == pParent; lResult pObject
+#define SAL_MSG_CREATEOBJECT (WM_USER+116)
+// MP1 == bWait; MP2 == pMutex
+#define SAL_MSG_THREADYIELD (WM_USER+117)
+// MP1 == 0; MP2 == 0
+#define SAL_MSG_RELEASEWAITYIELD (WM_USER+118)
+// MP1 == 0; MP2 == pData
+#define SAL_MSG_SYSPROCESSMENU (WM_USER+119)
+// POSTFOCUS-Message; MP1 == nMP1; MP2 == nMP2 (SHORT1( bFocus ), 0)
+#define SAL_MSG_POSTFOCUS (WM_USER+120)
+// POSTSIZE-Message; MP1 == nMP1; MP2 == nMP2
+#define SAL_MSG_POSTSIZE (WM_USER+121)
+
+// SysChild-ToTop; nMP1 = 0; nMP2 = 0
+#define SALOBJ_MSG_TOTOP (WM_USER+150)
+// POSTFOCUS-Message; MP1 == nMP1; MP2 == nMP2 (SHORT1( bFocus ), 0)
+#define SALOBJ_MSG_POSTFOCUS (WM_USER+151)
+
+// -----------------
+// - Helpfunctions -
+// -----------------
+
+inline void SetWindowPtr( HWND hWnd, SalFrame* pThis )
+{
+ WinSetWindowULong( hWnd, SAL_FRAME_THIS, (PM_ULONG)pThis );
+}
+
+inline SalFrame* GetWindowPtr( HWND hWnd )
+{
+ return (SalFrame*)WinQueryWindowULong( hWnd, SAL_FRAME_THIS );
+}
+
+inline void SetSalObjWindowPtr( HWND hWnd, SalObject* pThis )
+{
+ WinSetWindowULong( hWnd, SAL_OBJECT_THIS, (PM_ULONG)pThis );
+}
+
+inline SalObject* GetSalObjWindowPtr( HWND hWnd )
+{
+ return (SalObject*)WinQueryWindowULong( hWnd, SAL_OBJECT_THIS );
+}
+
+#endif // _SV_SALDATA_HXX
diff --git a/vcl/os2/inc/salframe.h b/vcl/os2/inc/salframe.h
new file mode 100644
index 000000000000..6d71e5c457d4
--- /dev/null
+++ b/vcl/os2/inc/salframe.h
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * $RCSfile: salframe.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALFRAME_H
+#define _SV_SALFRAME_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+class SalFrame;
+
+// ----------------
+// - SalFrameData -
+// ----------------
+
+class SalFrameData
+{
+public:
+ HWND mhWndFrame; // HWND-Frame
+ HWND mhWndClient; // HWND-Client
+ HAB mhAB; // HAB
+ HPOINTER mhPointer; // Current MousePointer
+ void* mpInst; // VCL-Instance
+ SALFRAMEPROC mpProc; // VCL-Proc
+ SalGraphics* mpGraphics; // current frame graphics
+ SalFrame* mpNextFrame; // pointer to next frame
+ SalFrameState maState; // frame state
+ SystemEnvData maSysData; // system data
+ ULONG mnStyle; // SalFrameStyle
+ PM_ULONG mnOS2Style; // OS2-CreationFrameStyle
+ long mnWidth; // Window-Witdth
+ long mnHeight; // Window-Height
+ SWP maFullScreenRect; // WindowRect befor FullScreenMode
+ BOOL mbFullScreen; // is in fullscreenmode
+ BOOL mbGraphics; // is Graphics used
+ BOOL mbAllwayOnTop; // Allways on top modus
+ BOOL mbVisible; // Visible Show/Hide-Status
+ BOOL mbMinHide; // hide called from OS2
+ BOOL mbInShow; // innerhalb eines Show/Hide-Aufrufs
+ BOOL mbRestoreMaximize; // Restore-Maximize
+ BOOL mbInMoveMsg; // Move-Message wird verarbeitet
+ BOOL mbInSizeMsg; // Size-Message wird verarbeitet
+ BOOL mbDefPos; // default-position
+ BOOL mbOverwriteState; // TRUE: WindowState darf umgesetzt werden
+ BOOL mbHandleIME; // TRUE: Wir handeln die IME-Messages
+ BOOL mbConversionMode; // TRUE: Wir befinden uns im Conversion-Modus
+ BOOL mbCandidateMode; // TRUE: Wir befinden uns im Candidate-Modus
+};
+
+#endif // _SV_SALFRAME_H
diff --git a/vcl/os2/inc/salgdi.h b/vcl/os2/inc/salgdi.h
new file mode 100644
index 000000000000..b2afac448744
--- /dev/null
+++ b/vcl/os2/inc/salgdi.h
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALGDI_H
+#define _SV_SALGDI_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+// -------------------
+// - SalGraphicsData -
+// -------------------
+
+class SalGraphicsData
+{
+public:
+ HPS mhPS; // HPS
+ HDC mhDC; // HDC
+ HWND mhWnd; // HWND
+ LONG mnHeight; // Height of frame Window
+ ULONG mnClipElementCount; // number of clip rects in clip rect array
+ RECTL* mpClipRectlAry; // clip rect array
+ ULONG mnFontMetricCount; // number of entries in the font list
+ PFONTMETRICS mpFontMetrics; // cached font list
+ LONG mnOrientationX; // X-Font orientation
+ LONG mnOrientationY; // Y-Font orientation
+ BOOL mbFontIsOutline; // is outline font
+ BOOL mbFontIsFixed; // is fixed font
+ BOOL mbLine; // draw lines
+ BOOL mbFill; // fill areas
+ BOOL mbPrinter; // is Printer
+ BOOL mbVirDev; // is VirDev
+ BOOL mbWindow; // is Window
+ BOOL mbScreen; // is Screen compatible
+ BOOL mbXORMode; // _every_ output with RasterOp XOR
+};
+
+// Init/Deinit Graphics
+void ImplSalInitGraphics( SalGraphicsData* mpData );
+void ImplSalDeInitGraphics( SalGraphicsData* mpData );
+
+// -----------
+// - Defines -
+// -----------
+
+#define RGBCOLOR(r,g,b) ((ULONG)(((BYTE)(b)|((USHORT)(g)<<8))|(((ULONG)(BYTE)(r))<<16)))
+#define TY( y ) (maGraphicsData.mnHeight-(y)-1)
+
+#endif // _SV_SALGDI_H
diff --git a/vcl/os2/inc/salids.hrc b/vcl/os2/inc/salids.hrc
new file mode 100644
index 000000000000..0a04771edd9a
--- /dev/null
+++ b/vcl/os2/inc/salids.hrc
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * $RCSfile: salids.hrc,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALIDS_HRC
+#define _SV_SALIDS_HRC
+
+// Pointer
+#define SAL_RESID_POINTER_NULL 10000
+#define SAL_RESID_POINTER_HELP 10001
+#define SAL_RESID_POINTER_CROSS 10002
+#define SAL_RESID_POINTER_MOVE 10003
+#define SAL_RESID_POINTER_HSPLIT 10004
+#define SAL_RESID_POINTER_VSPLIT 10005
+#define SAL_RESID_POINTER_HSIZEBAR 10006
+#define SAL_RESID_POINTER_VSIZEBAR 10007
+#define SAL_RESID_POINTER_HAND 10008
+#define SAL_RESID_POINTER_REFHAND 10009
+#define SAL_RESID_POINTER_PEN 10010
+#define SAL_RESID_POINTER_MAGNIFY 10011
+#define SAL_RESID_POINTER_FILL 10012
+#define SAL_RESID_POINTER_ROTATE 10013
+#define SAL_RESID_POINTER_HSHEAR 10014
+#define SAL_RESID_POINTER_VSHEAR 10015
+#define SAL_RESID_POINTER_MIRROR 10016
+#define SAL_RESID_POINTER_CROOK 10017
+#define SAL_RESID_POINTER_CROP 10018
+#define SAL_RESID_POINTER_MOVEPOINT 10019
+#define SAL_RESID_POINTER_MOVEBEZIERWEIGHT 10020
+#define SAL_RESID_POINTER_MOVEDATA 10021
+#define SAL_RESID_POINTER_COPYDATA 10022
+#define SAL_RESID_POINTER_LINKDATA 10023
+#define SAL_RESID_POINTER_MOVEDATALINK 10024
+#define SAL_RESID_POINTER_COPYDATALINK 10025
+#define SAL_RESID_POINTER_MOVEFILE 10026
+#define SAL_RESID_POINTER_COPYFILE 10027
+#define SAL_RESID_POINTER_LINKFILE 10028
+#define SAL_RESID_POINTER_MOVEFILELINK 10029
+#define SAL_RESID_POINTER_COPYFILELINK 10030
+#define SAL_RESID_POINTER_MOVEFILES 10031
+#define SAL_RESID_POINTER_COPYFILES 10032
+#define SAL_RESID_POINTER_DRAW_LINE 10033
+#define SAL_RESID_POINTER_DRAW_RECT 10034
+#define SAL_RESID_POINTER_DRAW_POLYGON 10035
+#define SAL_RESID_POINTER_DRAW_BEZIER 10036
+#define SAL_RESID_POINTER_DRAW_ARC 10037
+#define SAL_RESID_POINTER_DRAW_PIE 10038
+#define SAL_RESID_POINTER_DRAW_CIRCLECUT 10039
+#define SAL_RESID_POINTER_DRAW_ELLIPSE 10040
+#define SAL_RESID_POINTER_DRAW_FREEHAND 10041
+#define SAL_RESID_POINTER_DRAW_CONNECT 10042
+#define SAL_RESID_POINTER_DRAW_TEXT 10043
+#define SAL_RESID_POINTER_DRAW_CAPTION 10044
+#define SAL_RESID_POINTER_CHART 10045
+#define SAL_RESID_POINTER_DETECTIVE 10046
+#define SAL_RESID_POINTER_PIVOT_COL 10047
+#define SAL_RESID_POINTER_PIVOT_ROW 10048
+#define SAL_RESID_POINTER_PIVOT_FIELD 10049
+#define SAL_RESID_POINTER_CHAIN 10050
+#define SAL_RESID_POINTER_CHAIN_NOTALLOWED 10051
+#define SAL_RESID_POINTER_TIMEEVENT_MOVE 10052
+#define SAL_RESID_POINTER_TIMEEVENT_SIZE 10053
+#define SAL_RESID_POINTER_AUTOSCROLL_N 10054
+#define SAL_RESID_POINTER_AUTOSCROLL_S 10055
+#define SAL_RESID_POINTER_AUTOSCROLL_W 10056
+#define SAL_RESID_POINTER_AUTOSCROLL_E 10057
+#define SAL_RESID_POINTER_AUTOSCROLL_NW 10058
+#define SAL_RESID_POINTER_AUTOSCROLL_NE 10059
+#define SAL_RESID_POINTER_AUTOSCROLL_SW 10060
+#define SAL_RESID_POINTER_AUTOSCROLL_SE 10061
+#define SAL_RESID_POINTER_AUTOSCROLL_NS 10062
+#define SAL_RESID_POINTER_AUTOSCROLL_WE 10063
+#define SAL_RESID_POINTER_AUTOSCROLL_NSWE 10064
+
+#define SAL_RESID_ICON_SD 12000
+
+#endif // _SV_SALIDS_HRC
diff --git a/vcl/os2/inc/salinst.h b/vcl/os2/inc/salinst.h
new file mode 100644
index 000000000000..cae8cb62c3ee
--- /dev/null
+++ b/vcl/os2/inc/salinst.h
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALINST_H
+#define _SV_SALINST_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+#ifdef _VOS_NO_NAMESPACE
+class OMutex;
+#else
+namespace vos { class OMutex; }
+#endif
+class SalYieldMutex;
+class SalInstance;
+class SalFrame;
+class SalObject;
+
+// -------------------
+// - SalInstanceData -
+// -------------------
+
+#define SAL_COMMANDLINENOINIT ((USHORT)0xFFFF)
+#define SAL_MAXPARAM 40
+
+class SalInstanceData
+{
+public:
+ HAB mhAB; // anchor block handle
+ HMQ mhMQ; // handle of os2 message queue
+ HPOINTER mhAppIcon; // app icon
+ int mnArgc; // commandline param count
+ char** mpArgv; // commandline
+ HWND mhComWnd; // window, for communication (between threads and the main thread)
+ void* mpFilterInst; // hack for clipboard
+ void* mpFilterCallback; // hack for clipboard
+ SalYieldMutex* mpSalYieldMutex; // Sal-Yield-Mutex
+#ifdef _VOS_NO_NAMESPACE
+ OMutex* mpSalWaitMutex; // Sal-Wait-Mutex
+#else
+ vos::OMutex* mpSalWaitMutex; // Sal-Wait-Mutex
+#endif
+};
+
+SalFrame* ImplSalCreateFrame( SalInstance* pInst, SalFrame* pParent, ULONG nSalFrameStyle );
+SalObject* ImplSalCreateObject( SalInstance* pInst, SalFrame* pParent );
+void ImplSalStartTimer();
+
+#endif // _SV_SALINST_H
diff --git a/vcl/os2/inc/sallang.hxx b/vcl/os2/inc/sallang.hxx
new file mode 100644
index 000000000000..736613e59ec3
--- /dev/null
+++ b/vcl/os2/inc/sallang.hxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * $RCSfile: sallang.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SALLANG_HXX
+#define _SALLANG_HXX
+
+#ifndef _TOOLS_LANG_HXX
+#include <tools/lang.hxx>
+#endif
+
+// --------------------
+// - Language Strings -
+// --------------------
+
+// --- Key-Namen ---
+#define LSTR_KEY_SHIFT 0
+#define LSTR_KEY_CTRL 1
+#define LSTR_KEY_ALT 2
+#define LSTR_KEY_UP 3
+#define LSTR_KEY_DOWN 4
+#define LSTR_KEY_LEFT 5
+#define LSTR_KEY_RIGHT 6
+#define LSTR_KEY_HOME 7
+#define LSTR_KEY_END 8
+#define LSTR_KEY_PAGEUP 9
+#define LSTR_KEY_PAGEDOWN 10
+#define LSTR_KEY_RETURN 11
+#define LSTR_KEY_ESC 12
+#define LSTR_KEY_TAB 13
+#define LSTR_KEY_BACKSPACE 14
+#define LSTR_KEY_SPACE 15
+#define LSTR_KEY_INSERT 16
+#define LSTR_KEY_DELETE 17
+
+// --- Anzahl der Texte ---
+
+#define LSTR_COUNT 18
+
+// --------------------------------------------
+// - Methoden zum Abfragen der Sprach-Strings -
+// --------------------------------------------
+
+const char** ImplGetLangTab( LanguageType eLang );
+
+#endif // _SALLANG_HXX
diff --git a/vcl/os2/inc/salobj.h b/vcl/os2/inc/salobj.h
new file mode 100644
index 000000000000..a8c80f474e88
--- /dev/null
+++ b/vcl/os2/inc/salobj.h
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * $RCSfile: salobj.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALOBJ_H
+#define _SV_SALOBJ_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+// -----------------
+// - SalObjectData -
+// -----------------
+
+class SalObjectData
+{
+public:
+ HWND mhWnd; // Window handle
+ HWND mhWndChild; // Child Window handle
+ HWND mhLastFocusWnd; // Child-Window, welches als letztes den Focus hatte
+ SystemChildData maSysData; // SystemEnvData
+ HWND mhLastClipWnd; // LastClip-Window
+ HWND mhOldLastClipWnd; // LastClip-Window befor BeginSetClipRegion
+ long mnHeight; // Fenster-Hoehe fuer Positionsumrechnung
+ SalObject* mpNextObject; // pointer to next object
+ void* mpInst; // instance handle for callback
+ SALOBJECTPROC mpProc; // callback proc
+};
+
+#endif // _SV_SALOBJ_H
diff --git a/vcl/os2/inc/salprn.h b/vcl/os2/inc/salprn.h
new file mode 100644
index 000000000000..1b151ad1ae2e
--- /dev/null
+++ b/vcl/os2/inc/salprn.h
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * $RCSfile: salprn.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALPRN_H
+#define _SV_SALPRN_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+class SalGraphics;
+class SalInfoPrinter;
+
+struct ImplFormInfo;
+typedef ImplFormInfo* PIMPLFORMINFO;
+struct ImplTrayInfo;
+typedef ImplTrayInfo* PIMPLTRAYINFO;
+
+// ----------------------
+// - SalInfoPrinterData -
+// ----------------------
+
+class SalInfoPrinterData
+{
+public:
+ SalGraphics* mpGraphics; // Graphics
+ HDC mhDC; // printer hdc
+ HPS mhPS; // printer hps
+ String maPrinterName; // pszPrinters
+ String maName; // pszName bzw. LogAdress
+ String maDriverName; // pszDriverName nach .
+ String maDeviceName; // pszDriverName bis .
+ String maJobSetupDeviceName; // DeviceName aus pDriverData
+ PIMPLFORMINFO* mpFormArray; // PaperForm-Names
+ USHORT mnFormCount; // PaperForm-Count
+ PIMPLTRAYINFO* mpTrayArray; // PaperTray-Names
+ USHORT mnTrayCount; // PaperTray-Count
+ BOOL mbDJPSupported; // is driver DJP enabled
+ BOOL mbGraphics; // is Graphics used
+};
+
+// ------------------
+// - SalPrinterData -
+// ------------------
+
+class SalPrinterData
+{
+public:
+ SalGraphics* mpGraphics; // current Printer graphics
+ SalInfoPrinter* mpInfoPrinter; // pointer to the compatible InfoPrinter
+ HDC mhDC; // printer hdc
+ HPS mhPS; // printer hps
+ ULONG mnError; // Error Code
+ BOOL mbFirstPage; // IsFirstPage
+ BOOL mbAbort; // JobAborted
+ BOOL mbPrintDJPSupported; // is driver PrintDJP enabled (DEVESC_NEWFRAME_WPROP)
+ char maCommentBuf[33]; // Comment
+ char maCopyBuf[10]; // Kopien
+};
+
+#endif // _SV_SALPRN_H
diff --git a/vcl/os2/inc/salsound.hxx b/vcl/os2/inc/salsound.hxx
new file mode 100644
index 000000000000..e766d8df869f
--- /dev/null
+++ b/vcl/os2/inc/salsound.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * $RCSfile: salsound.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALSOUND_HXX
+#define _SV_SALSOUND_HXX
+
+#ifndef _GEN_HXX
+#include <tools/gen.hxx>
+#endif
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _STRING_HXX
+#include <tools/string.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOTYPE_HXX
+#include <salstype.hxx>
+#endif
+
+// ------------
+// - SalSound -
+// ------------
+
+class SalSound
+{
+private:
+
+ static HMODULE mhMCILib;
+ static ULONG mnSoundState;
+ static void* mpMCIFnc;
+ SALSOUNDPROC mpProc;
+ void* mpInst;
+ ULONG mnStartTime;
+ ULONG mnPlayLen;
+ HWND mhSoundWnd;
+ USHORT mnDeviceId;
+ BOOL mbLoop;
+ BOOL mbPaused;
+
+public:
+
+ void ImplSetError( ULONG nMciErr );
+ void ImplNotify( SoundNotification eNotification, ULONG nError );
+
+public:
+
+ SalSound();
+ ~SalSound();
+
+ BOOL Create();
+ static void Release();
+ static BOOL IsValid() { return( SOUND_STATE_VALID == SalSound::mnSoundState ); }
+
+ BOOL Init( SalFrame* pFrame, const String& rSoundName, ULONG& rSoundLen );
+ BOOL Init( SalFrame* pFrame, const BYTE* pSound, ULONG nDataLen, ULONG& rSoundLen );
+ void Play( ULONG nStartTime, ULONG nPlayTime, BOOL bLoop );
+ void Stop();
+ void Pause();
+
+ void SetNotifyProc( void* pInst, SALSOUNDPROC pProc )
+ { mpInst = pInst; mpProc = pProc; }
+};
+
+#endif // _SV_SALSOUND_HXX
diff --git a/vcl/os2/inc/salsys.h b/vcl/os2/inc/salsys.h
new file mode 100644
index 000000000000..49f5e0659f58
--- /dev/null
+++ b/vcl/os2/inc/salsys.h
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * $RCSfile: salsys.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALSYS_H
+#define _SV_SALSYS_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+class SalFrame;
+
+// -----------------
+// - SalSystemData -
+// -----------------
+
+class SalSystemData
+{
+};
+
+#endif // _SV_SALSYS_H
diff --git a/vcl/os2/inc/salvd.h b/vcl/os2/inc/salvd.h
new file mode 100644
index 000000000000..e95248eec69e
--- /dev/null
+++ b/vcl/os2/inc/salvd.h
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * $RCSfile: salvd.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALVD_H
+#define _SV_SALVD_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+class SalGraphics;
+
+// -----------------
+// - SalVirDevData -
+// -----------------
+
+class SalVirDevData
+{
+public:
+ HPS mhPS; // HPS
+ HDC mhDC; // HDC
+ HBITMAP mhBmp; // Memory Bitmap
+ HBITMAP mhDefBmp; // Default Bitmap
+ SalGraphics* mpGraphics; // current VirDev graphics
+ USHORT mnBitCount; // BitCount (0 or 1)
+ BOOL mbGraphics; // is Graphics used
+};
+
+// Help-Functions
+HBITMAP ImplCreateVirDevBitmap( HDC hDC, HPS hPS, long nDX, long nDY,
+ USHORT nBitCount );
+
+#endif // _SV_SALVD_H
diff --git a/vcl/os2/inc/svsys.h b/vcl/os2/inc/svsys.h
new file mode 100644
index 000000000000..23f834d48550
--- /dev/null
+++ b/vcl/os2/inc/svsys.h
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * $RCSfile: svsys.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SVSYS_H
+#define _SV_SVSYS_H
+
+#ifndef _SVPM_H
+#include <tools/svpm.h>
+#endif
+
+#endif // _SV_SVSYS_H
diff --git a/vcl/os2/source/app/makefile.mk b/vcl/os2/source/app/makefile.mk
new file mode 100644
index 000000000000..e83b8f3a4f11
--- /dev/null
+++ b/vcl/os2/source/app/makefile.mk
@@ -0,0 +1,96 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=SV
+TARGET=salapp
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= salmain.cxx \
+ salshl.cxx \
+ salinst.cxx \
+ sallang.cxx \
+ saltimer.cxx \
+ salsound.cxx \
+ salsys.cxx
+
+OBJFILES= $(OBJ)$/salmain.obj
+
+SLOFILES= $(SLO)$/salshl.obj \
+ $(SLO)$/salinst.obj \
+ $(SLO)$/sallang.obj \
+ $(SLO)$/saltimer.obj \
+ $(SLO)$/salsound.obj \
+ $(SLO)$/salsys.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/os2/source/app/salinst.cxx b/vcl/os2/source/app/salinst.cxx
new file mode 100644
index 000000000000..8a3ef0d1315f
--- /dev/null
+++ b/vcl/os2/source/app/salinst.cxx
@@ -0,0 +1,754 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define INCL_DOSMISC
+#define INCL_DOSMODULEMGR
+#define INCL_DOSPROCESS
+
+#include <string.h>
+#include <tools/svpm.h>
+#include <process.h>
+
+#define _SV_SALINST_CXX
+
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+
+#define SVMODULENAME "VCL" MAKE_NUMSTR( SUPD ) __DLLEXTENSION
+
+// =======================================================================
+
+void SalSetExceptionHandler( SALEXCEPTIONPROC pProc )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalAbort( const XubString& rErrorText )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ULONG ImplSalGetCurrentThreadId()
+{
+ PTIB pptib = NULL;
+ PPIB pppib = NULL;
+
+ DosGetInfoBlocks( &pptib, &pppib );
+ return pptib->tib_ptib2->tib2_ultid;
+}
+
+// =======================================================================
+
+class SalYieldMutex : public NAMESPACE_VOS(OMutex)
+{
+public:
+ SalInstanceData* mpInstData;
+ ULONG mnCount;
+ ULONG mnWaitCount;
+ ULONG mnThreadId;
+
+public:
+ SalYieldMutex( SalInstanceData* pInstData );
+
+ virtual void acquire();
+ virtual void release();
+ virtual Boolean tryToAcquire();
+
+ ULONG GetAcquireCount( ULONG nThreadId );
+};
+
+// -----------------------------------------------------------------------
+
+SalYieldMutex::SalYieldMutex( SalInstanceData* pInstData )
+{
+ mpInstData = pInstData;
+ mnCount = 0;
+ mnThreadId = 0;
+ mnWaitCount = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SalYieldMutex::acquire()
+{
+ OMutex::acquire();
+ mnCount++;
+ mnThreadId = ImplSalGetCurrentThreadId();
+}
+
+// -----------------------------------------------------------------------
+
+void SalYieldMutex::release()
+{
+ ULONG nThreadId = ImplSalGetCurrentThreadId();
+ if ( mnThreadId != nThreadId )
+ OMutex::release();
+ else
+ {
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mnAppThreadId != nThreadId )
+ {
+ NAMESPACE_VOS(OGuard) aGuard( mpInstData->mpSalWaitMutex );
+ if ( mnCount == 1 )
+ {
+ if ( mnWaitCount && WinPostMsg( mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 ) )
+ mnWaitCount--;
+ mnThreadId = 0;
+ }
+ mnCount--;
+ OMutex::release();
+ }
+ else
+ {
+ if ( mnCount == 1 )
+ mnThreadId = 0;
+ mnCount--;
+ OMutex::release();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Boolean SalYieldMutex::tryToAcquire()
+{
+ if ( OMutex::tryToAcquire() )
+ {
+ mnCount++;
+ mnThreadId = ImplSalGetCurrentThreadId();
+ return True;
+ }
+ else
+ return False;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalYieldMutex::GetAcquireCount( ULONG nThreadId )
+{
+ if ( nThreadId == mnThreadId )
+ return mnCount;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplSalYieldMutexTryToAcquire()
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstInstance )
+ return pSalData->mpFirstInstance->maInstData.mpSalYieldMutex->tryToAcquire();
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexAcquire()
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstInstance )
+ pSalData->mpFirstInstance->maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexRelease()
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstInstance )
+ pSalData->mpFirstInstance->maInstData.mpSalYieldMutex->release();
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+
+void ImplDbgTestSolarMutex()
+{
+ SalData* pSalData = GetSalData();
+ ULONG nCurThreadId = ImplSalGetCurrentThreadId();
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" );
+ }
+ }
+ }
+ else
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked in the main thread" );
+ }
+ }
+ }
+}
+
+#endif
+
+// =======================================================================
+
+void InitSalSystemData()
+{
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalYield( BOOL bWait, BOOL bMainThread, SalYieldMutex* pYieldMutex )
+{
+ QMSG aMsg;
+ QMSG aTmpMsg;
+ BOOL bDispatch = FALSE;
+ USHORT nPostReleaseWait = 0;
+ static QMSG* pMsg = NULL;
+ SalData* pSalData = GetSalData();
+
+ do
+ {
+ if ( !pMsg )
+ {
+ BOOL bQuit = FALSE;
+ if ( bWait )
+ {
+ if ( WinGetMsg( pSalData->mhAB, &aMsg, 0, 0, 0 ) )
+ pMsg = &aMsg;
+ else
+ bQuit = TRUE;
+ }
+ else
+ {
+ if ( WinPeekMsg( pSalData->mhAB, &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ if ( aMsg.msg == WM_QUIT )
+ bQuit = TRUE;
+ else
+ pMsg = &aMsg;
+ }
+ }
+
+ // ShutDown-Event ausloesen (ist immer dann der Fall,
+ // wenn wir eine Quit-Message bekommen)
+ if ( bQuit && pSalData->mpDefaultFrame )
+ {
+ SalFrame* pDefaultFrame = pSalData->mpDefaultFrame;
+ if ( pDefaultFrame->maFrameData.mpProc( pDefaultFrame->maFrameData.mpInst, pDefaultFrame,
+ SALEVENT_SHUTDOWN, 0 ) )
+ WinCancelShutdown( pSalData->mhAB, FALSE );
+ }
+
+ // ReleaseWaitYield ignorieren wir, da diese fuer andere
+ // Yield-Aufrufe gedacht sind
+ if ( pMsg )
+ {
+ if ( pMsg->msg == SAL_MSG_RELEASEWAITYIELD )
+ {
+ nPostReleaseWait++;
+ pMsg = NULL;
+ continue;
+ }
+ }
+ }
+
+ if ( pMsg )
+ {
+ // Darf ich die Message dispatchen
+ pYieldMutex->mpInstData->mpSalWaitMutex->acquire();
+ if ( pYieldMutex->tryToAcquire() )
+ {
+ pYieldMutex->mpInstData->mpSalWaitMutex->release();
+ bDispatch = TRUE;
+ }
+ else
+ {
+ pYieldMutex->mnWaitCount++;
+ pYieldMutex->mpInstData->mpSalWaitMutex->release();
+ WinGetMsg( pSalData->mhAB, &aTmpMsg, pYieldMutex->mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD );
+ if ( !pMsg )
+ bDispatch = TRUE;
+ }
+ }
+ else
+ bDispatch = TRUE;
+ }
+ while( !bDispatch );
+
+ if ( pMsg )
+ {
+ // acquire ist nicht notwendig, da dies schon in der oberen
+ // Schleife bei tryToAcquire() gemacht wurde
+ QMSG* pTmpMsg = pMsg;
+ pMsg = NULL;
+ WinDispatchMsg( pSalData->mhAB, pTmpMsg );
+ pYieldMutex->release();
+ }
+
+ while ( nPostReleaseWait )
+ {
+ WinPostMsg( pYieldMutex->mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
+ nPostReleaseWait--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+MRESULT EXPENTRY SalComWndProc( HWND hWnd, PM_ULONG nMsg,
+ MPARAM nMP1, MPARAM nMP2 )
+{
+ switch ( nMsg )
+ {
+ case SAL_MSG_STARTTIMER:
+ ImplSalStartTimer();
+ return 0;
+ case SAL_MSG_CREATEFRAME:
+ return (MRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, (SalFrame*)(ULONG)nMP2, (ULONG)nMP1 );
+ case SAL_MSG_CREATEOBJECT:
+ return (MRESULT)ImplSalCreateObject( GetSalData()->mpFirstInstance, (SalFrame*)(ULONG)nMP2 );
+ case SAL_MSG_THREADYIELD:
+ ImplSalYield( (BOOL)(LONG)nMP1, FALSE, (SalYieldMutex*)(LONG)nMP2 );
+ return 0;
+ }
+
+ return WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
+}
+
+// =======================================================================
+
+void InitSalData()
+{
+ SalData* pSalData = new SalData;
+ memset( pSalData, 0, sizeof( SalData ) );
+ SetSalData( pSalData );
+}
+
+// -----------------------------------------------------------------------
+
+void DeInitSalData()
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFontMetrics )
+ delete pSalData->mpFontMetrics;
+ delete pSalData;
+ SetSalData( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void SetFilterCallback( void* pCallback, void* pInst )
+{
+ SalData* pSalData = GetSalData();
+ pSalData->mpFirstInstance->maInstData.mpFilterCallback = pCallback;
+ pSalData->mpFirstInstance->maInstData.mpFilterInst = pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance* CreateSalInstance()
+{
+ SalData* pSalData = GetSalData();
+ SalInstance* pInst = new SalInstance;
+
+ // determine Module-Handle for SVDLL
+ DosQueryModuleHandle( (PSZ)SVMODULENAME, &aSalShlData.mhMod );
+
+ // determine the os2 version
+ PM_ULONG nMayor;
+ PM_ULONG nMinor;
+ DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_MAJOR, &nMayor, sizeof( nMayor ) );
+ DosQuerySysInfo( QSV_VERSION_MINOR, QSV_VERSION_MINOR, &nMinor, sizeof( nMinor ) );
+ aSalShlData.mnVersion = (USHORT)(nMayor*10 + nMinor);
+
+ pSalData->mnAppThreadId = ImplSalGetCurrentThreadId();
+
+ // register frame class
+ if ( !WinRegisterClass( pSalData->mhAB, (PSZ)SAL_FRAME_CLASSNAME,
+ (PFNWP)SalFrameWndProc, CS_HITTEST | CS_MOVENOTIFY,
+ SAL_FRAME_WNDEXTRA ) )
+ {
+ delete pInst;
+ return NULL;
+ }
+
+ // register frame class
+ if ( !WinRegisterClass( pSalData->mhAB, (PSZ)SAL_COM_CLASSNAME,
+ (PFNWP)SalComWndProc, 0, 0 ))
+ {
+ delete pInst;
+ return NULL;
+ }
+
+ HWND hComWnd = WinCreateWindow( HWND_OBJECT, (PSZ)SAL_COM_CLASSNAME,
+ "", 0, 0, 0, 0, 0,
+ HWND_OBJECT, HWND_TOP,
+ 222, NULL, NULL);
+
+ // init system data
+ InitSalSystemData();
+
+ // init instance (only one instance in this version !!!)
+ pSalData->mpFirstInstance = pInst;
+ pInst->maInstData.mhAB = pSalData->mhAB;
+ pInst->maInstData.mhMQ = pSalData->mhMQ;
+ pInst->maInstData.mnArgc = pSalData->mnArgc;
+ pInst->maInstData.mpArgv = pSalData->mpArgv;
+ pInst->maInstData.mhComWnd = hComWnd;
+
+ // AppIcon ermitteln
+ pInst->maInstData.mhAppIcon = WinLoadPointer( HWND_DESKTOP, pSalData->mhAB, 1 );
+ if ( !pInst->maInstData.mhAppIcon )
+ pInst->maInstData.mhAppIcon = ImplLoadPointer( SAL_RESID_ICON_SD );
+
+ return pInst;
+}
+
+// -----------------------------------------------------------------------
+
+void DestroySalInstance( SalInstance* pInst )
+{
+ SalData* pSalData = GetSalData();
+
+ // (only one instance in this version !!!)
+
+#ifdef ENABLE_IME
+ // IME-Daten freigeben
+ if ( pSalData->mpIMEData )
+ ImplReleaseSALIMEData();
+#endif
+
+ // Destroy Dummy Frame
+ if ( pSalData->mpDummyFrame )
+ pInst->DestroyFrame( pSalData->mpDummyFrame );
+
+ // reset instance
+ if ( pSalData->mpFirstInstance == pInst )
+ pSalData->mpFirstInstance = NULL;
+
+ delete pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::SalInstance()
+{
+ maInstData.mpFilterCallback = NULL;
+ maInstData.mpFilterInst = NULL;
+
+ maInstData.mpSalWaitMutex = new NAMESPACE_VOS(OMutex);
+ maInstData.mpSalYieldMutex = new SalYieldMutex( &maInstData );
+ maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::~SalInstance()
+{
+ maInstData.mpSalYieldMutex->release();
+ delete maInstData.mpSalYieldMutex;
+ delete maInstData.mpSalWaitMutex;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInstance::AnyInput( USHORT nType )
+{
+ SalData* pSalData = GetSalData();
+ QMSG aQMSG;
+
+ if ( (nType & (INPUT_ANY)) == INPUT_ANY )
+ {
+ // Any Input
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0, 0, 0, PM_NOREMOVE ) )
+ return TRUE;
+ }
+ else
+ {
+ if ( nType & INPUT_MOUSE )
+ {
+ // Test auf Mouseinput
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
+ WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_KEYBOARD )
+ {
+ // Test auf Keyinput
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
+ WM_CHAR, WM_CHAR, PM_NOREMOVE ) )
+ return !(SHORT1FROMMP( aQMSG.mp1 ) & KC_KEYUP);
+ }
+
+ if ( nType & INPUT_PAINT )
+ {
+ // Test auf Paintinput
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
+ WM_PAINT, WM_PAINT, PM_NOREMOVE ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_TIMER )
+ {
+ // Test auf Timerinput
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0,
+ WM_TIMER, WM_TIMER, PM_NOREMOVE ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_OTHER )
+ {
+ // Test auf sonstigen Input
+ if ( WinPeekMsg( pSalData->mhAB, &aQMSG, 0, 0, 0, PM_NOREMOVE ) )
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::Yield( BOOL bWait )
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ SalData* pSalData = GetSalData();
+ ULONG nCurThreadId = ImplSalGetCurrentThreadId();
+ ULONG nCount = pYieldMutex->GetAcquireCount( nCurThreadId );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ WinSendMsg( maInstData.mhComWnd, SAL_MSG_THREADYIELD,
+ (MPARAM)bWait, (MPARAM)(void*)pYieldMutex );
+
+ n = nCount;
+ while ( n )
+ {
+ pYieldMutex->acquire();
+ n--;
+ }
+ }
+ else
+ {
+ ImplSalYield( bWait, TRUE, pYieldMutex );
+
+ n = nCount;
+ while ( n )
+ {
+ // Wenn wir den Mutex nicht bekommen, muessen wir solange
+ // warten, bis wir Ihn bekommen
+ pYieldMutex->mpInstData->mpSalWaitMutex->acquire();
+ if ( pYieldMutex->tryToAcquire() )
+ {
+ pYieldMutex->mpInstData->mpSalWaitMutex->release();
+ n--;
+ }
+ else
+ {
+ pYieldMutex->mnWaitCount++;
+ pYieldMutex->mpInstData->mpSalWaitMutex->release();
+ QMSG aTmpMsg;
+ WinGetMsg( pSalData->mhAB, &aTmpMsg, maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalInstance::GetFileName()
+{
+ String aFileName( maInstData.mpArgv[0] );
+ return aFileName;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalInstance::GetCommandLineParamCount()
+{
+ return maInstData.mnArgc-1;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalInstance::GetCommandLineParam( USHORT nParam )
+{
+ if ( nParam < maInstData.mnArgc-1 )
+ {
+ String aParam( maInstData.mpArgv[nParam+1] );
+ return aParam;
+ }
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef _VOS_NO_NAMESPACE
+IMutex* SalInstance::GetYieldMutex()
+#else
+vos::IMutex* SalInstance::GetYieldMutex()
+#endif
+{
+ return maInstData.mpSalYieldMutex;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInstance::ReleaseYieldMutex()
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ ULONG nCount = pYieldMutex->GetAcquireCount( ImplSalGetCurrentThreadId() );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+
+ return nCount;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::AcquireYieldMutex( ULONG nCount )
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ while ( nCount )
+ {
+ pYieldMutex->acquire();
+ nCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* SalInstance::CreateFrame( SalFrame* pParent, USHORT nSalFrameStyle )
+{
+ // Um auf Main-Thread umzuschalten
+ return (SalFrame*)WinSendMsg( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, (MPARAM)nSalFrameStyle, (MPARAM)pParent );
+}
+
+// -----------------------------------------------------------------------
+
+SalObject* SalInstance::CreateObject( SalFrame* pParent )
+{
+ // Um auf Main-Thread umzuschalten
+ return (SalObject*)WinSendMsg( maInstData.mhComWnd, SAL_MSG_CREATEOBJECT, 0, (MPARAM)pParent );
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::Start( ULONG nMS )
+{
+ // Um auf Main-Thread umzuschalten
+ SalData* pSalData = GetSalData();
+ pSalData->mnNewTimerMS = nMS;
+ if ( pSalData->mpFirstInstance )
+ {
+ if ( pSalData->mnAppThreadId != ImplSalGetCurrentThreadId() )
+ WinPostMsg( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, 0 );
+ else
+ WinSendMsg( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, 0 );
+ }
+ else
+ ImplSalStartTimer();
+}
diff --git a/vcl/os2/source/app/sallang.cxx b/vcl/os2/source/app/sallang.cxx
new file mode 100644
index 000000000000..ba8be275ec4b
--- /dev/null
+++ b/vcl/os2/source/app/sallang.cxx
@@ -0,0 +1,406 @@
+/*************************************************************************
+ *
+ * $RCSfile: sallang.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_INTN_HXX
+#include <tools/intn.hxx>
+#endif
+
+#ifndef _SALLANG_HXX
+#include <sallang.hxx>
+#endif
+
+// =======================================================================
+
+// -----------------------------------------------------------------------
+// Danish
+
+static const char* aImplLangDanishTab[LSTR_COUNT] =
+{
+ "Skift", // LSTR_KEY_SHIFT
+ "Ctrl", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Op", // LSTR_KEY_UP
+ "Ned", // LSTR_KEY_DOWN
+ "Venstre", // LSTR_KEY_LEFT
+ "Hjre", // LSTR_KEY_RIGHT
+ "Home", // LSTR_KEY_HOME
+ "End", // LSTR_KEY_END
+ "PageUp", // LSTR_KEY_PAGEUP
+ "PageDown", // LSTR_KEY_PAGEDOWN
+ "Enter", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Tilbage", // LSTR_KEY_BACKSPACE
+ "Mellemrum", // LSTR_KEY_SPACE
+ "Insert", // LSTR_KEY_INSERT
+ "Delete", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// Dutch (Netherland/Belgian)
+
+static const char* aImplLangDutchTab[LSTR_COUNT] =
+{
+ "Shift", // LSTR_KEY_SHIFT
+ "Ctrl", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Boven", // LSTR_KEY_UP
+ "Onder", // LSTR_KEY_DOWN
+ "Links", // LSTR_KEY_LEFT
+ "Links", // LSTR_KEY_RIGHT
+ "Pos1", // LSTR_KEY_HOME
+ "Einde", // LSTR_KEY_END
+ "PageUp", // LSTR_KEY_PAGEUP
+ "PageDown", // LSTR_KEY_PAGEDOWN
+ "Return", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Backspace", // LSTR_KEY_BACKSPACE
+ "Spatiebalk", // LSTR_KEY_SPACE
+ "Ins", // LSTR_KEY_INSERT
+ "Verwijderen", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// English (US/UK/AUS/CAN/NZ/EIRE/SAFRICA/JAMAICA/CARRIBEAN)
+
+static const char* aImplLangEnglishTab[LSTR_COUNT] =
+{
+ "Shift", // LSTR_KEY_SHIFT
+ "Ctrl", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Up", // LSTR_KEY_UP
+ "Down", // LSTR_KEY_DOWN
+ "Left", // LSTR_KEY_LEFT
+ "Right", // LSTR_KEY_RIGHT
+ "Home", // LSTR_KEY_HOME
+ "End", // LSTR_KEY_END
+ "PageUp", // LSTR_KEY_PAGEUP
+ "PageDown", // LSTR_KEY_PAGEDOWN
+ "Enter", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Backspace", // LSTR_KEY_BACKSPACE
+ "Space", // LSTR_KEY_SPACE
+ "Insert", // LSTR_KEY_INSERT
+ "Del", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// Finnish
+
+static const char* aImplLangFinnishTab[LSTR_COUNT] =
+{
+ "Vaihtonppain", // LSTR_KEY_SHIFT
+ "Ctrl", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Yl", // LSTR_KEY_UP
+ "Ala", // LSTR_KEY_DOWN
+ "Vasen", // LSTR_KEY_LEFT
+ "Oikea", // LSTR_KEY_RIGHT
+ "Home", // LSTR_KEY_HOME
+ "End", // LSTR_KEY_END
+ "PageUp", // LSTR_KEY_PAGEUP
+ "PageDown", // LSTR_KEY_PAGEDOWN
+ "Enter", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Sarkain", // LSTR_KEY_TAB
+ "Askelpalautin", // LSTR_KEY_BACKSPACE
+ "Vlinppin", // LSTR_KEY_SPACE
+ "Insert", // LSTR_KEY_INSERT
+ "Delete", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// French (French/Belgian/Canadian/Swiss/Luxenbourg)
+
+static const char* aImplLangFrenchTab[LSTR_COUNT] =
+{
+ "Maj", // LSTR_KEY_SHIFT
+ "Ctrl", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Haut", // LSTR_KEY_UP
+ "Bas", // LSTR_KEY_DOWN
+ "Gauche", // LSTR_KEY_LEFT
+ "Droite", // LSTR_KEY_RIGHT
+ "Origine", // LSTR_KEY_HOME
+ "Fin", // LSTR_KEY_END
+ "Pg. Prc", // LSTR_KEY_PAGEUP
+ "Pg. Suiv", // LSTR_KEY_PAGEDOWN
+ "Entre", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Ret. Arr", // LSTR_KEY_BACKSPACE
+ "Espace", // LSTR_KEY_SPACE
+ "Insrer", // LSTR_KEY_INSERT
+ "Suppr", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// German (German/Swiss/Austrian/Luxembourg/Liechtenstein)
+
+static const char* aImplLangGermanTab[LSTR_COUNT] =
+{
+ "Umschalt", // LSTR_KEY_SHIFT
+ "Strg", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Nach-Oben", // LSTR_KEY_UP
+ "Nach-Unten", // LSTR_KEY_DOWN
+ "Nach-Links", // LSTR_KEY_LEFT
+ "Nach-Rechts", // LSTR_KEY_RIGHT
+ "Pos1", // LSTR_KEY_HOME
+ "Ende", // LSTR_KEY_END
+ "Bild-Nach-Oben", // LSTR_KEY_PAGEUP
+ "Bild-Nach-Unten", // LSTR_KEY_PAGEDOWN
+ "Eingabe", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Rck", // LSTR_KEY_BACKSPACE
+ "Leer", // LSTR_KEY_SPACE
+ "Einfg", // LSTR_KEY_INSERT
+ "Entf", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// Italian (Italian/Swiss)
+
+static const char* aImplLangItalianTab[LSTR_COUNT] =
+{
+ "Maiusc", // LSTR_KEY_SHIFT
+ "Ctrl", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Sposta verso l'alto", // LSTR_KEY_UP
+ "Sposta verso il basso", // LSTR_KEY_DOWN
+ "A sinistra", // LSTR_KEY_LEFT
+ "A destra", // LSTR_KEY_RIGHT
+ "Home", // LSTR_KEY_HOME
+ "Fine", // LSTR_KEY_END
+ "PgSu", // LSTR_KEY_PAGEUP
+ "PgGi", // LSTR_KEY_PAGEDOWN
+ "Invio", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Backspace", // LSTR_KEY_BACKSPACE
+ "Spaziatrice", // LSTR_KEY_SPACE
+ "Ins", // LSTR_KEY_INSERT
+ "Canc", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// Norwegian (Bokmal)
+
+static const char* aImplLangNorwegianTab[LSTR_COUNT] =
+{
+ "Skift", // LSTR_KEY_SHIFT
+ "Ctrl", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Opp", // LSTR_KEY_UP
+ "Ned", // LSTR_KEY_DOWN
+ "Venstre", // LSTR_KEY_LEFT
+ "Hyre", // LSTR_KEY_RIGHT
+ "Home", // LSTR_KEY_HOME
+ "End", // LSTR_KEY_END
+ "PageUp", // LSTR_KEY_PAGEUP
+ "PageDown", // LSTR_KEY_PAGEDOWN
+ "Enter", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Tilbake", // LSTR_KEY_BACKSPACE
+ "Mellomrom", // LSTR_KEY_SPACE
+ "Insert", // LSTR_KEY_INSERT
+ "Delete", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// Portuguse (Portuguse/Brazilian)
+
+static const char* aImplLangPortugueseTab[LSTR_COUNT] =
+{
+ "Shift", // LSTR_KEY_SHIFT
+ "Ctrl", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Acima", // LSTR_KEY_UP
+ "Abaixo", // LSTR_KEY_DOWN
+ "Esquerda", // LSTR_KEY_LEFT
+ "Direita", // LSTR_KEY_RIGHT
+ "Home", // LSTR_KEY_HOME
+ "End", // LSTR_KEY_END
+ "PageUp", // LSTR_KEY_PAGEUP
+ "PageDown", // LSTR_KEY_PAGEDOWN
+ "Enter", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Backspace", // LSTR_KEY_BACKSPACE
+ "Space", // LSTR_KEY_SPACE
+ "Insert", // LSTR_KEY_INSERT
+ "Delete", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// Spanish (Spanish/Mexican/Modern/Guatemala/Costarica/Panama/Dominican/
+// Venezuela/Colombia/Peru/Argentina/Ecuador/Chile/Uruguay/
+// Paraguay/Bolivia)
+
+static const char* aImplLangSpanishTab[LSTR_COUNT] =
+{
+ "Mays", // LSTR_KEY_SHIFT
+ "Control", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Hacia arriba", // LSTR_KEY_UP
+ "Hacia abajo", // LSTR_KEY_DOWN
+ "Hacia la izquierda", // LSTR_KEY_LEFT
+ "Hacia la derecha", // LSTR_KEY_RIGHT
+ "Home", // LSTR_KEY_HOME
+ "Fin", // LSTR_KEY_END
+ "RePg", // LSTR_KEY_PAGEUP
+ "AvPg", // LSTR_KEY_PAGEDOWN
+ "Entrada", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Ret", // LSTR_KEY_BACKSPACE
+ "Espacio", // LSTR_KEY_SPACE
+ "Insert", // LSTR_KEY_INSERT
+ "Supr", // LSTR_KEY_DELETE
+};
+
+// -----------------------------------------------------------------------
+// Swedish
+
+static const char* aImplLangSwedishTab[LSTR_COUNT] =
+{
+ "Skift", // LSTR_KEY_SHIFT
+ "Ctrl", // LSTR_KEY_CTRL
+ "Alt", // LSTR_KEY_ALT
+ "Up", // LSTR_KEY_UP
+ "Ned", // LSTR_KEY_DOWN
+ "Vnster", // LSTR_KEY_LEFT
+ "Hger", // LSTR_KEY_RIGHT
+ "Home", // LSTR_KEY_HOME
+ "End", // LSTR_KEY_END
+ "PageUp", // LSTR_KEY_PAGEUP
+ "PageDown", // LSTR_KEY_PAGEDOWN
+ "Retur", // LSTR_KEY_RETURN
+ "Esc", // LSTR_KEY_ESC
+ "Tab", // LSTR_KEY_TAB
+ "Backsteg", // LSTR_KEY_BACKSPACE
+ "Blank", // LSTR_KEY_SPACE
+ "Insert", // LSTR_KEY_INSERT
+ "Delete", // LSTR_KEY_DELETE
+};
+
+// =======================================================================
+
+const char** ImplGetLangTab( LanguageType eLang )
+{
+ // Sprachtabelle ermitteln
+ const char** pLangTab;
+ switch ( International::GetNeutralLanguage( eLang ) )
+ {
+ case LANGUAGE_DANISH:
+ pLangTab = aImplLangDanishTab;
+ break;
+
+ case LANGUAGE_DUTCH:
+ case LANGUAGE_DUTCH_BELGIAN:
+ pLangTab = aImplLangDutchTab;
+ break;
+
+ case LANGUAGE_FINNISH:
+ pLangTab = aImplLangFinnishTab;
+ break;
+
+ case LANGUAGE_FRENCH:
+ pLangTab = aImplLangFrenchTab;
+ break;
+
+ case LANGUAGE_GERMAN:
+ pLangTab = aImplLangGermanTab;
+ break;
+
+ case LANGUAGE_ITALIAN:
+ pLangTab = aImplLangItalianTab;
+ break;
+
+ case LANGUAGE_NORWEGIAN:
+ case LANGUAGE_NORWEGIAN_BOKMAL:
+ pLangTab = aImplLangNorwegianTab;
+ break;
+
+ case LANGUAGE_PORTUGUESE:
+ case LANGUAGE_PORTUGUESE_BRAZILIAN:
+ pLangTab = aImplLangPortugueseTab;
+ break;
+
+ case LANGUAGE_SPANISH:
+ pLangTab = aImplLangSpanishTab;
+ break;
+
+ case LANGUAGE_SWEDISH:
+ pLangTab = aImplLangSwedishTab;
+ break;
+
+ default:
+ pLangTab = aImplLangEnglishTab;
+ break;
+ }
+
+ return pLangTab;
+}
diff --git a/vcl/os2/source/app/salshl.cxx b/vcl/os2/source/app/salshl.cxx
new file mode 100644
index 000000000000..c81cee1c67f1
--- /dev/null
+++ b/vcl/os2/source/app/salshl.cxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * $RCSfile: salshl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <tools/svpm.h>
+
+#define _SV_SALSHL_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// =======================================================================
+
+SalShlData aSalShlData;
+
+// =======================================================================
+
+HPOINTER ImplLoadPointer( ULONG nId )
+{
+ return WinLoadPointer( HWND_DESKTOP, aSalShlData.mhMod, nId );
+}
+
diff --git a/vcl/os2/source/app/salsound.cxx b/vcl/os2/source/app/salsound.cxx
new file mode 100644
index 000000000000..45bf1ee67153
--- /dev/null
+++ b/vcl/os2/source/app/salsound.cxx
@@ -0,0 +1,421 @@
+/*************************************************************************
+ *
+ * $RCSfile: salsound.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALSOUND_CXX
+
+// ------------
+// - Includes -
+// ------------
+
+#include <string.h>
+
+#define INCL_DOSMODULEMGR
+#include <tools/svpm.h>
+
+#ifndef _SV_SALSOUND_HXX
+#include <salsound.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+
+#define INCL_MCIOS2
+#include <os2me.h>
+
+// ---------
+// - Names -
+// ---------
+
+#define SOUND_LIBNAME "MDM"
+#define SOUND_PROCNAME "mciSendCommand"
+
+// ------------
+// - Fnc cast -
+// ------------
+
+typedef ULONG (_cdecl *SALMCIPROC)( USHORT nDeviceId, USHORT nMessage, ULONG nFlags, void* pParam, USHORT );
+#define MCIFNC ( (SALMCIPROC) SalSound::mpMCIFnc )
+
+// -----------------
+// - Statics init. -
+// -----------------
+
+HMODULE SalSound::mhMCILib = 0;
+ULONG SalSound::mnSoundState = SOUND_STATE_UNLOADED;
+void* SalSound::mpMCIFnc = NULL;
+
+// -------------------
+// - Window-Callback -
+// -------------------
+
+MRESULT EXPENTRY SoundWndProc( HWND hWnd, ULONG nMsg, MPARAM nPar1, MPARAM nPar2 )
+{
+ if( MM_MCINOTIFY == nMsg )
+ {
+ USHORT nNotify = (USHORT)(ULONG) nPar1;
+ SoundNotification eNotification;
+ BOOL bNotify = TRUE;
+
+ switch( nNotify )
+ {
+ case( MCI_NOTIFY_SUCCESSFUL ):
+ eNotification = SOUND_NOTIFY_SUCCESS;
+ break;
+
+ case( MCI_NOTIFY_ABORTED ):
+ eNotification = SOUND_NOTIFY_ABORTED;
+ break;
+
+ case( MCI_NOTIFY_SUPERSEDED ):
+ bNotify = FALSE;
+ break;
+
+ default:
+ eNotification = SOUND_NOTIFY_ERROR;
+ break;
+ }
+
+ if( bNotify )
+ ( (SalSound*) WinQueryWindowULong( hWnd, 0 ) )->ImplNotify( eNotification, 0 );
+ }
+
+ return WinDefWindowProc( hWnd, nMsg, nPar1, nPar2 );
+}
+
+// ------------
+// - SalSound -
+// ------------
+
+SalSound::SalSound() :
+ mpProc ( NULL ),
+ mhSoundWnd ( 0 ),
+ mnDeviceId ( 0 ),
+ mbLoop ( FALSE ),
+ mbPaused ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------------
+
+SalSound::~SalSound()
+{
+ Stop();
+
+ if( mnDeviceId )
+ {
+ MCI_GENERIC_PARMS aGenericParams;
+ memset( &aGenericParams, 0, sizeof( aGenericParams ) );
+ aGenericParams.hwndCallback = mhSoundWnd;
+ MCIFNC( mnDeviceId, MCI_CLOSE, MCI_WAIT, &aGenericParams, 0 );
+ }
+
+ if( mhSoundWnd )
+ WinDestroyWindow( mhSoundWnd );
+}
+
+// ------------------------------------------------------------------------
+
+void SalSound::ImplSetError( ULONG nMciErr )
+{
+ struct aMapper { DWORD nMci; ULONG nSv; };
+
+ ULONG nError = SOUNDERR_GENERAL_ERROR;
+ static aMapper aErrArr[] =
+ {
+ { 0, SOUNDERR_SUCCESS },
+ { MCIERR_CANNOT_LOAD_DRIVER, SOUNDERR_CANNOT_LOAD_DRIVER },
+ { MCIERR_DEVICE_LOCKED, SOUNDERR_DEVICE_LOCKED },
+ { MCIERR_DEVICE_NOT_READY, SOUNDERR_DEVICE_NOT_READY },
+ { MCIERR_DEVICE_TYPE_REQUIRED, SOUNDERR_DEVICE_NOT_FOUND },
+ { MCIERR_DRIVER, SOUNDERR_CANNOT_LOAD_DRIVER },
+ { MCIERR_DRIVER_INTERNAL, SOUNDERR_CANNOT_LOAD_DRIVER },
+ { MCIERR_EXTENSION_NOT_FOUND, SOUNDERR_SOUND_NOT_FOUND },
+ { MCIERR_FILE_NOT_FOUND, SOUNDERR_SOUND_NOT_FOUND },
+ { MCIERR_HARDWARE, SOUNDERR_HARDWARE_ERROR },
+ { MCIERR_INVALID_DEVICE_NAME, SOUNDERR_DEVICE_NOT_FOUND },
+ { MCIERR_OUT_OF_MEMORY, SOUNDERR_OUT_OF_MEMORY },
+ { MCIERR_UNSUPPORTED_FUNCTION, SOUNDERR_UNSUPPORTED_FUNCTION }
+ };
+
+ for( USHORT n=0; n < (sizeof( aErrArr ) / sizeof( aMapper ) ); n++ )
+ {
+ if( aErrArr[ n ].nMci == nMciErr )
+ {
+ nError = aErrArr[ n ].nSv;
+ break;
+ }
+ }
+
+ if( nError )
+ ImplNotify( SOUND_NOTIFY_ERROR, nError );
+}
+
+// ------------------------------------------------------------------------
+
+void SalSound::ImplNotify( SoundNotification eNotification, ULONG nError )
+{
+ if( mbLoop && ( SOUND_NOTIFY_SUCCESS == eNotification ) && !nError )
+ Play( mnStartTime, mnPlayLen, TRUE );
+
+ if( mpProc && mpInst )
+ mpProc( mpInst, eNotification, nError );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalSound::Create()
+{
+ SalData* pData = GetSalData();
+ BOOL bRet = FALSE;
+
+ if( SOUND_STATE_UNLOADED == SalSound::mnSoundState )
+ {
+ if( DosLoadModule( 0, 0, SOUND_LIBNAME, &SalSound::mhMCILib ) == 0 &&
+ DosQueryProcAddr( SalSound::mhMCILib, 0, SOUND_PROCNAME, (PFN*) &SalSound::mpMCIFnc ) == 0 )
+ {
+ char* pszClassName = "SoundWin";
+ PFNWP pWindowProc = SoundWndProc;
+
+ WinRegisterClass( pData->mhAB, pszClassName, pWindowProc, 0L, 4 );
+ SalSound::mnSoundState = SOUND_STATE_VALID;
+ bRet = TRUE;
+ }
+ else
+ {
+ if( SalSound::mhMCILib )
+ DosFreeModule( SalSound::mhMCILib );
+
+ SalSound::mnSoundState = SOUND_STATE_INVALID;
+ ImplNotify( SOUND_NOTIFY_ERROR, SOUNDERR_CANNOT_LOAD_DRIVER );
+ }
+ }
+ else if( SOUND_STATE_VALID == SalSound::mnSoundState )
+ bRet = TRUE;
+
+ if( bRet )
+ {
+ mhSoundWnd = WinCreateWindow( HWND_OBJECT, "SoundWin", "Sound", 0, 0, 0, 0, 0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 );
+ WinSetWindowULong( mhSoundWnd, 0, (ULONG) this );
+ }
+ else
+ mhSoundWnd = 0;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void SalSound::Release()
+{
+ if( SalSound::mhMCILib )
+ DosFreeModule( SalSound::mhMCILib );
+
+ SalSound::mnSoundState = SOUND_STATE_UNLOADED;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalSound::Init( SalFrame* pFrame, const String& rSoundName, ULONG& rSoundLen )
+{
+ MCI_OPEN_PARMS aOpenParams;
+ ULONG nMciErr = 0;
+
+ rSoundLen = 0;
+
+ // clear old device
+ if( mnDeviceId )
+ {
+ Stop();
+
+ MCI_GENERIC_PARMS aGenericParams;
+ memset( &aGenericParams, 0, sizeof( aGenericParams ) );
+ aGenericParams.hwndCallback = mhSoundWnd;
+ nMciErr = MCIFNC( mnDeviceId, MCI_CLOSE, MCI_WAIT, &aGenericParams, 0 );
+ mnDeviceId = 0;
+ }
+
+ if( rSoundName.Len() )
+ {
+ // init new device with sound name
+ memset( &aOpenParams, 0, sizeof( aOpenParams ) );
+ aOpenParams.pszElementName = (char*) rSoundName.GetStr();
+ aOpenParams.hwndCallback = mhSoundWnd;
+ nMciErr = MCIFNC( 0, MCI_OPEN, MCI_WAIT | MCI_OPEN_ELEMENT, &aOpenParams, 0 );
+
+ if( !nMciErr )
+ {
+ // set time format
+ MCI_SET_PARMS aSetParams;
+ memset( &aSetParams, 0, sizeof( aSetParams ) );
+ mnDeviceId = aOpenParams.usDeviceID;
+ aSetParams.ulTimeFormat = MCI_FORMAT_MILLISECONDS;
+ nMciErr = MCIFNC( mnDeviceId, MCI_SET, MCI_WAIT | MCI_SET_TIME_FORMAT, &aSetParams, 0 );
+
+ if( !nMciErr )
+ {
+ // get length of sound
+ MCI_STATUS_PARMS aStatus;
+ memset( &aStatus, 0, sizeof( aStatus ) );
+ aStatus.ulItem = MCI_STATUS_LENGTH;
+ MCIFNC( mnDeviceId, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, &aStatus, 0 );
+ rSoundLen = (ULONG) aStatus.ulReturn;
+ }
+ }
+ }
+
+ if( nMciErr )
+ ImplSetError( nMciErr );
+
+ return( nMciErr ? FALSE : TRUE );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalSound::Init( SalFrame* pFrame, const BYTE* pSound, ULONG nDataLen, ULONG& rSoundLen )
+{
+ rSoundLen = 0UL;
+ ImplSetError( MCIERR_FILE_NOT_FOUND );
+
+ return FALSE;
+}
+
+// ------------------------------------------------------------------------
+
+void SalSound::Play( ULONG nStartTime, ULONG nPlayLen, BOOL bLoop )
+{
+ if( mnDeviceId )
+ {
+ ULONG nMciErr = 0;
+
+ if( !mbPaused )
+ {
+ MCI_SEEK_PARMS aSeekParams;
+ memset( &aSeekParams, 0, sizeof( aSeekParams ) );
+ aSeekParams.hwndCallback = mhSoundWnd;
+ aSeekParams.ulTo = 0;
+ nMciErr = MCIFNC( mnDeviceId, MCI_SEEK,MCI_WAIT | MCI_TO, &aSeekParams, 0 );
+ }
+
+ mnStartTime = nStartTime;
+ mnPlayLen = nPlayLen;
+ mbLoop = bLoop;
+ mbPaused = FALSE;
+
+ if( !nMciErr )
+ {
+ MCI_PLAY_PARMS aPlayParams;
+ DWORD nFlags = MCI_NOTIFY;
+
+ memset( &aPlayParams, 0, sizeof( aPlayParams ) );
+ aPlayParams.hwndCallback = mhSoundWnd;
+
+ if( nStartTime )
+ {
+ aPlayParams.ulFrom = nStartTime;
+ nFlags |= MCI_FROM;
+ }
+
+ if( nPlayLen != SOUND_PLAYALL )
+ {
+ aPlayParams.ulTo = nStartTime + nPlayLen;
+ nFlags |= MCI_TO;
+ }
+
+ nMciErr = MCIFNC( mnDeviceId, MCI_PLAY, nFlags, &aPlayParams, 0 );
+
+ if( !nMciErr )
+ mbPaused = FALSE;
+ }
+
+ if( nMciErr )
+ ImplSetError( nMciErr );
+ }
+ else
+ ImplSetError( MCIERR_EXTENSION_NOT_FOUND );
+}
+
+// ------------------------------------------------------------------------
+
+void SalSound::Stop()
+{
+ if( mnDeviceId )
+ {
+ MCI_GENERIC_PARMS aGenericParams;
+ memset( &aGenericParams, 0, sizeof( aGenericParams ) );
+ aGenericParams.hwndCallback = mhSoundWnd;
+ mbLoop = mbPaused = FALSE;
+ MCIFNC( mnDeviceId, MCI_STOP, MCI_WAIT, &aGenericParams, 0 );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SalSound::Pause()
+{
+ if( mnDeviceId )
+ {
+ MCI_GENERIC_PARMS aGenericParams;
+ memset( &aGenericParams, 0, sizeof( aGenericParams ) );
+ aGenericParams.hwndCallback = mhSoundWnd;
+ mbPaused = TRUE;
+ MCIFNC( mnDeviceId, MCI_PAUSE, MCI_WAIT, &aGenericParams, 0 );
+ }
+}
diff --git a/vcl/os2/source/app/salsys.cxx b/vcl/os2/source/app/salsys.cxx
new file mode 100644
index 000000000000..54244723be33
--- /dev/null
+++ b/vcl/os2/source/app/salsys.cxx
@@ -0,0 +1,287 @@
+/*************************************************************************
+ *
+ * $RCSfile: salsys.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALSYS_CXX
+
+#include <string.h>
+
+#define INCL_DOS
+#define INCL_DOSERRORS
+#ifndef _SVPM_H
+#include <tools/svpm.h>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+#ifndef _VOS_PROCESS_HXX
+#include <vos/process.hxx>
+#endif
+#ifndef _TOOLS_FASTFSYS_HXX
+#include <tools/fastfsys.hxx>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+// =======================================================================
+
+SalSystem* SalInstance::CreateSystem()
+{
+ return new SalSystem();
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroySystem( SalSystem* pSystem )
+{
+ delete pSystem;
+}
+
+// -----------------------------------------------------------------------
+
+SalSystem::SalSystem()
+{
+}
+
+// -----------------------------------------------------------------------
+
+SalSystem::~SalSystem()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalSystem::StartProcess( SalFrame* pFrame, const XubString& rFileName,
+ const XubString& rParam,
+ const XubString& rWorkingDirectory )
+{
+ ItemIDPath aFile(rFileName);
+
+ //
+ // first check if item has a context menu with open command
+ //
+
+ ItemIDPath aParent, aChild;
+
+ if(aFile.Split(aParent, aChild))
+ {
+ IfcContextMenu *pConMenu = Folder(aParent).GetContextMenu(1, &aChild);
+
+ if(pConMenu)
+ {
+ UINT32 nCount = pConMenu->GetItemCount();
+
+ for(UINT32 n = 0; n < nCount; n++)
+ {
+ MenuItem aMenuItem;
+
+ if(pConMenu->GetMenuItem(n, aMenuItem) &&
+ aMenuItem.aVerb.Compare("open") == COMPARE_EQUAL)
+ {
+ return pConMenu->ExecuteCommand(aMenuItem.aCommand);
+ }
+ }
+ }
+ }
+
+ // Dateinamen mit Wildcards lehnen wir ab
+ if ( (rFileName.Search( '*' ) != STRING_NOTFOUND) ||
+ (rFileName.Search( '?' ) != STRING_NOTFOUND) )
+ return FALSE;
+
+ XubString aFileName = aFile.GetHostNotationPath();
+ char* aStdExtAry[] = { "exe", "com", "cmd", "bat" };
+ const char* pStdExt;
+ const xub_Unicode* pFileName = aFileName.GetStr();
+ const xub_Unicode* pParam = rParam.GetStr();
+ XubString aSearchFileName;
+ XubString aExt;
+ BOOL bExe = FALSE;
+ BOOL bProcess = FALSE;
+ BOOL bRet = FALSE;
+ BOOL bExtension;
+ int i;
+
+ // Parameter und Extension ermitteln
+ if ( !rParam.Len() )
+ pParam = NULL;
+ // Wenn keine Extension, dann versuchen wir eine zu ermitteln,
+ // indem wir nach EXE-, COM-, CMD- oder BAT-Dateien suchen.
+ bExtension = ImplSalGetExtension( aFileName, aExt );
+ if ( !bExtension )
+ {
+ i = 0;
+ do
+ {
+ pStdExt = aStdExtAry[i];
+ aSearchFileName = aFileName;
+ aSearchFileName += '.';
+ aSearchFileName += pStdExt;
+ if ( ImplSalFindFile( aSearchFileName.GetStr(), aSearchFileName ) )
+ {
+ pFileName = aSearchFileName.GetStr();
+ bExtension = ImplSalGetExtension( aSearchFileName, aExt );
+ break;
+ }
+ i++;
+ }
+ while ( i < 4 );
+ }
+ else
+ {
+ // Ansonsten Filename im Pfad suchen
+ if ( ImplSalFindFile( pFileName, aSearchFileName ) )
+ {
+ pFileName = aSearchFileName.GetStr();
+ bExtension = ImplSalGetExtension( aSearchFileName, aExt );
+ }
+ }
+ // Wenn wir eine Extension haben, testen wir, ob es eine
+ // Standard-Extension ist, womit wir einen Process starten koennen
+ if ( bExtension )
+ {
+ aExt.ToLower();
+ i = 0;
+ do
+ {
+ if ( aExt == aStdExtAry[i] )
+ {
+ bExe = TRUE;
+ break;
+ }
+ i++;
+ }
+ while ( i < 4 );
+ }
+
+ // change to path of executable if no working dir set
+ XubString aWorkingDir(rWorkingDirectory);
+
+ if(aWorkingDir.Len() == 0)
+ {
+ USHORT nIndex;
+
+ aWorkingDir = pFileName;
+ nIndex = aWorkingDir.SearchCharBackward("\\/:");
+
+ if(nIndex == STRING_NOTFOUND)
+ nIndex = 0;
+ else if(aWorkingDir.GetChar(nIndex) == ':')
+ aWorkingDir[nIndex++] = '\\';
+
+ aWorkingDir.Erase(nIndex);
+ }
+
+ // start executables with process execute
+ if ( bExe )
+ {
+ NAMESPACE_VOS( OProcess )::TProcessError nProcessError;
+ NAMESPACE_VOS( OProcess ) aProcess( pFileName, pParam );
+
+ aProcess.setDirectory(aWorkingDir.GetStr());
+
+ nProcessError = aProcess.execute( (NAMESPACE_VOS(OProcess)::TProcessOption)
+ (NAMESPACE_VOS(OProcess)::TOption_Detached) );
+ bRet = nProcessError == NAMESPACE_VOS( OProcess )::E_None;
+ }
+
+ // when not startet, start programm with WPS
+ if ( !bRet )
+ {
+ HOBJECT hObject = WinQueryObject( pFileName );
+ if ( hObject )
+ {
+ if ( WinOpenObject( hObject, 0, FALSE ) )
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalSystem::AddRecentDoc( SalFrame* pFrame, const XubString& rFileName )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+String SalSystem::GetSummarySystemInfos( ULONG nFlags )
+{
+ return String();
+}
+
diff --git a/vcl/os2/source/app/saltimer.cxx b/vcl/os2/source/app/saltimer.cxx
new file mode 100644
index 000000000000..284c987c4250
--- /dev/null
+++ b/vcl/os2/source/app/saltimer.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * $RCSfile: saltimer.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <tools/svpm.h>
+
+#define _SV_SALTIMER_CXX
+
+#ifndef _SV_SALINST_H
+#include <salinst.h>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+
+// =======================================================================
+
+// Maximale Periode
+#define MAX_SYSPERIOD 65533
+
+// =======================================================================
+
+void ImplSalStartTimer()
+{
+ SalData* pSalData = GetSalData();
+ SalFrame* pSalFrame = GetSalDefaultFrame();
+
+ // Periode darf nicht zu gross sein, da OS2 2.11 mit USHORT arbeitet
+ ULONG nMS = pSalData->mnNewTimerMS;
+ if ( nMS > MAX_SYSPERIOD )
+ nMS = MAX_SYSPERIOD;
+
+ // Gibt es einen Timer, dann zerstoren
+ if ( pSalData->mnTimerId )
+ WinStopTimer( pSalData->mhAB, pSalFrame->maFrameData.mhWndClient, pSalData->mnTimerId );
+
+ // Make a new timer with new period
+ pSalData->mnTimerId = WinStartTimer( pSalData->mhAB, pSalFrame->maFrameData.mhWndClient, 10, nMS );
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::Stop()
+{
+ SalData* pSalData = GetSalData();
+ SalFrame* pSalFrame = GetSalDefaultFrame();
+
+ // Exitstiert ein Timer, dann diesen zerstoeren
+ if ( pSalData->mnTimerId )
+ WinStopTimer( pSalData->mhAB, pSalFrame->maFrameData.mhWndClient, pSalData->mnTimerId );
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::SetCallback( SALTIMERPROC pProc )
+{
+ SalData* pSalData = GetSalData();
+ pSalData->mpTimerProc = pProc;
+}
diff --git a/vcl/os2/source/gdi/makefile.mk b/vcl/os2/source/gdi/makefile.mk
new file mode 100644
index 000000000000..e3a50cad9c94
--- /dev/null
+++ b/vcl/os2/source/gdi/makefile.mk
@@ -0,0 +1,94 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=SV
+TARGET=salgdi
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= salgdi.cxx \
+ salgdi2.cxx \
+ salgdi3.cxx \
+ salvd.cxx \
+ salprn.cxx \
+ salbmp.cxx \
+ salogl.cxx
+
+SLOFILES= $(SLO)$/salgdi.obj \
+ $(SLO)$/salgdi2.obj \
+ $(SLO)$/salgdi3.obj \
+ $(SLO)$/salvd.obj \
+ $(SLO)$/salprn.obj \
+ $(SLO)$/salbmp.obj \
+ $(SLO)$/salogl.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/os2/source/gdi/salbmp.cxx b/vcl/os2/source/gdi/salbmp.cxx
new file mode 100644
index 000000000000..d53814a481a5
--- /dev/null
+++ b/vcl/os2/source/gdi/salbmp.cxx
@@ -0,0 +1,760 @@
+/*************************************************************************
+ *
+ * $RCSfile: salbmp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <tools/svpm.h>
+
+#define _SV_SALBMP_CXX
+
+#ifndef _RTL_ALLOC_H_
+#include <rtl/alloc.h>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#include <string.h>
+
+// -----------
+// - Inlines -
+// -----------
+
+inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex )
+{
+ BYTE& rByte = pScanline[ nX >> 1 ];
+
+ ( nX & 1 ) ? ( rByte &= 0xf0, rByte |= ( cIndex & 0x0f ) ) :
+ ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) );
+}
+
+// -------------
+// - SalBitmap -
+// -------------
+
+SalBitmap::SalBitmap() :
+ mhDIB ( 0 ),
+ mhDIB1Subst ( 0 ),
+ mhDDB ( 0 ),
+ mnBitCount ( 0 )
+{
+}
+
+// ------------------------------------------------------------------
+
+SalBitmap::~SalBitmap()
+{
+ Destroy();
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( HANDLE hBitmap, BOOL bDIB, BOOL bCopyHandle )
+{
+ BOOL bRet = TRUE;
+
+ if( bDIB )
+ mhDIB = (HANDLE) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, TRUE ) : hBitmap );
+ else
+ mhDDB = (HBITMAP) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, FALSE ) : hBitmap );
+
+ if( mhDIB )
+ {
+ // bitmap-header is the beginning of memory block
+ PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) mhDIB;
+
+ maSize = Size( pBIH->cx, pBIH->cy );
+ mnBitCount = pBIH->cBitCount;
+
+ if( mnBitCount )
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 : ( mnBitCount <= 4 ) ? 4 : ( mnBitCount <= 8 ) ? 8 : 24;
+ }
+ else if( mhDDB )
+ {
+ BITMAPINFOHEADER2 aDDBInfoHeader;
+
+ aDDBInfoHeader.cbFix = sizeof( aDDBInfoHeader );
+
+ if( GpiQueryBitmapInfoHeader( mhDDB, &aDDBInfoHeader ) )
+ {
+ maSize = Size( aDDBInfoHeader.cx, aDDBInfoHeader.cy );
+ mnBitCount = aDDBInfoHeader.cPlanes * aDDBInfoHeader.cBitCount;
+
+ if( mnBitCount )
+ {
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 :
+ ( mnBitCount <= 4 ) ? 4 :
+ ( mnBitCount <= 8 ) ? 8 : 24;
+ }
+ }
+ else
+ {
+ mhDDB = 0;
+ bRet = FALSE;
+ }
+
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal )
+{
+ BOOL bRet = FALSE;
+
+ mhDIB = ImplCreateDIB( rSize, nBitCount, rPal );
+
+ if( mhDIB )
+ {
+ maSize = rSize;
+ mnBitCount = nBitCount;
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBitmap )
+{
+ BOOL bRet = FALSE;
+
+ if ( rSalBitmap.mhDIB || rSalBitmap.mhDDB )
+ {
+ HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB,
+ rSalBitmap.mhDIB != 0 );
+
+ if( hNewHdl )
+ {
+ if( rSalBitmap.mhDIB )
+ mhDIB = (HANDLE) hNewHdl;
+ else if( rSalBitmap.mhDDB )
+ mhDDB = (HBITMAP) hNewHdl;
+
+ maSize = rSalBitmap.maSize;
+ mnBitCount = rSalBitmap.mnBitCount;
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
+{
+ BOOL bRet = FALSE;
+
+ if( rSalBmp.mhDIB )
+ {
+ HPS hPS = pGraphics->maGraphicsData.mhPS;
+ HBITMAP hNewDDB;
+ BITMAPINFOHEADER2 aInfoHeader;
+ const Size aSize( rSalBmp.GetSize() );
+ long nFormat[ 2 ];
+
+ memset( &aInfoHeader, 0, sizeof( aInfoHeader ) );
+ aInfoHeader.cbFix = 16;
+ aInfoHeader.cx = aSize.Width();
+ aInfoHeader.cy = aSize.Height();
+
+ GpiQueryDeviceBitmapFormats( hPS, 2L, (PLONG) &nFormat );
+ aInfoHeader.cPlanes = nFormat[ 0 ];
+ aInfoHeader.cBitCount = nFormat[ 1 ];
+
+ // ! wegen Postscript-Treiber
+ if( !aInfoHeader.cBitCount )
+ aInfoHeader.cBitCount = 24;
+ else if( ( aInfoHeader.cPlanes == 1 ) && ( aInfoHeader.cBitCount == 1 ) )
+ aInfoHeader.cBitCount = 4;
+
+ // BitCount == 1 ist wegen aller moeglichen Treiberfehler nicht moeglich
+ if( rSalBmp.GetBitCount() == 1 )
+ {
+ HANDLE hTmp = ImplCreateDIB4FromDIB1( rSalBmp.mhDIB );
+ PBYTE pBits = (PBYTE) hTmp + *(ULONG*) hTmp + ImplGetDIBColorCount( hTmp ) * sizeof( RGB2 );
+
+ hNewDDB = GpiCreateBitmap( hPS, &aInfoHeader, CBM_INIT, pBits, (PBITMAPINFO2) hTmp );
+ rtl_freeMemory( hTmp );
+ }
+ else
+ {
+ PBYTE pBits = (PBYTE) rSalBmp.mhDIB + *(ULONG*) rSalBmp.mhDIB + ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGB2 );
+ hNewDDB = GpiCreateBitmap( hPS, &aInfoHeader, CBM_INIT, pBits, (PBITMAPINFO2) rSalBmp.mhDIB );
+ }
+
+ aInfoHeader.cbFix = sizeof( aInfoHeader );
+
+ if( hNewDDB && GpiQueryBitmapInfoHeader( hNewDDB, &aInfoHeader ) )
+ {
+ mhDDB = hNewDDB;
+ maSize = Size( aInfoHeader.cx, aInfoHeader.cy );
+ mnBitCount = aInfoHeader.cPlanes * aInfoHeader.cBitCount;
+
+ if( mnBitCount )
+ {
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 :
+ ( mnBitCount <= 4 ) ? 4 :
+ ( mnBitCount <= 8 ) ? 8 : 24;
+ }
+
+ bRet = TRUE;
+ }
+ else if( hNewDDB )
+ GpiDeleteBitmap( hNewDDB );
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, USHORT nNewBitCount )
+{
+ BOOL bRet = FALSE;
+
+ if( rSalBmp.mhDDB )
+ {
+ mhDIB = ImplCreateDIB( rSalBmp.maSize, nNewBitCount, BitmapPalette() );
+
+ if( mhDIB )
+ {
+ // bitmap-header is the beginning of memory block
+ PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB;
+ const int nLines = (int) rSalBmp.maSize.Height();
+ PBYTE pBits = (PBYTE) pBI + *(ULONG*) pBI + ImplGetDIBColorCount( mhDIB ) * sizeof( RGB2 );
+ SIZEL aSizeL = { rSalBmp.maSize.Width(), nLines };
+ HAB hAB = GetSalData()->mhAB;
+ DEVOPENSTRUC aDevOpenStruc = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+ HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
+ HPS hMemPS = GpiCreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
+ HBITMAP hMemOld = (HBITMAP) GpiSetBitmap( hMemPS, rSalBmp.mhDDB );
+
+ if( GpiQueryBitmapBits( hMemPS, 0, nLines, pBits, pBI ) == nLines )
+ {
+ maSize = rSalBmp.maSize;
+ mnBitCount = nNewBitCount;
+ bRet = TRUE;
+ }
+ else
+ {
+ rtl_freeMemory( mhDIB );
+ mhDIB = 0;
+ }
+
+ GpiSetBitmap( hMemPS, hMemOld );
+ GpiDestroyPS( hMemPS );
+ DevCloseDC( hMemDC );
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::Destroy()
+{
+ if( mhDIB )
+ rtl_FreeMemory( mhDIB );
+ else if( mhDDB )
+ GpiDeleteBitmap( mhDDB );
+
+ if( mhDIB1Subst )
+ {
+ rtl_FreeMemory( mhDIB1Subst );
+ mhDIB1Subst = NULL;
+ }
+
+ maSize = Size();
+ mnBitCount = 0;
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::ImplReplacehDIB1Subst( HANDLE hDIB1Subst )
+{
+ if( mhDIB1Subst )
+ rtl_FreeMemory( mhDIB1Subst );
+
+ mhDIB1Subst = hDIB1Subst;
+}
+
+// ------------------------------------------------------------------
+
+USHORT SalBitmap::ImplGetDIBColorCount( HANDLE hDIB )
+{
+ USHORT nColors = 0;
+
+ if( hDIB )
+ {
+ // bitmap infos can be found at the beginning of the memory
+ PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) hDIB;
+
+ if( pBIH->cBitCount <= 8 )
+ {
+ if( pBIH->cclrUsed )
+ nColors = (USHORT) pBIH->cclrUsed;
+ else
+ nColors = 1 << pBIH->cBitCount;
+ }
+ }
+
+ return nColors;
+}
+
+// ------------------------------------------------------------------
+
+HANDLE SalBitmap::ImplCreateDIB( const Size& rSize, USHORT nBits, const BitmapPalette& rPal )
+{
+ DBG_ASSERT( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24, "Unsupported BitCount!" );
+
+ HANDLE hDIB = 0;
+
+ if ( rSize.Width() && rSize.Height() && ( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24 ) )
+ {
+ const ULONG nImageSize = AlignedWidth4Bytes( nBits * rSize.Width() ) * rSize.Height();
+ const USHORT nColors = ( nBits <= 8 ) ? ( 1 << nBits ) : 0;
+
+ hDIB = (HANDLE) rtl_allocateZeroMemory( sizeof( BITMAPINFOHEADER2 ) + nColors * sizeof( RGB2 ) + nImageSize );
+
+ if( hDIB )
+ {
+ // bitmap infos can be found at the beginning of the memory
+ PBITMAPINFO2 pBI = (PBITMAPINFO2) hDIB;
+ PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI;
+
+ pBIH->cbFix = sizeof( BITMAPINFOHEADER2 );
+ pBIH->cx = rSize.Width();
+ pBIH->cy = rSize.Height();
+ pBIH->cPlanes = 1;
+ pBIH->cBitCount = nBits;
+ pBIH->ulCompression = BCA_UNCOMP; // BI_RGB;
+ pBIH->cbImage = nImageSize;
+ pBIH->cxResolution = 0;
+ pBIH->cyResolution = 0;
+ pBIH->cclrUsed = 0;
+ pBIH->cclrImportant = 0;
+
+ // Rest auf 0 setzen
+ memset( (PBYTE) &pBIH->usUnits, 0, (PBYTE) pBI->argbColor - (PBYTE) &pBIH->usUnits );
+
+ if( nColors )
+ {
+ const USHORT nMinCount = Min( nColors, rPal.GetEntryCount() );
+
+ if( nMinCount )
+ HMEMCPY( pBI->argbColor, rPal.ImplGetColorBuffer(), nMinCount * sizeof( RGB2 ) );
+ }
+ }
+ }
+
+ return hDIB;
+}
+
+// ------------------------------------------------------------------
+
+HANDLE SalBitmap::ImplCreateDIB4FromDIB1( HANDLE hDIB1 )
+{
+ PBITMAPINFO2 pBI = (PBITMAPINFO2) hDIB1;
+ PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI;
+ PBYTE pBits = (PBYTE) pBI + *(ULONG*) pBIH + SalBitmap::ImplGetDIBColorCount( hDIB1 ) * sizeof( RGB2 );
+ ULONG nWidth = pBIH->cx, nHeight = pBIH->cy;
+ ULONG nAligned = AlignedWidth4Bytes( nWidth );
+ ULONG nAligned4 = AlignedWidth4Bytes( nWidth << 2 );
+ ULONG nSize4 = sizeof( BITMAPINFOHEADER2 ) + ( sizeof( RGB2 ) << 4 ) + nAligned4 * nHeight;
+ PBYTE pDIB4 = (PBYTE) rtl_allocateZeroMemory( nSize4 );
+ PBITMAPINFO2 pBI4 = (PBITMAPINFO2) pDIB4;
+ PBITMAPINFOHEADER2 pBIH4 = (PBITMAPINFOHEADER2) pBI4;
+ BYTE aMap[ 4 ] = { 0x00, 0x01, 0x10, 0x11 };
+
+ memset( pBIH4, 0, sizeof( BITMAPINFOHEADER2 ) );
+ pBIH4->cbFix = sizeof( BITMAPINFOHEADER2 );
+ pBIH4->cx = nWidth;
+ pBIH4->cy = nHeight;
+ pBIH4->cPlanes = 1;
+ pBIH4->cBitCount = 4;
+
+ // die ersten beiden Eintraege der 1Bit-Farbtabelle kopieren
+ memcpy( pBI4->argbColor, pBI->argbColor, sizeof( RGB2 ) << 1 );
+
+ PBYTE pBits4 = (PBYTE) pBI4 + *(ULONG*) pBIH4 + ( sizeof( RGB2 ) << 4 );
+
+ // 4Bit-DIB-Bilddaten setzen
+ for( ULONG nY = 0UL; nY < nHeight; nY++ )
+ {
+ PBYTE pTmp = pBits; pBits += nAligned;
+ PBYTE pTmp4 = pBits4; pBits4 += nAligned4;
+
+ for( ULONG nX = 0UL; nX < nWidth; nX += 8UL )
+ {
+ *pTmp4++ = aMap[ ( *pTmp >> 6 ) & 3 ];
+ *pTmp4++ = aMap[ ( *pTmp >> 4 ) & 3 ];
+ *pTmp4++ = aMap[ ( *pTmp >> 2 ) & 3 ];
+ *pTmp4++ = aMap[ *pTmp++ & 3 ];
+ }
+ }
+
+ return (HANDLE) pDIB4;
+}
+
+// ------------------------------------------------------------------
+
+HANDLE SalBitmap::ImplCopyDIBOrDDB( HANDLE hHdl, BOOL bDIB )
+{
+ HANDLE hCopy = 0;
+
+ if( bDIB && hHdl )
+ {
+ PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) hHdl;
+ const ULONG nSize = sizeof( BITMAPINFOHEADER2 )
+ + ImplGetDIBColorCount( hHdl ) * sizeof( RGB2 ) +
+ ( pBIH->cbImage ? pBIH->cbImage : AlignedWidth4Bytes( pBIH->cx * pBIH->cBitCount ) );
+
+ BYTE* pCopy = rtl_allocateZeroMemory( nSize );
+ memcpy( pCopy, (BYTE*) hHdl, nSize );
+ hCopy = (HANDLE) pCopy;
+ }
+ else if( hHdl )
+ {
+ HAB hAB = GetSalData()->mhAB;
+ HDC hSrcMemDC;
+ HDC hDestMemDC;
+ HPS hSrcMemPS;
+ HPS hDestMemPS;
+ HBITMAP hCopyBitmap;
+ BITMAPINFOHEADER2 aInfoHeader;
+ DEVOPENSTRUC aDevOpenStruc;
+ SIZEL size;
+
+ aInfoHeader.cbFix = sizeof( BITMAPINFOHEADER2 );
+ GpiQueryBitmapInfoHeader( hHdl, &aInfoHeader );
+ size.cx = aInfoHeader.cx;
+ size.cy = aInfoHeader.cy;
+
+ // Memory DCs erzeugen
+ aDevOpenStruc.pszLogAddress = 0;
+ aDevOpenStruc.pszDriverName = (PSZ)"DISPLAY";
+
+ hSrcMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 2, (PDEVOPENDATA)&aDevOpenStruc, 0 );
+ hDestMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 2, (PDEVOPENDATA)&aDevOpenStruc, 0 );
+
+ // Memory PSs erzeugen
+ hSrcMemPS = GpiCreatePS( hAB, hSrcMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
+ hDestMemPS = GpiCreatePS( hAB, hDestMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
+
+ GpiSetBitmap( hSrcMemPS, hHdl );
+
+ if( !hHdl )
+ {
+ memset( &aInfoHeader, 0, sizeof( BITMAPINFOHEADER2 ) );
+ aInfoHeader.cbFix = sizeof( BITMAPINFOHEADER2 );
+ aInfoHeader.cx = 0;
+ aInfoHeader.cy = 0;
+ aInfoHeader.cPlanes = 1;
+ aInfoHeader.cBitCount = 1;
+ }
+
+ hCopy = GpiCreateBitmap( hDestMemPS, &aInfoHeader, 0, NULL, NULL );
+ GpiSetBitmap( hDestMemPS, hCopy );
+
+ POINTL pts[3];
+
+ pts[0].x = 0;
+ pts[0].y = 0;
+ pts[1].x = size.cx;
+ pts[1].y = size.cy;
+ pts[2].x = 0;
+ pts[2].y = 0;
+
+ GpiBitBlt( hDestMemPS, hSrcMemPS, 3, pts, ROP_SRCCOPY, BBO_IGNORE );
+
+ GpiSetBitmap( hSrcMemPS, (HBITMAP)0L);
+ GpiSetBitmap( hDestMemPS, (HBITMAP)0L);
+ GpiAssociate( hSrcMemPS, NULLHANDLE );
+ GpiAssociate( hDestMemPS, NULLHANDLE );
+ GpiDestroyPS( hSrcMemPS );
+ GpiDestroyPS( hDestMemPS );
+ DevCloseDC( hSrcMemDC );
+ DevCloseDC( hDestMemDC );
+ }
+
+ return hCopy;
+}
+
+// ------------------------------------------------------------------
+
+BitmapBuffer* SalBitmap::AcquireBuffer( BOOL bReadOnly )
+{
+ BitmapBuffer* pBuffer = NULL;
+
+ if( mhDIB )
+ {
+ // bitmap infos can be found at the beginning of the memory
+ PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB;
+ PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI;
+
+ if( ( pBIH->ulCompression == BCA_RLE4 ) || ( pBIH->ulCompression == BCA_RLE8 ) )
+ {
+ Size aSizePix( pBIH->cx, pBIH->cy );
+ HANDLE hNewDIB = ImplCreateDIB( aSizePix, pBIH->cBitCount, BitmapPalette() );
+
+ if( hNewDIB )
+ {
+ // bitmap infos can be found at the beginning of the memory
+ PBITMAPINFO2 pNewBI = (PBITMAPINFO2) hNewDIB;
+ PBITMAPINFOHEADER2 pNewBIH = (PBITMAPINFOHEADER2) pNewBI;
+ const USHORT nColorCount = ImplGetDIBColorCount( hNewDIB );
+ const ULONG nOffset = *(ULONG*) pBI + nColorCount * sizeof( RGB2 );
+ BYTE* pOldBits = (BYTE*) pBI + nOffset;
+ BYTE* pNewBits = (BYTE*) pNewBI + nOffset;
+
+ memcpy( pNewBI, pBI, nOffset );
+ pNewBIH->ulCompression = 0;
+ ImplDecodeRLEBuffer( pOldBits, pNewBits, aSizePix, pBIH->ulCompression == BCA_RLE4 );
+
+ rtl_freeMemory( mhDIB );
+
+ mhDIB = hNewDIB;
+ pBI = pNewBI;
+ pBIH = pNewBIH;
+ }
+ }
+
+ if( pBIH->cPlanes == 1 )
+ {
+ pBuffer = new BitmapBuffer;
+
+ pBuffer->mnFormat = BMP_FORMAT_BOTTOM_UP |
+ ( pBIH->cBitCount == 1 ? BMP_FORMAT_1BIT_MSB_PAL :
+ pBIH->cBitCount == 4 ? BMP_FORMAT_4BIT_MSN_PAL :
+ pBIH->cBitCount == 8 ? BMP_FORMAT_8BIT_PAL :
+ pBIH->cBitCount == 16 ? BMP_FORMAT_16BIT_TC_MASK :
+ pBIH->cBitCount == 24 ? BMP_FORMAT_24BIT_TC_BGR :
+ pBIH->cBitCount == 32 ? BMP_FORMAT_32BIT_TC_MASK : 0UL );
+
+ if( BMP_SCANLINE_FORMAT( pBuffer->mnFormat ) )
+ {
+ pBuffer->mnWidth = maSize.Width();
+ pBuffer->mnHeight = maSize.Height();
+ pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->cBitCount );
+ pBuffer->mnBitCount = (USHORT) pBIH->cBitCount;
+
+ if( pBuffer->mnBitCount <= 8 )
+ {
+ const USHORT nPalCount = ImplGetDIBColorCount( mhDIB );
+
+ pBuffer->maPalette.SetEntryCount( nPalCount );
+
+ if( nPalCount )
+ memcpy( pBuffer->maPalette.ImplGetColorBuffer(), pBI->argbColor, nPalCount * sizeof( RGB2 ) );
+
+ pBuffer->mpBits = (BYTE*) pBI + *(ULONG*) pBI + nPalCount * sizeof( RGB2 );
+ }
+ else
+ pBuffer->mpBits = (BYTE*) pBI + *(ULONG*) pBI;
+ }
+ else
+ {
+ delete pBuffer;
+ pBuffer = NULL;
+ }
+ }
+ }
+
+ if( pBuffer && mhDIB1Subst )
+ {
+ rtl_FreeMemory( mhDIB1Subst );
+ mhDIB1Subst = 0;
+ }
+
+ return pBuffer;
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BOOL bReadOnly )
+{
+ if( pBuffer )
+ {
+ if( mhDIB )
+ {
+ if( !bReadOnly && !!pBuffer->maPalette )
+ {
+ // bitmap infos can be found at the beginning of the memory
+ PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB;
+ const USHORT nCount = pBuffer->maPalette.GetEntryCount();
+
+ if( nCount )
+ memcpy( pBI->argbColor, pBuffer->maPalette.ImplGetColorBuffer(), nCount * sizeof( RGB2 ) );
+ }
+ }
+
+ delete pBuffer;
+ }
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::ImplDecodeRLEBuffer( const BYTE* pSrcBuf, BYTE* pDstBuf,
+ const Size& rSizePixel, BOOL bRLE4 )
+{
+ HPBYTE pRLE = (HPBYTE) pSrcBuf;
+ HPBYTE pDIB = (HPBYTE) pDstBuf;
+ HPBYTE pRow = (HPBYTE) pDstBuf;
+ ULONG nWidthAl = AlignedWidth4Bytes( rSizePixel.Width() * ( bRLE4 ? 4UL : 8UL ) );
+ HPBYTE pLast = pDIB + rSizePixel.Height() * nWidthAl - 1;
+ ULONG nCountByte;
+ ULONG nRunByte;
+ ULONG nX = 0;
+ ULONG i;
+ BYTE cTmp;
+ BOOL bEndDecoding = FALSE;
+
+ if( pRLE && pDIB )
+ {
+ do
+ {
+ if( !( nCountByte = *pRLE++ ) )
+ {
+ nRunByte = *pRLE++;
+
+ if( nRunByte > 2UL )
+ {
+ if( bRLE4 )
+ {
+ nCountByte = nRunByte >> 1UL;
+
+ for( i = 0; i < nCountByte; i++ )
+ {
+ cTmp = *pRLE++;
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
+ }
+
+ if( nRunByte & 1 )
+ ImplSetPixel4( pDIB, nX++, *pRLE++ >> 4 );
+
+ if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
+ pRLE++;
+ }
+ else
+ {
+ HMEMCPY( &pDIB[ nX ], pRLE, nRunByte );
+ pRLE += nRunByte;
+ nX += nRunByte;
+
+ if( nRunByte & 1 )
+ pRLE++;
+ }
+ }
+ else if( !nRunByte )
+ {
+ pDIB = ( pRow += nWidthAl );
+ nX = 0UL;
+ }
+ else if( nRunByte == 1 )
+ bEndDecoding = TRUE;
+ else
+ {
+ nX += *pRLE++;
+ pDIB = ( pRow += ( *pRLE++ ) * nWidthAl );
+ }
+ }
+ else
+ {
+ cTmp = *pRLE++;
+
+ if( bRLE4 )
+ {
+ nRunByte = nCountByte >> 1;
+
+ for( i = 0; i < nRunByte; i++ )
+ {
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
+ }
+
+ if( nCountByte & 1 )
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ }
+ else
+ {
+ for( i = 0; i < nCountByte; i++ )
+ pDIB[ nX++ ] = cTmp;
+ }
+ }
+ }
+ while( !bEndDecoding && ( pDIB <= pLast ) );
+ }
+}
diff --git a/vcl/os2/source/gdi/salgdi.cxx b/vcl/os2/source/gdi/salgdi.cxx
new file mode 100644
index 000000000000..f501f8da303e
--- /dev/null
+++ b/vcl/os2/source/gdi/salgdi.cxx
@@ -0,0 +1,852 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <tools/svpm.h>
+
+#define _SV_SALGDI_CXX
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+// ClipRegions funktionieren immer noch nicht auf allen getesteten Druckern
+#define SAL_PRINTER_CLIPPATH 1
+// #define SAL_PRINTER_POLYPATH 1
+
+// =======================================================================
+
+void ImplInitSalGDI()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFreeSalGDI()
+{
+}
+
+// =======================================================================
+
+void ImplSalInitGraphics( SalGraphicsData* pData )
+{
+ GpiCreateLogColorTable( pData->mhPS, LCOL_RESET, LCOLF_RGB, 0, 0, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalDeInitGraphics( SalGraphicsData* pData )
+{
+}
+
+// =======================================================================
+
+SalGraphics::SalGraphics()
+{
+ maGraphicsData.mhPS = 0;
+ maGraphicsData.mhDC = 0;
+ maGraphicsData.mbLine = FALSE;
+ maGraphicsData.mbFill = FALSE;
+ maGraphicsData.mbXORMode = FALSE;
+ maGraphicsData.mbFontIsOutline = FALSE;
+ maGraphicsData.mbFontIsFixed = FALSE;
+ maGraphicsData.mnFontMetricCount = 0;
+ maGraphicsData.mpFontMetrics = NULL;
+ maGraphicsData.mpClipRectlAry = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics::~SalGraphics()
+{
+ if ( maGraphicsData.mpFontMetrics )
+ delete maGraphicsData.mpFontMetrics;
+}
+
+// -----------------------------------------------------------------------
+
+static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
+{
+ SalColor nSalColor;
+
+ switch( nROPColor )
+ {
+ case SAL_ROP_0:
+ nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
+ break;
+
+ case SAL_ROP_1:
+ case SAL_ROP_INVERT:
+ nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
+ break;
+ }
+
+ return nSalColor;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetResolution( long& rDPIX, long& rDPIY )
+{
+ long nResolution;
+
+ // convert resolution from pels per meter to pels per inch
+ DevQueryCaps( maGraphicsData.mhDC, CAPS_HORIZONTAL_RESOLUTION, 1, &nResolution );
+ rDPIX = (nResolution * 100) / 3937;
+
+ // convert resolution from pels per meter to pels per inch
+ DevQueryCaps( maGraphicsData.mhDC, CAPS_VERTICAL_RESOLUTION, 1, &nResolution );
+ rDPIY = (nResolution * 100) / 3937;
+
+ if ( rDPIY < 96 )
+ {
+ rDPIX = (rDPIX*96) / rDPIY;
+ rDPIY = 96;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetScreenFontResolution( long& rDPIX, long& rDPIY )
+{
+ DevQueryCaps( maGraphicsData.mhDC, CAPS_HORIZONTAL_FONT_RES, 1, &rDPIX );
+ DevQueryCaps( maGraphicsData.mhDC, CAPS_VERTICAL_FONT_RES, 1, &rDPIY );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalGraphics::GetBitCount()
+{
+ LONG nBitCount;
+ DevQueryCaps( maGraphicsData.mhDC, CAPS_COLOR_BITCOUNT, 1, &nBitCount );
+ return (USHORT)nBitCount;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::ResetClipRegion()
+{
+#ifdef SAL_PRINTER_CLIPPATH
+ if ( maGraphicsData.mbPrinter )
+ GpiSetClipPath( maGraphicsData.mhPS, 0, SCP_RESET );
+ else
+#endif
+ {
+ HRGN hOldRegion;
+
+ GpiSetClipRegion( maGraphicsData.mhPS, NULL, &hOldRegion );
+ if ( hOldRegion )
+ GpiDestroyRegion( maGraphicsData.mhPS, hOldRegion );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::BeginSetClipRegion( ULONG nCount )
+{
+ maGraphicsData.mpClipRectlAry = new RECTL[ nCount ];
+ maGraphicsData.mnClipElementCount = 0;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalGraphics::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ RECTL* pClipRect = &maGraphicsData.mpClipRectlAry[ maGraphicsData.mnClipElementCount ];
+ pClipRect->xLeft = nX;
+ pClipRect->yTop = maGraphicsData.mnHeight - nY;
+ pClipRect->xRight = nX + nWidth;
+ pClipRect->yBottom = maGraphicsData.mnHeight - (nY + nHeight);
+ maGraphicsData.mnClipElementCount++;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::EndSetClipRegion()
+{
+#ifdef SAL_PRINTER_CLIPPATH
+ if ( maGraphicsData.mbPrinter )
+ {
+ GpiSetClipPath( maGraphicsData.mhPS, 0, SCP_RESET );
+ GpiBeginPath( maGraphicsData.mhPS, 1L );
+
+ for( int i = 0; i < maGraphicsData.mnClipElementCount; i++ )
+ {
+ POINTL aPt;
+ RECTL* pClipRect = &maGraphicsData.mpClipRectlAry[ i ];
+
+ aPt.x = pClipRect->xLeft;
+ aPt.y = pClipRect->yTop-1;
+ GpiMove( maGraphicsData.mhPS, &aPt );
+
+ aPt.x = pClipRect->xRight-1;
+ aPt.y = pClipRect->yBottom;
+
+ GpiBox( maGraphicsData.mhPS, DRO_OUTLINE, &aPt, 0, 0 );
+ }
+
+ GpiEndPath( maGraphicsData.mhPS );
+ GpiSetClipPath( maGraphicsData.mhPS, 1L, SCP_ALTERNATE | SCP_AND );
+ }
+ else
+#endif
+ {
+ HRGN hClipRegion = GpiCreateRegion( maGraphicsData.mhPS,
+ maGraphicsData.mnClipElementCount,
+ maGraphicsData.mpClipRectlAry );
+ HRGN hOldRegion;
+
+ GpiSetClipRegion( maGraphicsData.mhPS, hClipRegion, &hOldRegion );
+ if( hOldRegion )
+ GpiDestroyRegion( maGraphicsData.mhPS, hOldRegion );
+ }
+
+ delete [] maGraphicsData.mpClipRectlAry;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetLineColor()
+{
+ // don't draw line!
+ maGraphicsData.mbLine = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetLineColor( SalColor nSalColor )
+{
+ LINEBUNDLE lb;
+
+ // set color
+ lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ GpiSetAttrs( maGraphicsData.mhPS,
+ PRIM_LINE,
+ LBB_COLOR,
+ 0,
+ &lb );
+
+ // draw line!
+ maGraphicsData.mbLine = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetFillColor()
+{
+ // don't fill area!
+ maGraphicsData.mbFill = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetFillColor( SalColor nSalColor )
+{
+ AREABUNDLE ab;
+
+ // set color
+ ab.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ GpiSetAttrs( maGraphicsData.mhPS,
+ PRIM_AREA,
+ ABB_COLOR,
+ 0,
+ &ab );
+
+ // fill area!
+ maGraphicsData.mbFill = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetXORMode( BOOL bSet )
+{
+ maGraphicsData.mbXORMode = bSet;
+ LONG nMixMode = bSet ? FM_XOR : FM_OVERPAINT;
+
+ // set mix mode for lines
+ LINEBUNDLE lb;
+ lb.usMixMode = nMixMode;
+ GpiSetAttrs( maGraphicsData.mhPS,
+ PRIM_LINE,
+ LBB_MIX_MODE,
+ 0,
+ &lb );
+
+ // set mix mode for areas
+ AREABUNDLE ab;
+ ab.usMixMode = nMixMode;
+ GpiSetAttrs( maGraphicsData.mhPS,
+ PRIM_AREA,
+ ABB_MIX_MODE,
+ 0,
+ &ab );
+
+ // set mix mode for text
+ CHARBUNDLE cb;
+ cb.usMixMode = nMixMode;
+ GpiSetAttrs( maGraphicsData.mhPS,
+ PRIM_CHAR,
+ CBB_MIX_MODE,
+ 0,
+ &cb );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetROPLineColor( SalROPColor nROPColor )
+{
+ SetLineColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetROPFillColor( SalROPColor nROPColor )
+{
+ SetFillColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPixel( long nX, long nY )
+{
+ POINTL aPt;
+
+ aPt.x = nX;
+ aPt.y = TY( nY );
+
+ // set color
+ GpiSetPel( maGraphicsData.mhPS, &aPt );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPixel( long nX, long nY, SalColor nSalColor )
+{
+ // save old color
+ LINEBUNDLE oldLb;
+ GpiQueryAttrs( maGraphicsData.mhPS,
+ PRIM_LINE,
+ LBB_COLOR,
+ &oldLb );
+
+ // set new color
+ LINEBUNDLE lb;
+ lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+ GpiSetAttrs( maGraphicsData.mhPS,
+ PRIM_LINE,
+ LBB_COLOR,
+ 0,
+ &lb );
+
+ // set color of pixel
+ POINTL aPt;
+ aPt.x = nX;
+ aPt.y = TY( nY );
+ GpiSetPel( maGraphicsData.mhPS, &aPt );
+
+ // restore old color
+ GpiSetAttrs( maGraphicsData.mhPS,
+ PRIM_LINE,
+ LBB_COLOR,
+ 0,
+ &oldLb );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ // OS2 zeichnet den Endpunkt mit
+ POINTL aPt;
+ aPt.x = nX1;
+ aPt.y = TY( nY1 );
+ GpiMove( maGraphicsData.mhPS, &aPt );
+ aPt.x = nX2;
+ aPt.y = TY( nY2 );
+ GpiLine( maGraphicsData.mhPS, &aPt );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ POINTL aPt;
+ long lControl;
+
+ if ( maGraphicsData.mbFill )
+ {
+ if ( maGraphicsData.mbLine )
+ lControl = DRO_OUTLINEFILL;
+ else
+ lControl = DRO_FILL;
+ }
+ else
+ {
+ if ( maGraphicsData.mbLine )
+ lControl = DRO_OUTLINE;
+ else
+ return;
+ }
+
+ aPt.x = nX;
+ aPt.y = TY( nY );
+ GpiMove( maGraphicsData.mhPS, &aPt );
+ aPt.x = nX + nWidth - 1;
+ aPt.y = TY( nY + nHeight - 1 );
+ GpiBox( maGraphicsData.mhPS, lControl, &aPt, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolyLine( ULONG nPoints, const SalPoint* pPtAry )
+{
+ // convert all points to sys orientation
+ POINTL* pOS2PtAry = new POINTL[ nPoints ];
+ POINTL* pTempOS2PtAry = pOS2PtAry;
+ const SalPoint* pTempPtAry = pPtAry;
+ ULONG nTempPoints = nPoints;
+ long nHeight = maGraphicsData.mnHeight - 1;
+
+ while( nTempPoints-- )
+ {
+ (*pTempOS2PtAry).x = (*pTempPtAry).mnX;
+ (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
+ pTempOS2PtAry++;
+ pTempPtAry++;
+ }
+
+ GpiMove( maGraphicsData.mhPS, pOS2PtAry );
+ GpiPolyLine( maGraphicsData.mhPS, nPoints, pOS2PtAry );
+ delete [] pOS2PtAry;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolygon( ULONG nPoints, const SalPoint* pPtAry )
+{
+ POLYGON aPolygon;
+
+ // create polygon
+ aPolygon.aPointl = new POINTL[ nPoints ];
+ aPolygon.ulPoints = nPoints;
+
+ // convert all points to sys orientation
+ POINTL* pTempOS2PtAry = aPolygon.aPointl;
+ const SalPoint* pTempPtAry = pPtAry;
+ ULONG nTempPoints = nPoints;
+ long nHeight = maGraphicsData.mnHeight - 1;
+
+ while( nTempPoints-- )
+ {
+ (*pTempOS2PtAry).x = (*pTempPtAry).mnX;
+ (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
+ pTempOS2PtAry++;
+ pTempPtAry++;
+ }
+
+ // Innenleben zeichnen
+ if ( maGraphicsData.mbFill )
+ {
+#ifdef SAL_PRINTER_POLYPATH
+ if ( maGraphicsData.mbPrinter )
+ {
+ GpiBeginPath( maGraphicsData.mhPS, 1 );
+ GpiMove( maGraphicsData.mhPS, aPolygon.aPointl );
+ GpiPolyLine( maGraphicsData.mhPS, aPolygon.ulPoints, aPolygon.aPointl );
+ GpiEndPath( maGraphicsData.mhPS );
+ GpiFillPath( maGraphicsData.mhPS, 1, 0 );
+
+ if ( maGraphicsData.mbLine )
+ {
+ GpiMove( maGraphicsData.mhPS, aPolygon.aPointl );
+ GpiPolyLine( maGraphicsData.mhPS, aPolygon.ulPoints, aPolygon.aPointl );
+ }
+ }
+ else
+#endif
+ {
+ ULONG nOptions = POLYGON_ALTERNATE;
+
+ if ( maGraphicsData.mbLine )
+ nOptions |= POLYGON_BOUNDARY;
+ else
+ nOptions |= POLYGON_NOBOUNDARY;
+
+ GpiMove( maGraphicsData.mhPS, aPolygon.aPointl );
+ GpiPolygons( maGraphicsData.mhPS, 1, &aPolygon, nOptions, POLYGON_EXCL );
+ }
+ }
+ else
+ {
+ if ( maGraphicsData.mbLine )
+ {
+ GpiMove( maGraphicsData.mhPS, aPolygon.aPointl );
+ GpiPolyLine( maGraphicsData.mhPS, nPoints, aPolygon.aPointl );
+ }
+ }
+
+ delete [] aPolygon.aPointl;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolyPolygon( ULONG nPoly, const ULONG* pPoints,
+ PCONSTSALPOINT* pPtAry )
+{
+ ULONG i;
+ long nHeight = maGraphicsData.mnHeight - 1;
+ POLYGON* aPolygonAry = new POLYGON[ nPoly ];
+
+ for( i = 0; i < nPoly; i++ )
+ {
+ const SalPoint * pTempPtAry = (const SalPoint*)pPtAry[ i ];
+
+ // create polygon
+ ULONG nTempPoints = pPoints[ i ];
+ POINTL * pTempOS2PtAry = new POINTL[ nTempPoints ];
+
+ // convert all points to sys orientation
+ aPolygonAry[ i ].ulPoints = nTempPoints;
+ aPolygonAry[ i ].aPointl = pTempOS2PtAry;
+
+ while( nTempPoints-- )
+ {
+ (*pTempOS2PtAry).x = (*pTempPtAry).mnX;
+ (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
+ pTempOS2PtAry++;
+ pTempPtAry++;
+ }
+ }
+
+ // Innenleben zeichnen
+ if ( maGraphicsData.mbFill )
+ {
+#ifdef SAL_PRINTER_POLYPATH
+ if ( maGraphicsData.mbPrinter )
+ {
+ GpiBeginPath( maGraphicsData.mhPS, 1 );
+ for ( i = 0; i < nPoly; i++ )
+ {
+ GpiMove( maGraphicsData.mhPS, aPolygonAry[i].aPointl );
+ GpiPolyLine( maGraphicsData.mhPS, aPolygonAry[i].ulPoints, aPolygonAry[i].aPointl );
+ }
+ GpiEndPath( maGraphicsData.mhPS );
+ GpiFillPath( maGraphicsData.mhPS, 1, 0 );
+ }
+ else
+#endif
+ {
+ ULONG nOptions = POLYGON_ALTERNATE;
+
+ if ( maGraphicsData.mbLine )
+ nOptions |= POLYGON_BOUNDARY;
+ else
+ nOptions |= POLYGON_NOBOUNDARY;
+
+ GpiMove( maGraphicsData.mhPS, aPolygonAry[ 0 ].aPointl );
+ GpiPolygons( maGraphicsData.mhPS, nPoly, aPolygonAry, nOptions, POLYGON_EXCL );
+ }
+ }
+ else
+ {
+ if ( maGraphicsData.mbLine )
+ {
+ for( i = 0; i < nPoly; i++ )
+ {
+ GpiMove( maGraphicsData.mhPS, aPolygonAry[ i ].aPointl );
+ GpiPolyLine( maGraphicsData.mhPS, aPolygonAry[ i ].ulPoints, aPolygonAry[ i ].aPointl );
+ }
+ }
+ }
+
+ // cleanup
+ for( i = 0; i < nPoly; i++ )
+ delete [] aPolygonAry[ i ].aPointl;
+ delete [] aPolygonAry;
+}
+
+// =======================================================================
+
+// MAXIMUM BUFSIZE EQ 0xFFFF
+#define POSTSCRIPT_BUFSIZE 0x1024
+// we only try to get the BoundingBox in the first 4096 bytes
+#define POSTSCRIPT_BOUNDINGSEARCH 0x1000
+
+static BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, ULONG nComp, ULONG nSize )
+{
+ while ( nComp-- >= nSize )
+ {
+ for ( ULONG i = 0; i < nSize; i++ )
+ {
+ if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
+ break;
+ }
+ if ( i == nSize )
+ return pSource;
+ pSource++;
+ }
+ return NULL;
+}
+
+
+static BOOL ImplGetBoundingBox( double* nNumb, BYTE* pSource, ULONG nSize )
+{
+ BOOL bRetValue = FALSE;
+ ULONG nBytesRead;
+
+ if ( nSize < 256 ) // we assume that the file is greater than 256 bytes
+ return FALSE;
+
+ if ( nSize < POSTSCRIPT_BOUNDINGSEARCH )
+ nBytesRead = nSize;
+ else
+ nBytesRead = POSTSCRIPT_BOUNDINGSEARCH;
+
+ BYTE* pDest = ImplSearchEntry( pSource, (BYTE*)"%%BoundingBox:", nBytesRead, 14 );
+ if ( pDest )
+ {
+ int nSecurityCount = 100; // only 100 bytes following the bounding box will be checked
+ nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
+ pDest += 14;
+ for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ )
+ {
+ int nDivision = 1;
+ BOOL bDivision = FALSE;
+ BOOL bNegative = FALSE;
+ BOOL bValid = TRUE;
+
+ while ( ( --nSecurityCount ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++;
+ BYTE nByte = *pDest;
+ while ( nSecurityCount && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
+ {
+ switch ( nByte )
+ {
+ case '.' :
+ if ( bDivision )
+ bValid = FALSE;
+ else
+ bDivision = TRUE;
+ break;
+ case '-' :
+ bNegative = TRUE;
+ break;
+ default :
+ if ( ( nByte < '0' ) || ( nByte > '9' ) )
+ nSecurityCount = 1; // error parsing the bounding box values
+ else if ( bValid )
+ {
+ if ( bDivision )
+ nDivision*=10;
+ nNumb[i] *= 10;
+ nNumb[i] += nByte - '0';
+ }
+ break;
+ }
+ nSecurityCount--;
+ nByte = *(++pDest);
+ }
+ if ( bNegative )
+ nNumb[i] = -nNumb[i];
+ if ( bDivision && ( nDivision != 1 ) )
+ nNumb[i] /= nDivision;
+ }
+ if ( nSecurityCount)
+ bRetValue = TRUE;
+ }
+ return bRetValue;
+}
+
+static void ImplWriteDouble( BYTE** pBuf, double nNumber )
+{
+// *pBuf += sprintf( (char*)*pBuf, "%f", nNumber );
+
+ if ( nNumber < 0 )
+ {
+ *(*pBuf)++ = (BYTE)'-';
+ nNumber = -nNumber;
+ }
+ ULONG nTemp = (ULONG)nNumber;
+ const String aNumber1( nTemp );
+ ULONG nLen = aNumber1.Len();
+
+ for ( USHORT n = 0; n < nLen; n++ )
+ *(*pBuf)++ = aNumber1[ n ];
+
+ nTemp = (ULONG)( ( nNumber - nTemp ) * 100000 );
+ if ( nTemp )
+ {
+ *(*pBuf)++ = (BYTE)'.';
+ const String aNumber2( nTemp );
+
+ ULONG nLen = aNumber2.Len();
+ if ( nLen < 8 )
+ {
+ for ( n = 0; n < ( 5 - nLen ); n++ )
+ {
+ *(*pBuf)++ = (BYTE)'0';
+ }
+ }
+ for ( USHORT n = 0; n < nLen; n++ )
+ {
+ *(*pBuf)++ = aNumber2[ n ];
+ }
+ }
+ *(*pBuf)++ = ' ';
+}
+
+inline void ImplWriteString( BYTE** pBuf, const char* sString )
+{
+ strcpy( (char*)*pBuf, sString );
+ *pBuf += strlen( sString );
+}
+
+BOOL SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize )
+{
+ if ( !maGraphicsData.mbPrinter )
+ return FALSE;
+
+ BOOL bRet = FALSE;
+ LONG nLong = 0;
+ if ( !(DevQueryCaps( maGraphicsData.mhDC, CAPS_TECHNOLOGY, 1, &nLong ) &&
+ (CAPS_TECH_POSTSCRIPT == nLong)) )
+ return FALSE;
+
+ BYTE* pBuf = new BYTE[ POSTSCRIPT_BUFSIZE ];
+ double nBoundingBox[4];
+
+ if ( pBuf && ImplGetBoundingBox( nBoundingBox, (BYTE*)pPtr, nSize ) )
+ {
+ LONG pOS2DXAry[4]; // hack -> print always 2 white space
+ POINTL aPt;
+ aPt.x = 0;
+ aPt.y = 0;
+ PCH pStr = " ";
+ for( long i = 0; i < 4; i++ )
+ pOS2DXAry[i] = i;
+ GpiCharStringPosAt( maGraphicsData.mhPS, &aPt, NULL, 0, 2, (PCH)pStr,(PLONG)&pOS2DXAry[0] );
+
+ double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] );
+ double dM22 = - ( nHeight / (nBoundingBox[1] - nBoundingBox[3] ) );
+
+ BYTE* pTemp = pBuf;
+ ImplWriteString( &pTemp, "save\n[ " );
+ ImplWriteDouble( &pTemp, dM11 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, dM22 );
+ ImplWriteDouble( &pTemp, nX - ( dM11 * nBoundingBox[0] ) );
+ ImplWriteDouble( &pTemp, maGraphicsData.mnHeight - nY - ( dM22 * nBoundingBox[3] ) );
+ ImplWriteString( &pTemp, "] concat /showpage {} def\n" );
+
+ if ( DevEscape( maGraphicsData.mhDC, DEVESC_RAWDATA, pTemp - pBuf,
+ (PBYTE)pBuf, 0, NULL ) == DEV_OK )
+ {
+ UINT32 nToDo = nSize;
+ UINT32 nDoNow;
+ bRet = TRUE;
+ while( nToDo && bRet )
+ {
+ nDoNow = 0x4000;
+ if ( nToDo < nDoNow )
+ nDoNow = nToDo;
+
+ if ( DevEscape( maGraphicsData.mhDC, DEVESC_RAWDATA, nDoNow, (PBYTE)pPtr + nSize - nToDo,
+ 0, NULL ) == -1 )
+ bRet = FALSE;
+ nToDo -= nDoNow;
+ }
+
+ if ( bRet )
+ {
+ strcpy ( (char*)pBuf, "\nrestore\n" );
+ if ( DevEscape( maGraphicsData.mhDC, DEVESC_RAWDATA, 9, (PBYTE)pBuf,
+ 0, NULL ) == DEV_OK ) bRet = TRUE;
+ }
+ }
+ }
+ delete pBuf;
+ return bRet;
+}
+
diff --git a/vcl/os2/source/gdi/salgdi2.cxx b/vcl/os2/source/gdi/salgdi2.cxx
new file mode 100644
index 000000000000..ccc966d13aa3
--- /dev/null
+++ b/vcl/os2/source/gdi/salgdi2.cxx
@@ -0,0 +1,786 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <tools/svpm.h>
+
+#define _SV_SALGDI2_CXX
+
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+
+BOOL bFastTransparent = FALSE;
+
+// -----------
+// - Defines -
+// -----------
+
+#define RGBCOLOR( r, g, b ) ((ULONG)(((BYTE)(b)|((USHORT)(g)<<8))|(((ULONG)(BYTE)(r))<<16)))
+#define TY( y ) (maGraphicsData.mnHeight-(y)-1)
+
+// ---------------
+// - SalGraphics -
+// ---------------
+
+void SalGraphics::CopyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics )
+{
+ HPS hSrcPS;
+ POINTL thePoints[4];
+ long nSrcHeight;
+
+ if ( pSrcGraphics )
+ {
+ hSrcPS = pSrcGraphics->maGraphicsData.mhPS;
+ nSrcHeight = pSrcGraphics->maGraphicsData.mnHeight;
+ }
+ else
+ {
+ hSrcPS = maGraphicsData.mhPS;
+ nSrcHeight = maGraphicsData.mnHeight;
+ }
+
+ // lower-left corner of target
+ thePoints[0].x = pPosAry->mnDestX;
+ thePoints[0].y = TY( pPosAry->mnDestY + pPosAry->mnDestHeight - 1 );
+
+ // upper-right corner of target
+ thePoints[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth;
+ thePoints[1].y = TY( pPosAry->mnDestY - 1 );
+
+ // lower-left corner of source
+ thePoints[2].x = pPosAry->mnSrcX;
+ thePoints[2].y = nSrcHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight );
+
+ if ( ( pPosAry->mnDestWidth != pPosAry->mnSrcWidth ) || ( pPosAry->mnDestHeight != pPosAry->mnSrcHeight ) )
+ {
+ // upper-right corner of Source
+ thePoints[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth;
+ thePoints[3].y = nSrcHeight - pPosAry->mnSrcY + pPosAry->mnSrcHeight;
+
+ GpiBitBlt( maGraphicsData.mhPS, hSrcPS, 4, thePoints,
+ maGraphicsData.mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE );
+ }
+ else
+ {
+ GpiBitBlt( maGraphicsData.mhPS, hSrcPS, 3, thePoints,
+ maGraphicsData.mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::CopyArea( long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ USHORT nFlags )
+{
+ POINTL thePoints[3];
+
+ // lower-left corner of target
+ thePoints[0].x = nDestX;
+ thePoints[0].y = TY( nDestY + nSrcHeight - 1 );
+
+ // upper-right corner of target
+ thePoints[1].x = nDestX + nSrcWidth;
+ thePoints[1].y = TY( nDestY - 1 );
+
+ // lower-left corner of source
+ thePoints[2].x = nSrcX;
+ thePoints[2].y = TY( nSrcY + nSrcHeight - 1);
+
+ GpiBitBlt( maGraphicsData.mhPS, maGraphicsData.mhPS, 3, thePoints,
+ ROP_SRCCOPY, BBO_IGNORE );
+
+ if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && maGraphicsData.mbWindow )
+ {
+ // Overlap-Bereich berechnen und invalidieren
+ Point aVCLSrcPos( nSrcX, nSrcY );
+ Size aVCLSrcSize( nSrcWidth, nSrcHeight );
+ Rectangle aVCLSrcRect( aVCLSrcPos, aVCLSrcSize );
+ Rectangle aVCLClipRect;
+ SWP aSWP;
+
+ WinQueryWindowPos( maGraphicsData.mhWnd, &aSWP );
+ aVCLClipRect.Right() = aSWP.cx-1;
+ aVCLClipRect.Bottom() = aSWP.cy-1;
+ if ( !aVCLSrcRect.Intersection( aVCLClipRect ).IsEmpty() )
+ {
+ RECTL aSrcRect;
+ RECTL aTempRect;
+ HRGN hInvalidateRgn;
+ HRGN hTempRgn;
+ HWND hWnd;
+ long nRgnType;
+
+ long nVCLScrHeight = aVCLSrcRect.GetHeight();
+ aSrcRect.xLeft = aVCLSrcRect.Left();
+ aSrcRect.yBottom = TY( aVCLSrcRect.Top()+nVCLScrHeight-1 );
+ aSrcRect.xRight = aSrcRect.xLeft+aVCLSrcRect.GetWidth();
+ aSrcRect.yTop = aSrcRect.yBottom+nVCLScrHeight;
+
+ // Rechteck in Screen-Koordinaaten umrechnen
+ POINTL aPt;
+ long nScreenDX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
+ long nScreenDY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
+ aPt.x = 0;
+ aPt.y = 0;
+ WinMapWindowPoints( maGraphicsData.mhWnd, HWND_DESKTOP, &aPt, 1 );
+ aSrcRect.xLeft += aPt.x;
+ aSrcRect.yTop += aPt.y;
+ aSrcRect.xRight += aPt.x;
+ aSrcRect.yBottom += aPt.y;
+ hInvalidateRgn = 0;
+ // Bereiche ausserhalb des sichtbaren Bereiches berechnen
+ if ( aSrcRect.xLeft < 0 )
+ {
+ if ( !hInvalidateRgn )
+ hInvalidateRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aSrcRect );
+ aTempRect.xLeft = -31999;
+ aTempRect.yBottom = 0;
+ aTempRect.xRight = 0;
+ aTempRect.yTop = 31999;
+ hTempRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aTempRect );
+ GpiCombineRegion( maGraphicsData.mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
+ GpiDestroyRegion( maGraphicsData.mhPS, hTempRgn );
+ }
+ if ( aSrcRect.yBottom < 0 )
+ {
+ if ( !hInvalidateRgn )
+ hInvalidateRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aSrcRect );
+ aTempRect.xLeft = 0;
+ aTempRect.yBottom = -31999;
+ aTempRect.xRight = 31999;
+ aTempRect.yTop = 0;
+ hTempRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aTempRect );
+ GpiCombineRegion( maGraphicsData.mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
+ GpiDestroyRegion( maGraphicsData.mhPS, hTempRgn );
+ }
+ if ( aSrcRect.xRight > nScreenDX )
+ {
+ if ( !hInvalidateRgn )
+ hInvalidateRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aSrcRect );
+ aTempRect.xLeft = nScreenDX;
+ aTempRect.yBottom = 0;
+ aTempRect.xRight = 31999;
+ aTempRect.yTop = 31999;
+ hTempRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aTempRect );
+ GpiCombineRegion( maGraphicsData.mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
+ GpiDestroyRegion( maGraphicsData.mhPS, hTempRgn );
+ }
+ if ( aSrcRect.yTop > nScreenDY )
+ {
+ if ( !hInvalidateRgn )
+ hInvalidateRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aSrcRect );
+ aTempRect.xLeft = 0;
+ aTempRect.yBottom = nScreenDY;
+ aTempRect.xRight = 31999;
+ aTempRect.yTop = 31999;
+ hTempRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aTempRect );
+ GpiCombineRegion( maGraphicsData.mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
+ GpiDestroyRegion( maGraphicsData.mhPS, hTempRgn );
+ }
+
+ // Bereiche die von anderen Fenstern ueberlagert werden berechnen
+ HWND hWndParent = WinQueryWindow( maGraphicsData.mhWnd, QW_PARENT );
+ hWnd = WinQueryWindow( HWND_DESKTOP, QW_TOP );
+ aVCLSrcRect = Rectangle( aSrcRect.xLeft, aSrcRect.yBottom, aSrcRect.xRight, aSrcRect.yTop );
+ while ( hWnd )
+ {
+ if ( hWnd == hWndParent )
+ break;
+ if ( WinIsWindowVisible( hWnd ) )
+ {
+ WinQueryWindowPos( hWnd, &aSWP );
+ if ( !(aSWP.fl & SWP_MINIMIZE) )
+ {
+ aVCLClipRect = Rectangle( Point( aSWP.x, aSWP.y ), Size( aSWP.cx, aSWP.cy ) );
+ if ( aVCLSrcRect.IsOver( aVCLClipRect ) )
+ {
+ if ( !hInvalidateRgn )
+ hInvalidateRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aSrcRect );
+ aTempRect.xLeft = aSWP.x;
+ aTempRect.yBottom = aSWP.y;
+ aTempRect.xRight = aTempRect.xLeft+aSWP.cx;
+ aTempRect.yTop = aTempRect.yBottom+aSWP.cy;
+ hTempRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aTempRect );
+ GpiCombineRegion( maGraphicsData.mhPS, hInvalidateRgn, hInvalidateRgn, hTempRgn, CRGN_DIFF );
+ GpiDestroyRegion( maGraphicsData.mhPS, hTempRgn );
+ }
+ }
+ }
+ hWnd = WinQueryWindow( hWnd, QW_NEXT );
+ }
+
+ if ( hInvalidateRgn )
+ {
+ hTempRgn = GpiCreateRegion( maGraphicsData.mhPS, 1, &aSrcRect );
+ nRgnType = GpiCombineRegion( maGraphicsData.mhPS, hInvalidateRgn, hTempRgn, hInvalidateRgn, CRGN_DIFF );
+ GpiDestroyRegion( maGraphicsData.mhPS, hTempRgn );
+ if ( (nRgnType != RGN_ERROR) && (nRgnType != RGN_NULL) )
+ {
+ long nOffX = (nDestX-nSrcX);
+ long nOffY = (nSrcY-nDestY);
+ aPt.x = nOffX-aPt.x;
+ aPt.y = nOffY-aPt.y;
+ GpiOffsetRegion( maGraphicsData.mhPS, hInvalidateRgn, &aPt );
+ WinInvalidateRegion( maGraphicsData.mhWnd, hInvalidateRgn, TRUE );
+ // Hier loesen wir nur ein Update aus, wenn es der
+ // MainThread ist, damit es beim Bearbeiten der
+ // Paint-Message keinen Deadlock gibt, da der
+ // SolarMutex durch diesen Thread schon gelockt ist
+ SalData* pSalData = GetSalData();
+ ULONG nCurThreadId = ImplSalGetCurrentThreadId();
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ WinUpdateWindow( maGraphicsData.mhWnd );
+ }
+ GpiDestroyRegion( maGraphicsData.mhPS, hInvalidateRgn );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDrawBitmap( HPS hPS, long nScreenHeight,
+ const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap,
+ BOOL bPrinter, int nDrawMode )
+{
+ if( hPS )
+ {
+ HANDLE hDrawDIB;
+ HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB();
+ SalBitmap* pTmpSalBmp = NULL;
+ BOOL bPrintDDB = ( bPrinter && hDrawDDB );
+ BOOL bDrawDDB1 = ( ( rSalBitmap.GetBitCount() == 1 ) && hDrawDDB );
+
+ if( bPrintDDB || bDrawDDB1 )
+ {
+ pTmpSalBmp = new SalBitmap;
+ pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() );
+ hDrawDIB = pTmpSalBmp->ImplGethDIB();
+ }
+ else
+ hDrawDIB = rSalBitmap.ImplGethDIB();
+
+ if( hDrawDIB )
+ {
+ HANDLE hSubst = rSalBitmap.ImplGethDIB1Subst();
+ POINTL pts[ 4 ];
+ BITMAPINFO2* pBI = (BITMAPINFO2*) hDrawDIB;
+ BITMAPINFOHEADER2* pBIH = (BITMAPINFOHEADER2*) pBI;
+ const long nHeight = pBIH->cy;
+ long nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGB2 );
+ BYTE* pBits = (BYTE*) pBI + nInfoSize;
+
+ pts[0].x = pPosAry->mnDestX;
+ pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight;
+ pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1;
+ pts[1].y = nScreenHeight - pPosAry->mnDestY - 1;
+
+ pts[2].x = pPosAry->mnSrcX;
+ pts[2].y = nHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight );
+ pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth;
+ pts[3].y = nHeight - pPosAry->mnSrcY;
+
+ // if we've got a 1Bit DIB, we create a 4Bit substitute
+ if( ( pBIH->cBitCount == 1 ) && !hSubst )
+ {
+ // create 4Bit substitute
+ hSubst = SalBitmap::ImplCreateDIB4FromDIB1( hDrawDIB );
+
+ // replace substitute only, if it is no temporary SalBitmap
+ if( !( bPrintDDB || bDrawDDB1 ) )
+ ( (SalBitmap&) rSalBitmap ).ImplReplacehDIB1Subst( hSubst );
+ }
+
+ if( hSubst )
+ {
+ pBI = (BITMAPINFO2*) hSubst;
+ pBIH = (BITMAPINFOHEADER2*) pBI;
+ nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hSubst ) * sizeof( RGB2 );
+ pBits = (BYTE*) pBI + nInfoSize;
+ }
+
+ if( bPrinter )
+ {
+ BYTE* pDummy;
+
+ // expand 8Bit-DIB's to 24Bit-DIB's, because some printer drivers
+ // have problems to print these DIB's (strange)
+ if( pBIH->cBitCount == 8 && pBIH->ulCompression == BCA_UNCOMP )
+ {
+ const long nWidth = pBIH->cx;
+ const long nHeight = pBIH->cy;
+ const long nWidthAl8 = AlignedWidth4Bytes( nWidth * 8 );
+ const long nWidthAl24 = AlignedWidth4Bytes( nWidth * 24 );
+ const long nNewImageSize = nHeight * nWidthAl24;
+ BITMAPINFOHEADER2* pNewInfo;
+
+ pDummy = new BYTE[ sizeof( BITMAPINFO2 ) + nNewImageSize ];
+ memset( pDummy, 0, sizeof( BITMAPINFO2 ) );
+
+ pNewInfo = (BITMAPINFOHEADER2*) pDummy;
+ pNewInfo->cbFix = sizeof( BITMAPINFOHEADER2 );
+ pNewInfo->cx = nWidth;
+ pNewInfo->cy = nHeight;
+ pNewInfo->cPlanes = 1;
+ pNewInfo->cBitCount = 24;
+ pNewInfo->ulCompression = BCA_UNCOMP;
+ pNewInfo->cbImage = nNewImageSize;
+
+ BYTE* pBitsSrc = (BYTE*) pBIH + nInfoSize;
+ BYTE* pBitsDst = pDummy + sizeof( BITMAPINFO2 );
+
+ for( long nY = 0UL; nY < nHeight; nY++ )
+ {
+ BYTE* pSrcLine = pBitsSrc + nY * nWidthAl8;
+ BYTE* pDstLine = pBitsDst + nY * nWidthAl24;
+
+ for( long nX = 0UL; nX < nWidth; nX++ )
+ {
+ const RGB2& rQuad = pBI->argbColor[ *pSrcLine++ ];
+
+ *pDstLine++ = rQuad.bBlue;
+ *pDstLine++ = rQuad.bGreen;
+ *pDstLine++ = rQuad.bRed;
+ }
+ }
+
+ nInfoSize = sizeof( BITMAPINFO2 );
+ }
+ else
+ {
+ const long nImageSize = ( pBIH->cbImage ? pBIH->cbImage : ( pBIH->cy * AlignedWidth4Bytes( pBIH->cx * pBIH->cBitCount ) ) );
+ const long nTotalSize = nInfoSize + nImageSize;
+
+ pDummy = new BYTE[ nTotalSize ];
+ memcpy( pDummy, pBI, nTotalSize );
+ }
+
+ GpiDrawBits( hPS, pDummy + nInfoSize, (BITMAPINFO2*) pDummy, 4L, pts, nDrawMode, BBO_IGNORE );
+ delete[] pDummy;
+ }
+ else
+ GpiDrawBits( hPS, pBits, pBI, 4L, pts, nDrawMode, BBO_IGNORE );
+ }
+ else if( hDrawDDB && !bPrintDDB )
+ {
+ POINTL pts[ 4 ];
+
+ pts[0].x = pPosAry->mnDestX;
+ pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight;
+ pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1;
+ pts[1].y = nScreenHeight - pPosAry->mnDestY - 1;
+
+ pts[2].x = pPosAry->mnSrcX;
+ pts[2].y = rSalBitmap.GetSize().Height() - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight );
+ pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth;
+ pts[3].y = rSalBitmap.GetSize().Height() - pPosAry->mnSrcY;
+
+ GpiWCBitBlt( hPS, hDrawDDB, 4L, pts, nDrawMode, BBO_IGNORE );
+/*
+ HPS hDrawPS = ImplGetCachedPS( CACHED_HPS_DRAW, hDrawDDB );
+ GpiBitBlt( hPS, hDrawPS, 4, pts, nDrawMode, BBO_IGNORE );
+ ImplReleaseCachedPS( CACHED_HPS_DRAW );
+*/
+ }
+
+ if( bPrintDDB || bDrawDDB1 )
+ delete pTmpSalBmp;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap )
+{
+ ImplDrawBitmap( maGraphicsData.mhPS, maGraphicsData.mnHeight,
+ pPosAry, rSalBitmap,
+ maGraphicsData.mbPrinter,
+ maGraphicsData.mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nTransparentColor )
+{
+ // an FM: kann erst einmal unberuecksichtigt bleiben
+ DrawBitmap( pPosAry, rSalBitmap );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rTransparentBitmap )
+{
+ if( bFastTransparent )
+ {
+ ImplDrawBitmap( maGraphicsData.mhPS, maGraphicsData.mnHeight, pPosAry, rTransparentBitmap, FALSE, ROP_SRCAND );
+ ImplDrawBitmap( maGraphicsData.mhPS, maGraphicsData.mnHeight, pPosAry, rSalBitmap, FALSE, ROP_SRCPAINT );
+ }
+ else
+ {
+ SalTwoRect aPosAry = *pPosAry;
+ int nDstX = (int) aPosAry.mnDestX;
+ int nDstY = (int) aPosAry.mnDestY;
+ int nDstWidth = (int) aPosAry.mnDestWidth;
+ int nDstHeight = (int) aPosAry.mnDestHeight;
+ HAB hAB = GetSalData()->mhAB;
+ HPS hPS = maGraphicsData.mhPS;
+ DEVOPENSTRUC aDevOpenStruc = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+ SIZEL aSizeL = { nDstWidth, nDstHeight };
+ POINTL aPtL[ 3 ];
+
+ HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
+ HPS hMemPS = GpiCreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
+ HBITMAP hMemBitmap = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDstWidth, nDstHeight, 0 );
+ HBITMAP hMemOld = (HBITMAP) GpiSetBitmap( hMemPS, hMemBitmap );
+ HDC hMaskDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
+ HPS hMaskPS = GpiCreatePS( hAB, hMaskDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
+ HBITMAP hMaskBitmap = ImplCreateVirDevBitmap( hMaskDC, hMaskPS, nDstWidth, nDstHeight, 0 );
+ HBITMAP hMaskOld = (HBITMAP) GpiSetBitmap( hMaskPS, hMaskBitmap );
+/*
+ HPS hMemPS = ImplGetCachedPS( CACHED_HPS_1, 0 );
+ HPS hMaskPS = ImplGetCachedPS( CACHED_HPS_2, 0 );
+*/
+ aPosAry.mnDestX = aPosAry.mnDestY = 0L;
+
+ aPtL[ 0 ].x = 0;
+ aPtL[ 0 ].y = 0;
+ aPtL[ 1 ].x = nDstWidth;
+ aPtL[ 1 ].y = nDstHeight;
+ aPtL[ 2 ].x = nDstX;
+ aPtL[ 2 ].y = TY( nDstY + nDstHeight - 1 );
+
+ GpiBitBlt( hMemPS, hPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE );
+ ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rTransparentBitmap, FALSE, ROP_SRCCOPY );
+
+ aPtL[ 2 ].x = 0;
+ aPtL[ 2 ].y = 0;
+
+ GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCAND, BBO_IGNORE );
+ ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rSalBitmap, FALSE, ROP_SRCERASE );
+ GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCPAINT, BBO_IGNORE );
+
+ aPtL[ 0 ].x = nDstX;
+ aPtL[ 0 ].y = TY( nDstY + nDstHeight - 1 );
+ aPtL[ 1 ].x = nDstX + nDstWidth;
+ aPtL[ 1 ].y = TY( nDstY - 1 );
+
+ GpiBitBlt( hPS, hMemPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE );
+
+ GpiSetBitmap( hMaskPS, hMaskOld );
+ GpiDestroyPS( hMaskPS );
+ DevCloseDC( hMaskDC );
+ GpiDeleteBitmap( hMaskBitmap );
+
+ GpiSetBitmap( hMemPS, hMemOld );
+ GpiDestroyPS( hMemPS );
+ DevCloseDC( hMemDC );
+ GpiDeleteBitmap( hMemBitmap );
+
+/*
+ ImplReleaseCachedPS( CACHED_HPS_1 );
+ ImplReleaseCachedPS( CACHED_HPS_2 );
+*/
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawMask( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor )
+{
+ SalTwoRect aPosAry = *pPosAry;
+ HPS hPS = maGraphicsData.mhPS;
+ IMAGEBUNDLE aBundle, aOldBundle;
+ AREABUNDLE aAreaBundle, aOldAreaBundle;
+ const ULONG nColor = RGBCOLOR( SALCOLOR_RED( nMaskColor ),
+ SALCOLOR_GREEN( nMaskColor ),
+ SALCOLOR_BLUE( nMaskColor ) );
+
+ GpiQueryAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, &aOldBundle );
+ aBundle.lColor = RGBCOLOR( 0, 0, 0 );
+ aBundle.lBackColor = RGBCOLOR( 0xFF, 0xFF, 0xFF );
+ GpiSetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aBundle );
+
+ GpiQueryAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL |
+ ABB_MIX_MODE | ABB_BACK_MIX_MODE, &aOldAreaBundle );
+ aAreaBundle.lColor = nColor;
+ aAreaBundle.lBackColor = nColor;
+ aAreaBundle.usSymbol = PATSYM_SOLID;
+ aAreaBundle.usMixMode = FM_OVERPAINT;
+ aAreaBundle.usBackMixMode = BM_OVERPAINT;
+ GpiSetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL |
+ ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aAreaBundle );
+
+ ImplDrawBitmap( hPS, maGraphicsData.mnHeight, &aPosAry, rSalBitmap, FALSE, 0x00B8L );
+
+ GpiSetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aOldBundle );
+ GpiSetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL |
+ ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aOldAreaBundle );
+}
+
+// -----------------------------------------------------------------------
+
+SalBitmap* SalGraphics::GetBitmap( long nX, long nY, long nDX, long nDY )
+{
+ HAB hAB = GetSalData()->mhAB;
+ SIZEL size = { nDX, nDY };
+ SalBitmap* pSalBitmap = NULL;
+
+ // create device context (at this time allways display compatible)
+ DEVOPENSTRUC aDevOpenStruc = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+ HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
+ HPS hMemPS = GpiCreatePS( hAB, hMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
+ HBITMAP hMemBmp = ImplCreateVirDevBitmap( hMemDC, hMemPS, nDX, nDY, 0 );
+ HBITMAP hMemOld = GpiSetBitmap( hMemPS, hMemBmp );
+
+ // creation successfull?
+ if( hMemDC && hMemPS && hMemBmp )
+ {
+ POINTL thePoints[ 3 ];
+
+ // lower-left corner of target
+ thePoints[ 0 ].x = 0;
+ thePoints[ 0 ].y = 0;
+
+ // upper-right corner of target
+ thePoints[ 1 ].x = nDX;
+ thePoints[ 1 ].y = nDY;
+
+ // lower-left corner of source
+ thePoints[ 2 ].x = nX;
+ thePoints[ 2 ].y = TY( nY + nDY - 1 );
+
+ long lHits = GpiBitBlt( hMemPS, maGraphicsData.mhPS, 3, thePoints,
+ maGraphicsData.mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE );
+
+ if( hMemPS )
+ {
+ GpiSetBitmap( hMemPS, hMemOld );
+ GpiDestroyPS( hMemPS );
+ }
+
+ if( hMemDC )
+ DevCloseDC( hMemDC );
+
+ if( lHits == GPI_OK )
+ {
+ pSalBitmap = new SalBitmap;
+
+ if( !pSalBitmap->Create( hMemBmp, FALSE, FALSE ) )
+ {
+ delete pSalBitmap;
+ pSalBitmap = NULL;
+ }
+ }
+ }
+
+ if( !pSalBitmap )
+ GpiDeleteBitmap( hMemBmp );
+
+ // return pointer to SAL-Bitmap
+ return pSalBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+SalColor SalGraphics::GetPixel( long nX, long nY )
+{
+ POINTL aPt = { nX, TY( nY ) };
+ LONG nColor = GpiQueryPel( maGraphicsData.mhPS, &aPt );
+
+ return MAKE_SALCOLOR( (BYTE) ( nColor >> 16 ), (BYTE) ( nColor >> 8 ), (BYTE) nColor );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::Invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
+{
+ if( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+ // save old vylues
+ LINEBUNDLE oldLb;
+ LINEBUNDLE lb;
+ GpiQueryAttrs( maGraphicsData.mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb );
+
+ // set linetype to short dash
+ lb.lColor = RGBCOLOR( 255, 255, 255 );
+ lb.usMixMode = FM_XOR;
+ lb.usType = LINETYPE_ALTERNATE;
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb );
+
+ // draw inverted box
+ POINTL aPt;
+
+ aPt.x = nX;
+ aPt.y = TY( nY );
+
+ GpiMove( maGraphicsData.mhPS, &aPt );
+
+ aPt.x = nX + nWidth - 1;
+ aPt.y = TY( nY + nHeight - 1 );
+
+ GpiBox( maGraphicsData.mhPS, DRO_OUTLINE, &aPt, 0, 0 );
+
+ // restore old values
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb );
+
+ }
+ else
+ {
+ // save old values
+ AREABUNDLE oldAb;
+ AREABUNDLE ab;
+
+ GpiQueryAttrs( maGraphicsData.mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb );
+
+ // set fill color to black
+ ab.lColor = RGBCOLOR( 255, 255, 255 );
+ ab.usMixMode = FM_XOR;
+ ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID;
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab );
+
+ // draw inverted box
+ POINTL aPt;
+
+ aPt.x = nX;
+ aPt.y = TY( nY );
+
+ GpiMove( maGraphicsData.mhPS, &aPt );
+
+ aPt.x = nX + nWidth - 1;
+ aPt.y = TY( nY + nHeight - 1 );
+
+ GpiBox( maGraphicsData.mhPS, DRO_FILL, &aPt, 0, 0 );
+
+ // restore old values
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::Invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert nFlags )
+{
+ if( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+ // save old vylues
+ LINEBUNDLE oldLb;
+ LINEBUNDLE lb;
+ GpiQueryAttrs( maGraphicsData.mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, &oldLb );
+
+ // set linetype to short dash
+ lb.lColor = RGBCOLOR( 255, 255, 255 );
+ lb.usMixMode = FM_XOR;
+ lb.usType = LINETYPE_ALTERNATE;
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &lb );
+
+ // Draw Polyline
+ DrawPolyLine( nPoints, pPtAry );
+
+ // restore old values
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_LINE, LBB_MIX_MODE | LBB_TYPE | LBB_COLOR, 0, &oldLb );
+ }
+ else
+ {
+ // save old values
+ AREABUNDLE oldAb;
+ AREABUNDLE ab;
+
+ GpiQueryAttrs( maGraphicsData.mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, &oldAb );
+
+ // set fill color to black
+ ab.lColor = RGBCOLOR( 255, 255, 255 );
+ ab.usMixMode = FM_XOR;
+ ab.usSymbol = (nFlags & SAL_INVERT_50) ? PATSYM_DENSE5 : PATSYM_SOLID;
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &ab );
+
+ // Draw Polyline
+ DrawPolygon( nPoints, pPtAry );
+
+ // restore old values
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_AREA, ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL, 0, &oldAb );
+ }
+}
+
diff --git a/vcl/os2/source/gdi/salgdi3.cxx b/vcl/os2/source/gdi/salgdi3.cxx
new file mode 100644
index 000000000000..0876f5c4f606
--- /dev/null
+++ b/vcl/os2/source/gdi/salgdi3.cxx
@@ -0,0 +1,780 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi3.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define INCL_GRE_STRINGS
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <tools/svpm.h>
+
+#define _SV_SALGDI3_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define SAL_DRAWTEXT_STACKBUF 128
+
+#define FONTTAB_FACTOR_PRINTER 18
+#define FONTTAB_FACTOR_DISPLAY 9
+static unsigned char aFontCharTab32[32] =
+{
+ 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
+};
+
+// =======================================================================
+
+static PM_USHORT ImplSalToCharSet( CharSet eCharSet )
+{
+ // !!! Fuer DBCS-Systeme muss dieser Code auskommentiert werden und 0
+ // !!! zurueckgegeben werden, solange die DBCS-Charsets nicht
+ // !!! durchgereicht werden
+
+ switch ( eCharSet )
+ {
+ case CHARSET_IBMPC_437:
+ return 437;
+
+ case CHARSET_IBMPC_850:
+ return 850;
+
+ case CHARSET_IBMPC_860:
+ return 860;
+
+ case CHARSET_IBMPC_861:
+ return 861;
+
+ case CHARSET_IBMPC_863:
+ return 863;
+
+ case CHARSET_IBMPC_865:
+ return 865;
+
+ case CHARSET_ANSI:
+ return 1004;
+
+ case CHARSET_SYMBOL:
+ return 65400;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static CharSet ImplCharSetToSal( PM_USHORT usCodePage )
+{
+ switch ( usCodePage )
+ {
+ case 437:
+ return CHARSET_IBMPC_437;
+
+ case 850:
+ return CHARSET_IBMPC_850;
+
+ case 860:
+ return CHARSET_IBMPC_860;
+
+ case 861:
+ return CHARSET_IBMPC_861;
+
+ case 863:
+ return CHARSET_IBMPC_863;
+
+ case 865:
+ return CHARSET_IBMPC_865;
+
+ case 1004:
+ return CHARSET_ANSI;
+
+ case 65400:
+ return CHARSET_SYMBOL;
+
+ }
+
+ return CHARSET_DONTKNOW;
+}
+
+// -----------------------------------------------------------------------
+
+static FontWeight ImplWeightToSal( PM_USHORT nWeight )
+{
+ // Falls sich jemand an die alte Doku gehalten hat
+ if ( nWeight > 999 )
+ nWeight /= 1000;
+
+ switch ( nWeight )
+ {
+ case 1:
+ return WEIGHT_THIN;
+
+ case 2:
+ return WEIGHT_ULTRALIGHT;
+
+ case 3:
+ return WEIGHT_LIGHT;
+
+ case 4:
+ return WEIGHT_SEMILIGHT;
+
+ case 5:
+ return WEIGHT_NORMAL;
+
+ case 6:
+ return WEIGHT_SEMIBOLD;
+
+ case 7:
+ return WEIGHT_BOLD;
+
+ case 8:
+ return WEIGHT_ULTRABOLD;
+
+ case 9:
+ return WEIGHT_BLACK;
+ }
+
+ return WEIGHT_DONTKNOW;
+}
+
+// -----------------------------------------------------------------------
+
+static XubString ImpStyleNameToSal( const xub_Unicode* pFamilyName,
+ const xub_Unicode* pFaceName,
+ USHORT nLen )
+{
+ if ( !nLen )
+ nLen = WSstrlen( pFamilyName );
+
+ // FamilyName gegebenenfalls abschneiden
+ if ( WSstrncmp( pFamilyName, pFaceName, nLen ) == 0 )
+ {
+ USHORT nFaceLen = (USHORT)WSstrlen( pFaceName+nLen );
+ // Ist Facename laenger, schneiden wir den FamilyName ab
+ if ( nFaceLen > 1 )
+ return XubString( pFaceName+(nLen+1), nFaceLen-1 );
+ else
+ return XubString();
+ }
+ else
+ return XubString( pFaceName );
+}
+
+// =======================================================================
+
+void SalGraphics::SetTextColor( SalColor nSalColor )
+{
+ CHARBUNDLE cb;
+
+ cb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ // set default color attributes
+ GpiSetAttrs( maGraphicsData.mhPS,
+ PRIM_CHAR,
+ CBB_COLOR,
+ 0,
+ &cb );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalGraphics::SetFont( ImplFontSelectData* pFont )
+{
+ ImplFontData* pFontData = pFont->mpFontData;
+ FATTRS aFAttrs;
+ BOOL bOutline;
+
+ memset( &aFAttrs, 0, sizeof( FATTRS ) );
+ aFAttrs.usRecordLength = sizeof( FATTRS );
+
+ aFAttrs.usCodePage = ImplSalToCharSet( pFont->meCharSet );
+ aFAttrs.lMaxBaselineExt = pFont->mnHeight;
+ aFAttrs.lAveCharWidth = pFont->mnWidth;
+
+ // do we have a pointer to the FONTMETRICS of the selected font? -> use it!
+ if ( pFontData )
+ {
+ PFONTMETRICS pFontMetric = (PFONTMETRICS)pFontData->mpSysData;
+ strcpy( (char*)(aFAttrs.szFacename), pFontMetric->szFacename );
+ aFAttrs.lMatch = pFontMetric->lMatch;
+ aFAttrs.idRegistry = pFontMetric->idRegistry;
+
+ bOutline = (pFontMetric->fsDefn & FM_DEFN_OUTLINE) != 0;
+ maGraphicsData.mbFontIsFixed = (pFontMetric->fsType & FM_TYPE_FIXED) != 0;
+
+ if ( bOutline )
+ {
+ aFAttrs.fsFontUse |= FATTR_FONTUSE_OUTLINE;
+ if ( pFont->mnOrientation )
+ aFAttrs.fsFontUse |= FATTR_FONTUSE_TRANSFORMABLE;
+ }
+ else
+ {
+ aFAttrs.lMaxBaselineExt = pFontData->mnHeight;
+ aFAttrs.lAveCharWidth = pFontData->mnWidth;
+ }
+
+ if ( (pFont->mpFontData->meItalic == ITALIC_NONE) && (pFont->meItalic != ITALIC_NONE) )
+ aFAttrs.fsSelection |= FATTR_SEL_ITALIC;
+ if ( ((short)pFont->meWeight - (short)pFont->mpFontData->meWeight >= 2) )
+ aFAttrs.fsSelection |= FATTR_SEL_BOLD;
+ }
+ else
+ {
+ String aName = pFont->maName.GetToken( 0 );
+ strncpy( (char*)(aFAttrs.szFacename), aName, sizeof( aFAttrs.szFacename ) );
+
+ bOutline = FALSE;
+ maGraphicsData.mbFontIsFixed = FALSE;
+
+ if ( pFont->meItalic != ITALIC_NONE )
+ aFAttrs.fsSelection |= FATTR_SEL_ITALIC;
+ if ( pFont->meWeight > WEIGHT_MEDIUM )
+ aFAttrs.fsSelection |= FATTR_SEL_BOLD;
+ }
+
+ if ( GpiCreateLogFont( maGraphicsData.mhPS, NULL, 10, &aFAttrs ) == GPI_ERROR )
+ return SAL_SETFONT_REMOVEANDMATCHNEW;
+
+ CHARBUNDLE aBundle;
+
+ PM_ULONG nAttrsDefault = 0;
+ PM_ULONG nAttrs = CBB_SET;
+ aBundle.usSet = 10;
+
+ nAttrs |= CBB_BOX;
+ if ( bOutline )
+ {
+ aBundle.sizfxCell.cy = MAKEFIXED( pFont->mnHeight, 0 );
+
+ if ( !pFont->mnWidth )
+ {
+ LONG nXFontRes;
+ LONG nYFontRes;
+ LONG nHeight;
+
+ // Auf die Aufloesung achten, damit das Ergebnis auch auf
+ // Drucken mit 180*360 DPI stimmt. Ausserdem muss gerundet
+ // werden, da auf meinem OS2 beispielsweise als
+ // Bildschirmaufloesung 3618*3622 PixelPerMeter zurueck-
+ // gegeben wird
+ DevQueryCaps( maGraphicsData.mhDC, CAPS_HORIZONTAL_RESOLUTION, 1, &nXFontRes );
+ DevQueryCaps( maGraphicsData.mhDC, CAPS_VERTICAL_RESOLUTION, 1, &nYFontRes );
+ nHeight = pFont->mnHeight;
+ nHeight *= nXFontRes;
+ nHeight += nYFontRes/2;
+ nHeight /= nYFontRes;
+ aBundle.sizfxCell.cx = MAKEFIXED( nHeight, 0 );
+ }
+ else
+ aBundle.sizfxCell.cx = MAKEFIXED( pFont->mnWidth, 0 );
+ }
+ else
+ nAttrsDefault |= CBB_BOX;
+
+ // set orientation for outlinefonts
+ nAttrs |= CBB_ANGLE;
+ if ( pFont->mnOrientation )
+ {
+ if ( bOutline )
+ {
+ double alpha = (double)(pFont->mnOrientation);
+ alpha *= 0.0017453292; // *PI / 1800
+ maGraphicsData.mnOrientationY = (long) (1000.0 * sin( alpha ));
+ maGraphicsData.mnOrientationX = (long) (1000.0 * cos( alpha ));
+ aBundle.ptlAngle.x = maGraphicsData.mnOrientationX;
+ aBundle.ptlAngle.y = maGraphicsData.mnOrientationY;
+ }
+ else
+ {
+ nAttrsDefault |= CBB_ANGLE;
+ maGraphicsData.mnOrientationX = 1;
+ maGraphicsData.mnOrientationY = 0;
+ }
+ }
+ else
+ {
+ nAttrsDefault |= CBB_ANGLE;
+ maGraphicsData.mnOrientationX = 1;
+ maGraphicsData.mnOrientationY = 0;
+ }
+
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_CHAR,
+ nAttrs,
+ nAttrsDefault,
+ &aBundle );
+
+ // save info about font
+ maGraphicsData.mbFontIsOutline = bOutline;
+
+ return SAL_SETFONT_USEDRAWTEXTARRAY;
+}
+
+// -----------------------------------------------------------------------
+
+long SalGraphics::GetCharWidth( USHORT nChar1, USHORT nChar2, long* pWidthAry )
+{
+ POINTL aNullPt = { 0, 0 };
+ POINTL aFontCharPtBuf[33];
+ unsigned char aFontCharTabBuf[FONTTAB_FACTOR_PRINTER];
+ long nFontTabFactor = maGraphicsData.mbPrinter
+ ? FONTTAB_FACTOR_PRINTER
+ : FONTTAB_FACTOR_DISPLAY;
+
+ // Orientation? -> rotate to 0 degree!
+ if ( (maGraphicsData.mnOrientationY != 0) && (maGraphicsData.mnOrientationX != 1) )
+ {
+ CHARBUNDLE aBundle;
+ aBundle.ptlAngle.x = 1;
+ aBundle.ptlAngle.y = 0;
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_CHAR, CBB_ANGLE, 0, &aBundle );
+ }
+
+ // Fixed-Font und Fontbreitentabelle bestimmen
+ // Wir benutzen GpiQueryCharStringPos() (und nicht GpiQueryWidthTable())
+ // um die Genauigkeit zu erhoehen. In dem String stehen bis auf die
+ // ersten 32-Zeichen FONTATB_FACTOR* in der Tabelle um die Genauigkeit
+ // um den Faktor FONTTAB_FACTOR (9 bzw. 18) zu steigern. Dies muessen wir tun,
+ // da auf einen ganzen String die Genauigkeit der Zeichenbreiten
+ // groesser als Pixel ist. Somit muessen die Werte, die in der Tabelle
+ // abgefragt werden durch FONTTAB_FACTOR dividiert werden.
+ USHORT i = 0;
+ if ( maGraphicsData.mbFontIsFixed )
+ {
+ // Bei FixedFonts brauchen wir nicht soviele Zeichen
+ // uebergeben, da alle gleich breit sind
+ memset( aFontCharTabBuf, 'x', nFontTabFactor );
+ GpiQueryCharStringPosAt( maGraphicsData.mhPS, &aNullPt, 0, nFontTabFactor,
+ (PCH)aFontCharTabBuf, NULL, aFontCharPtBuf );
+
+ long nWidth = aFontCharPtBuf[nFontTabFactor].x - aFontCharPtBuf[0].x;
+ long nFontTabFactor2 = nFontTabFactor/2;
+ // Breite auf ganze Pixel alignen, damit Schriftbild besser aussieht
+ nWidth = (nWidth+nFontTabFactor2)/nFontTabFactor;
+ for ( ; i < 256; i++ )
+ pWidthAry[i] = nWidth;
+ nFontTabFactor = 1;
+ }
+ else
+ {
+ // Die ersten 32 Zeichen haben nur eine einfache Genauigkeit, damit
+ // wir nicht soviele Werte abfragen muessen
+ GpiQueryCharStringPosAt( maGraphicsData.mhPS, &aNullPt, 0, 32,
+ (PCH)aFontCharTab32, NULL, aFontCharPtBuf );
+ for ( ; i < 32; i++ )
+ pWidthAry[ i ] = (aFontCharPtBuf[i+1].x - aFontCharPtBuf[i].x) * nFontTabFactor;
+
+ // Die restlichen Zeichen mit (fast) genauer Aufloesung
+ for ( ; i < 256; i++ )
+ {
+ memset( aFontCharTabBuf, i, nFontTabFactor );
+ GpiQueryCharStringPosAt( maGraphicsData.mhPS, &aNullPt, 0, nFontTabFactor,
+ (PCH)aFontCharTabBuf, NULL, aFontCharPtBuf );
+ pWidthAry[ i ] = aFontCharPtBuf[nFontTabFactor].x - aFontCharPtBuf[0].x;
+ }
+ }
+
+ // Orientation? -> rotate back!
+ if ( (maGraphicsData.mnOrientationY != 0) && (maGraphicsData.mnOrientationX != 1) )
+ {
+ CHARBUNDLE aBundle;
+ aBundle.ptlAngle.x = maGraphicsData.mnOrientationX;
+ aBundle.ptlAngle.y = maGraphicsData.mnOrientationY;
+ GpiSetAttrs( maGraphicsData.mhPS, PRIM_CHAR, CBB_ANGLE, 0, &aBundle );
+ }
+
+ return nFontTabFactor;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetFontMetric( ImplFontMetricData* pMetric )
+{
+ FONTMETRICS aOS2Metric;
+ GpiQueryFontMetrics( maGraphicsData.mhPS, sizeof( aOS2Metric ), &aOS2Metric );
+
+ pMetric->maName = aOS2Metric.szFamilyname;
+ pMetric->maStyleName = ImpStyleNameToSal( aOS2Metric.szFamilyname,
+ aOS2Metric.szFacename,
+ strlen( aOS2Metric.szFamilyname ) );
+
+ pMetric->meCharSet = ImplCharSetToSal( aOS2Metric.usCodePage );
+ pMetric->meWeight = ImplWeightToSal( aOS2Metric.usWeightClass );
+
+ if ( aOS2Metric.panose.bFamilyType == 3 )
+ pMetric->meFamily = FAMILY_SCRIPT;
+ else
+ pMetric->meFamily = FAMILY_DONTKNOW;
+
+ if ( aOS2Metric.fsType & FM_TYPE_FIXED )
+ pMetric->mePitch = PITCH_FIXED;
+ else
+ pMetric->mePitch = PITCH_VARIABLE;
+
+ if ( aOS2Metric.fsSelection & FM_SEL_ITALIC )
+ pMetric->meItalic = ITALIC_NORMAL;
+ else
+ pMetric->meItalic = ITALIC_NONE;
+
+ if ( aOS2Metric.fsDefn & FM_DEFN_OUTLINE )
+ {
+ pMetric->meType = TYPE_SCALABLE;
+ pMetric->mnWidth = aOS2Metric.lEmInc;
+ }
+ else
+ {
+ pMetric->meType = TYPE_RASTER;
+ pMetric->mnWidth = aOS2Metric.lAveCharWidth;
+ pMetric->mnOrientation = 0;
+ }
+
+ if ( aOS2Metric.fsDefn & FM_DEFN_GENERIC )
+ pMetric->mbDevice = FALSE;
+ else
+ pMetric->mbDevice = TRUE;
+
+ pMetric->mnAscent = aOS2Metric.lMaxAscender;
+ pMetric->mnDescent = aOS2Metric.lMaxDescender;
+ pMetric->mnLeading = aOS2Metric.lInternalLeading;
+ pMetric->mnSlant = 0;
+ pMetric->mnFirstChar = aOS2Metric.sFirstChar;
+ pMetric->mnLastChar = aOS2Metric.sLastChar;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs )
+{
+ if ( !nPairs || !pKernPairs )
+ {
+ FONTMETRICS aOS2Metric;
+ GpiQueryFontMetrics( maGraphicsData.mhPS, sizeof( aOS2Metric ), &aOS2Metric );
+ return aOS2Metric.sKerningPairs;
+ }
+
+ DBG_ASSERT( sizeof( KERNINGPAIRS ) == sizeof( ImplKernPairData ),
+ "SalGraphics::GetKernPairs(): KERNINGPAIRS != ImplKernPairData" );
+ // Einige Treiber liefern weniger Kerning-Paare, als wir mit
+ // GpiQueryFontMetrics() ermittelt haben. Deshalb hier den Rueckgabewert
+ // anpassen, damit der unabhaengige Teil entsprechend darauf reagieren
+ // kann
+ nPairs = GpiQueryKerningPairs( maGraphicsData.mhPS, nPairs, (KERNINGPAIRS*)pKernPairs );
+ return nPairs;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetDevFontList( ImplDevFontList* pList )
+{
+ PFONTMETRICS pFontMetrics;
+ ULONG nFontMetricCount;
+ SalData* pSalData;
+
+ if ( !maGraphicsData.mbPrinter )
+ {
+ // Bei Bildschirm-Devices cachen wir die Liste global, da
+ // dies im unabhaengigen Teil auch so gemacht wird und wir
+ // ansonsten auf geloeschten Systemdaten arbeiten koennten
+ pSalData = GetSalData();
+ nFontMetricCount = pSalData->mnFontMetricCount;
+ pFontMetrics = pSalData->mpFontMetrics;
+ // Bei Bildschirm-Devices holen wir uns die Fontliste jedesmal neu
+ if ( pFontMetrics )
+ {
+ delete pFontMetrics;
+ pFontMetrics = NULL;
+ nFontMetricCount = 0;
+ }
+ }
+ else
+ {
+ nFontMetricCount = maGraphicsData.mnFontMetricCount;
+ pFontMetrics = maGraphicsData.mpFontMetrics;
+ }
+
+ // do we have to create the cached font list first?
+ if ( !pFontMetrics )
+ {
+ // query the number of fonts available
+ LONG nTemp = 0;
+ nFontMetricCount = GpiQueryFonts( maGraphicsData.mhPS,
+ QF_PUBLIC | QF_PRIVATE,
+ NULL, &nTemp,
+ sizeof( FONTMETRICS ), NULL );
+
+ // procede only if at least one is available!
+ if ( nFontMetricCount )
+ {
+ // allocate memory for font list
+ pFontMetrics = new FONTMETRICS[nFontMetricCount];
+
+ // query font list
+ GpiQueryFonts( maGraphicsData.mhPS,
+ QF_PUBLIC | QF_PRIVATE,
+ NULL,
+ (PLONG)&nFontMetricCount,
+ (LONG) sizeof( FONTMETRICS ),
+ pFontMetrics );
+ }
+
+ if ( !maGraphicsData.mbPrinter )
+ {
+ pSalData->mnFontMetricCount = nFontMetricCount;
+ pSalData->mpFontMetrics = pFontMetrics;
+ }
+ else
+ {
+ maGraphicsData.mnFontMetricCount = nFontMetricCount;
+ maGraphicsData.mpFontMetrics = pFontMetrics;
+ }
+ }
+
+ // copy data from the font list
+ for( ULONG i = 0; i < nFontMetricCount; i++ )
+ {
+ PFONTMETRICS pFontMetric = &pFontMetrics[i];
+
+ // Bildschirm-Bitmap-Font's werden nicht fuer den Drucker angeboten
+ if ( maGraphicsData.mbPrinter )
+ {
+ if ( (pFontMetric->fsDefn & (FM_DEFN_OUTLINE | FM_DEFN_GENERIC)) == FM_DEFN_GENERIC )
+ // Font nicht aufnehmen
+ continue;
+ }
+
+ // create new font list element
+ ImplFontData* pData = new ImplFontData;
+ pData->maName = pFontMetric->szFamilyname;
+ pData->maStyleName = ImpStyleNameToSal( pFontMetric->szFamilyname,
+ pFontMetric->szFacename,
+ strlen( pFontMetric->szFamilyname) );
+ pData->mpSysData = (void*)pFontMetric;
+ pData->meCharSet = ImplCharSetToSal( pFontMetric->usCodePage );
+ pData->meWeight = ImplWeightToSal( pFontMetric->usWeightClass );
+ pData->meWidthType = WIDTH_DONTKNOW;
+ if ( pFontMetric->panose.bFamilyType == 3 )
+ pData->meFamily = FAMILY_SCRIPT;
+ else
+ pData->meFamily = FAMILY_DONTKNOW;
+ if ( pFontMetric->fsType & FM_TYPE_FIXED )
+ pData->mePitch = PITCH_FIXED;
+ else
+ pData->mePitch = PITCH_VARIABLE;
+ if ( pFontMetric->fsSelection & FM_SEL_ITALIC )
+ pData->meItalic = ITALIC_NORMAL;
+ else
+ pData->meItalic = ITALIC_NONE;
+ if ( pFontMetric->fsDefn & FM_DEFN_OUTLINE )
+ pData->meType = TYPE_SCALABLE;
+ else
+ pData->meType = TYPE_RASTER;
+ if ( pFontMetric->fsDefn & FM_DEFN_GENERIC )
+ pData->mbDevice = FALSE;
+ else
+ pData->mbDevice = TRUE;
+ if ( pData->meType != TYPE_RASTER )
+ {
+ pData->mnWidth = 0;
+ pData->mnHeight = 0;
+ pData->mbOrientation = TRUE;
+ }
+ else
+ {
+ pData->mnWidth = pFontMetric->lAveCharWidth;
+ pData->mnHeight = pFontMetric->lMaxBaselineExt;
+ pData->mbOrientation = FALSE;
+ }
+ pData->mnQuality = 0;
+
+ // add font list element to font list
+ pList->Add( pData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawText( long nX, long nY, const xub_Unicode* pStr, USHORT nLen )
+{
+ DBG_ERROR( "SalGraphics::DrawText called!" );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawTextArray( long nX, long nY,
+ const xub_Unicode* pStr, USHORT nLen,
+ const long* pDXAry )
+{
+ POINTL aPt;
+ LONG aStackAry[ SAL_DRAWTEXT_STACKBUF ];
+ LONG* pOS2DXAry;
+
+ if ( nLen <= SAL_DRAWTEXT_STACKBUF )
+ pOS2DXAry = aStackAry;
+ else
+ pOS2DXAry = new LONG[nLen];
+
+ aPt.x = nX;
+ aPt.y = maGraphicsData.mnHeight - nY;
+
+ pOS2DXAry[0] = (LONG)pDXAry[0];
+ for ( USHORT i = 1; i < nLen-1; i++ )
+ pOS2DXAry[i] = (LONG)pDXAry[i]-pDXAry[i-1];
+ pOS2DXAry[nLen-1] = 0;
+
+ // OS2 kann max. 512-Zeichen lange Strings ausgeben, deshalb kuerzen
+ // wir den String auf eine Laenge von 512-Zeichen
+ if ( nLen > 512 )
+ {
+ // Wir versuchen links die Zeichen zu ueberspringen, die evtl. im
+ // nicht sichtbaren Bereich liegen
+ LONG nWidth = 0;
+ LONG nCharWidth;
+ while ( nLen > 512 )
+ {
+ nCharWidth = *pOS2DXAry;
+ if ( (aPt.x+nWidth+nCharWidth) >= -999 )
+ break;
+ nWidth += nCharWidth;
+ pStr++;
+ pOS2DXAry++;
+ nLen--;
+ }
+
+ if ( nLen > 512 )
+ nLen = 512;
+
+ aPt.x = aPt.x + nWidth;
+ }
+
+ GpiCharStringPosAt( maGraphicsData.mhPS, &aPt, NULL, CHS_VECTOR, nLen, (PCH)pStr, pOS2DXAry );
+
+ if ( pOS2DXAry != aStackAry )
+ delete pOS2DXAry;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalGraphics::GetGlyphBoundRect( xub_Unicode cChar, long* pX, long* pY,
+ long* pWidth, long* pHeight )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+///---------------------------- PUBLIC ROUTINE -------------------------------
+// Using the following macro in PMDDIM.H you can use a GRE call to get the char outline
+// of system outline fonts. This call does not work for system bitmap fonts or device fonts.
+// Truetype fonts should also work however the data returned for truetype fonts will be mostly
+// scanline data until you install the latest fixpak ("31 or 32" I Think). The fix pak will improve
+// the data returned for truetype fonts to include curves. This call was
+// implemented in merlin and should be in fix pak 26 for Warp as well.
+//
+// #define GreQueryCharOutline(a,b,c,d,e)
+// (LONG)Gre32Entry7((HDC)(a),(ULONG)(b),(ULONG)(PBYTE)(c),(ULONG)(d),(ULONG)(e),0L,0x00004256L)
+// #define NGreQueryCharOutline 0x00004256L
+//
+// LONG APIENTRY QueryCharOutline32 (HDC hdc, ULONG ulCode, PBYTE pBuffer,
+// ULONG ulLen, ULONG fl, ULONG hddc,
+// ULONG ulFunN)
+//
+// This function returns outline data information of the specified
+// character glyph
+//
+// Parameters: hdc Device context handle
+// ulCode Code point
+// pBuffer Pointer to outline data to be returned
+// ulLen Length in bytes of pBuffer
+// fl Options flags
+// QCO_FORMAT_GOCA
+// QCO_FORMAT_IFI
+// QCO_NO_TRANSFORM
+// hddc
+// ulFunN
+// Returns:
+// The number of bytes needed to store character outline
+// GPI_ALTERROR
+//
+
+// -----------------------------------------------------------------------
+
+ULONG SalGraphics::GetGlyphOutline( xub_Unicode cChar, USHORT** ppPolySizes,
+ SalPoint** ppPoints, BYTE** ppFlags )
+{
+ return 0;
+}
diff --git a/vcl/os2/source/gdi/salogl.cxx b/vcl/os2/source/gdi/salogl.cxx
new file mode 100644
index 000000000000..bae6bc3f8222
--- /dev/null
+++ b/vcl/os2/source/gdi/salogl.cxx
@@ -0,0 +1,263 @@
+/*************************************************************************
+ *
+ * $RCSfile: salogl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+#define INCL_DOSMODULEMGR
+#include <tools/svpm.h>
+#define _SV_SALOGL_CXX
+#ifndef _SV_SALOGL_HXX
+#include <salogl.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+
+// ------------
+// - Typedefs -
+// ------------
+
+typedef VISUALCONFIG* PCFG;
+
+// ------------
+// - Lib-Name -
+// ------------
+
+#define OGL_LIBNAME "OPENGL"
+
+// ----------
+// - Macros -
+// ----------
+
+#define GET_OGLFNC_PGL( FncName ) \
+ nResult = DosQueryProcAddr( mhOGLLib, 0, "pgl" #FncName, (PFN*)&pFnc##FncName ); \
+if( nResult != 0 ) \
+ bRet = FALSE;
+
+// ------------------------------------------------------------------------
+
+#define GET_OGLFNC_GL( FncName ) \
+ nResult = DosQueryProcAddr( mhOGLLib, 0, "gl" #FncName, (PFN*)&pFnc##FncName ); \
+if( nResult != 0 ) \
+ bRet = FALSE;
+
+// -----------------
+// - Statics init. -
+// -----------------
+
+// Members
+HMODULE SalOpenGL::mhOGLLib = 0;
+HGC SalOpenGL::mhOGLContext = 0;
+HDC SalOpenGL::mhOGLLastDC = 0;
+ULONG SalOpenGL::mnOGLState = OGL_STATE_UNLOADED;
+
+// Internal use
+INIT_OGLFNC( SalOpenGL, ChooseConfig );
+INIT_OGLFNC( SalOpenGL, QueryConfigs );
+INIT_OGLFNC( SalOpenGL, CreateContext );
+INIT_OGLFNC( SalOpenGL, DestroyContext );
+INIT_OGLFNC( SalOpenGL, GetCurrentContext );
+INIT_OGLFNC( SalOpenGL, MakeCurrent );
+INIT_OGLFNC( SalOpenGL, QueryCapability );
+
+// -------------
+// - SalOpenGL -
+// -------------
+
+SalOpenGL::SalOpenGL( SalGraphics* pGraphics )
+{
+ // Set mhOGLLastDC only the first time a
+ // SalOpenGL object is created; we need
+ // this DC in SalOpenGL::Create();
+ if( OGL_STATE_UNLOADED == mnOGLState )
+ mhOGLLastDC = pGraphics->maGraphicsData.mhDC;
+}
+
+// ------------------------------------------------------------------------
+
+SalOpenGL::~SalOpenGL()
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::Create()
+{
+ BOOL bRet = FALSE;
+
+ if( OGL_STATE_UNLOADED == mnOGLState )
+ {
+ if( ImplInitLib() )
+ {
+/*
+ if( ImplInit() )
+ {
+ HAB hAB = GetSalData()->mhAB;
+ VISUALCONFIG aCfg = { PGL_RGBA, PGL_RED_SIZE, 4, PGL_GREEN_SIZE, 4,PGL_BLUE_SIZE, 4, PGL_DOUBLEBUFFER, 0 };
+ PCFG* ppCfgs = pFncQueryConfigs( hAB );
+
+ if( *ppCfgs )
+ {
+ if( ( mhOGLContext = pFncCreateContext( hAB, *ppCfgs, NULL, FALSE ) ) != 0 )
+ {
+ pFncMakeCurrent( hAB, mhOGLContext, WinWindowFromDC( mhOGLLastDC ) );
+ mnOGLState = OGL_STATE_VALID;
+ bRet = TRUE;
+ }
+ }
+ }
+*/
+
+ if( !bRet )
+ {
+ ImplFreeLib();
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ }
+ else
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ else if( OGL_STATE_VALID == mnOGLState )
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::Release()
+{
+ ImplFreeLib();
+}
+
+// ------------------------------------------------------------------------
+
+void* SalOpenGL::GetOGLFnc( const String& rFncName )
+{
+ void* pRet;
+
+ if( mhOGLLib )
+ {
+ APIRET rc;
+ PFN pFunction;
+
+ rc = DosQueryProcAddr( mhOGLLib, 0, rFncName, &pFunction );
+ pRet = rc == NULL ? pFunction : NULL;
+ }
+ else
+ pRet = NULL;
+
+ return pRet;
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::OGLEntry( SalGraphics* pGraphics )
+{
+ if( pGraphics->maGraphicsData.mhDC != mhOGLLastDC )
+ {
+ mhOGLLastDC = pGraphics->maGraphicsData.mhDC;
+ pFncMakeCurrent( GetSalData()->mhAB, mhOGLContext, WinWindowFromDC( mhOGLLastDC ) );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::OGLExit( SalGraphics* pGraphics )
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::ImplInitLib()
+{
+ DosLoadModule ((PSZ)0, 0, OGL_LIBNAME, &mhOGLLib );
+ return( mhOGLLib != NULL );
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::ImplFreeLib()
+{
+ if( mhOGLLib )
+ DosFreeModule( mhOGLLib );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::ImplInit()
+{
+ ULONG nResult;
+ BOOL bRet = TRUE;
+
+ // Internal use
+ GET_OGLFNC_PGL( ChooseConfig );
+ GET_OGLFNC_PGL( QueryConfigs );
+ GET_OGLFNC_PGL( CreateContext );
+ GET_OGLFNC_PGL( DestroyContext );
+ GET_OGLFNC_PGL( GetCurrentContext );
+ GET_OGLFNC_PGL( MakeCurrent );
+ GET_OGLFNC_PGL( QueryCapability );
+
+ return bRet;
+}
diff --git a/vcl/os2/source/gdi/salprn.cxx b/vcl/os2/source/gdi/salprn.cxx
new file mode 100644
index 000000000000..95e6baa2d6fb
--- /dev/null
+++ b/vcl/os2/source/gdi/salprn.cxx
@@ -0,0 +1,1878 @@
+/*************************************************************************
+ *
+ * $RCSfile: salprn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+// use this define to disable the DJP support
+// #define NO_DJP
+
+#define INCL_DOSMODULEMGR
+#define INCL_DEV
+#define INCL_SPL
+#define INCL_SPLDOSPRINT
+#define INCL_DEVDJP
+
+#define BOOL PM_BOOL
+#define BYTE PM_BYTE
+#define USHORT PM_USHORT
+#define ULONG PM_ULONG
+
+#define INCL_PM
+#include <os2.h>
+#include "pmdjp.h"
+
+#undef BOOL
+#undef BYTE
+#undef USHORT
+#undef ULONG
+
+#include <string.h>
+
+#define _SV_SALPRN_CXX
+
+#ifndef _NEW_HXX
+#include <tools/new.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALPTYPE_HXX
+#include <salptype.hxx>
+#endif
+#ifndef _SV_SALPRN_HXX
+#include <salprn.hxx>
+#endif
+
+#ifndef _SV_PRINT_H
+#include <print.h>
+#endif
+#ifndef _SV_JOBSET_H
+#include <jobset.h>
+#endif
+
+// =======================================================================
+
+// -----------------------
+// - struct ImplFormInfo -
+// -----------------------
+
+struct ImplFormInfo
+{
+ long mnPaperWidth;
+ long mnPaperHeight;
+ DJPT_PAPERSIZE mnId;
+};
+
+// =======================================================================
+
+// -----------------------
+// - struct ImplTrayInfo -
+// -----------------------
+
+struct ImplTrayInfo
+{
+ XubString maName;
+ XubString maDisplayName;
+ DJPT_TRAYTYPE mnId;
+
+ ImplTrayInfo( const char* pTrayName,
+ const char* pTrayDisplayName ) :
+ maName( pTrayName ),
+ maDisplayName( pTrayDisplayName )
+ {}
+};
+
+// =======================================================================
+
+struct ImplQueueSalSysData
+{
+ String maPrinterName; // pszPrinters
+ String maName; // pszName bzw. LogAddress
+ String maOrgDriverName; // pszDriverName (maDriverName.maDeviceName)
+ String maDriverName; // pszDriverName bis .
+ String maDeviceName; // pszDriverName nach .
+ PDRIVDATA mpDrivData;
+
+ ImplQueueSalSysData( const String& rPrinterName,
+ const String& rName,
+ const String& rDriverName,
+ const String& rDeviceName,
+ const String& rOrgDriverName,
+ PDRIVDATA pDrivData );
+ ~ImplQueueSalSysData();
+};
+
+// -----------------------------------------------------------------------
+
+ImplQueueSalSysData::ImplQueueSalSysData( const String& rPrinterName,
+ const String& rName,
+ const String& rOrgDriverName,
+ const String& rDriverName,
+ const String& rDeviceName,
+ PDRIVDATA pDrivData ) :
+ maPrinterName( rPrinterName ),
+ maName( rName ),
+ maOrgDriverName( rName ),
+ maDriverName( rDriverName ),
+ maDeviceName( rDeviceName )
+{
+ if ( pDrivData )
+ {
+ mpDrivData = (PDRIVDATA)new BYTE[pDrivData->cb];
+ memcpy( mpDrivData, pDrivData, pDrivData->cb );
+ }
+ else
+ mpDrivData = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplQueueSalSysData::~ImplQueueSalSysData()
+{
+ delete mpDrivData;
+}
+
+// =======================================================================
+
+static ULONG ImplPMQueueStatusToSal( PM_USHORT nPMStatus )
+{
+ ULONG nStatus = 0;
+ if ( nPMStatus & PRQ3_PAUSED )
+ nStatus |= QUEUE_STATUS_PAUSED;
+ if ( nPMStatus & PRQ3_PENDING )
+ nStatus |= QUEUE_STATUS_PENDING_DELETION;
+ if ( !nStatus )
+ nStatus |= QUEUE_STATUS_READY;
+ return nStatus;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
+{
+ APIRET rc;
+ ULONG nNeeded;
+ ULONG nReturned;
+ ULONG nTotal;
+
+ // query needed size of the buffer for the QueueInfo
+ rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL );
+ if( nNeeded == 0 )
+ return;
+
+ // create the buffer for the QueueInfo
+ PCHAR pQueueData = new CHAR[nNeeded];
+
+ // query QueueInfos
+ rc = SplEnumQueue( (PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL );
+
+ PPRQINFO3 pPrqInfo = (PPRQINFO3)pQueueData;
+ for ( int i = 0; i < nReturned; i++ )
+ {
+ // create entry for the QueueInfo array
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+
+ String aOrgDriverName( pPrqInfo->pszDriverName );
+ String aName( pPrqInfo->pszName );
+ pInfo->maDriver = aOrgDriverName;
+ pInfo->maPrinterName = pPrqInfo->pszComment;
+ pInfo->maLocation = aName;
+ pInfo->mnStatus = ImplPMQueueStatusToSal( pPrqInfo->fsStatus );
+ pInfo->mnJobs = pPrqInfo->cJobs;
+ // pInfo->maComment = !!!
+
+ // Feststellen, ob Name doppelt
+ PPRQINFO3 pTempPrqInfo = (PPRQINFO3)pQueueData;
+ for ( int j = 0; j < nReturned; j++ )
+ {
+ // Wenn Name doppelt, erweitern wir diesen um die Location
+ if ( (j != i) &&
+ (strcmp( pPrqInfo->pszComment, pTempPrqInfo->pszComment ) == 0) )
+ {
+ pInfo->maPrinterName += ';';
+ pInfo->maPrinterName += pInfo->maLocation;
+ }
+ pTempPrqInfo++;
+ }
+
+ // pszDriver in DriverName (bis .) und DeviceName (nach .) aufsplitten
+ PSZ pDriverName;
+ PSZ pDeviceName;
+ if ( (pDriverName = strchr( pPrqInfo->pszDriverName, '.' )) != 0 )
+ {
+ *pDriverName = 0;
+ pDeviceName = pDriverName + 1;
+ }
+ else
+ pDeviceName = NULL;
+
+ // Alle Bytes hinter dem DeviceNamen auf 0 initialisieren, damit
+ // ein memcmp vom JobSetup auch funktioniert
+ if ( pPrqInfo->pDriverData &&
+ (pPrqInfo->pDriverData->cb >= sizeof( pPrqInfo->pDriverData )) )
+ {
+ int nDeviceNameLen = strlen( pPrqInfo->pDriverData->szDeviceName );
+ memset( pPrqInfo->pDriverData->szDeviceName+nDeviceNameLen,
+ 0,
+ sizeof( pPrqInfo->pDriverData->szDeviceName )-nDeviceNameLen );
+ }
+
+ // save driver data and driver names
+ String aPrinterName( pPrqInfo->pszPrinters );
+ String aDriverName( pPrqInfo->pszDriverName );
+ String aDeviceName;
+ if ( pDeviceName )
+ aDeviceName = pDeviceName;
+ pInfo->mpSysData = new ImplQueueSalSysData( aPrinterName, aName,
+ aOrgDriverName,
+ aDriverName, aDeviceName,
+ pPrqInfo->pDriverData );
+
+ // add queue to the list
+ pList->Add( pInfo );
+
+ // increment to next element of the QueueInfo array
+ pPrqInfo++;
+ }
+
+ delete [] pQueueData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo )
+{
+ APIRET rc;
+ ULONG nNeeded;
+ ULONG nReturned;
+ ULONG nTotal;
+
+ // query needed size of the buffer for the QueueInfo
+ rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL );
+ if( nNeeded == 0 )
+ return;
+
+ // create the buffer for the QueueInfo
+ PCHAR pQueueData = new CHAR[nNeeded];
+
+ // query QueueInfos
+ rc = SplEnumQueue( (PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL );
+
+ PPRQINFO3 pPrqInfo = (PPRQINFO3)pQueueData;
+ for ( int i = 0; i < nReturned; i++ )
+ {
+ ImplQueueSalSysData* pSysData = (ImplQueueSalSysData*)(pInfo->mpSysData);
+ if ( (strcmp( pSysData->maPrinterName, pPrqInfo->pszPrinters ) == 0) &&
+ (strcmp( pSysData->maName, pPrqInfo->pszName ) == 0) &&
+ (strcmp( pSysData->maOrgDriverName, pPrqInfo->pszDriverName ) == 0) )
+ {
+ pInfo->mnStatus = ImplPMQueueStatusToSal( pPrqInfo->fsStatus );
+ pInfo->mnJobs = pPrqInfo->cJobs;
+ break;
+ }
+
+ // increment to next element of the QueueInfo array
+ pPrqInfo++;
+ }
+
+ delete [] pQueueData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
+{
+ delete ((ImplQueueSalSysData*)(pInfo->mpSysData));
+ delete pInfo;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalInstance::GetDefaultPrinter()
+{
+ APIRET rc;
+ ULONG nNeeded;
+ ULONG nReturned;
+ ULONG nTotal;
+ char szQueueName[255];
+ XubString aDefaultName;
+
+ // query default queue
+ if ( !PrfQueryProfileString( HINI_PROFILE, SPL_INI_SPOOLER, "QUEUE", 0, szQueueName, sizeof( szQueueName ) ) )
+ return aDefaultName;
+
+ // extract first queue name
+ PSZ pStr;
+ if ( (pStr = strchr( szQueueName, ';' )) != 0 )
+ *pStr = 0;
+
+ // query needed size of the buffer for the QueueInfo
+ rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL );
+ if ( nNeeded == 0 )
+ return aDefaultName;
+
+ // create the buffer for the QueueInfo
+ PCHAR pQueueData = new CHAR[ nNeeded ];
+
+ // query QueueInfos
+ rc = SplEnumQueue ((PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL );
+
+ // find printer name for default queue
+ PPRQINFO3 pPrqInfo = (PPRQINFO3) pQueueData;
+ for ( int i = 0; i < nReturned; i++ )
+ {
+ if ( strcmp( pPrqInfo->pszName, szQueueName ) == 0 )
+ {
+ aDefaultName = pPrqInfo->pszComment;
+
+ // Feststellen, ob Name doppelt
+ PPRQINFO3 pTempPrqInfo = (PPRQINFO3)pQueueData;
+ for ( int j = 0; j < nReturned; j++ )
+ {
+ // Wenn Name doppelt, erweitern wir diesen um die Location
+ if ( (j != i) &&
+ (strcmp( pPrqInfo->pszComment, pTempPrqInfo->pszComment ) == 0) )
+ {
+ aDefaultName += ';';
+ aDefaultName += pPrqInfo->pszName;
+ }
+ pTempPrqInfo++;
+ }
+ break;
+ }
+
+ // increment to next element of the QueueInfo array
+ pPrqInfo++;
+ }
+
+ delete [] pQueueData;
+
+ return aDefaultName;
+}
+
+// =======================================================================
+
+static void* ImplAllocPrnMemory( size_t n )
+{
+ PVOID pVoid = 0;
+
+ if ( DosAllocMem( &pVoid, n, PAG_COMMIT | PAG_READ | PAG_WRITE ) )
+ return 0;
+
+ return pVoid;
+}
+
+// -----------------------------------------------------------------------
+
+inline void ImplFreePrnMemory( void* p )
+{
+ DosFreeMem( p );
+}
+
+// -----------------------------------------------------------------------
+
+static PDRIVDATA ImplPrnDrivData( const ImplJobSetup* pSetupData )
+{
+ // Diese Funktion wird eingesetzt, damit Druckertreiber nicht auf
+ // unseren Daten arbeiten, da es durch Konfigurationsprobleme
+ // sein kann, das der Druckertreiber bei uns Daten ueberschreibt.
+ // Durch diese vorgehensweise werden einige Abstuerze vermieden, bzw.
+ // sind dadurch leichter zu finden
+
+ if ( !pSetupData->mpDriverData )
+ return NULL;
+
+ DBG_ASSERT( ((PRIVDATA)(pSetupData->mpDriverData))->cb == pSetupData->mnDriverDataLen,
+ "ImplPrnDrivData() - SetupDataLen != DriverDataLen" );
+
+ PDRIVDATA pDrivData = (PDRIVDATA)ImplAllocPrnMemory( pSetupData->mnDriverDataLen );
+ memcpy( pDrivData, pSetupData->mpDriverData, pSetupData->mnDriverDataLen );
+ return pDrivData;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplUpdateSetupData( const PDRIVDATA pDrivData, ImplJobSetup* pSetupData )
+{
+ // Diese Funktion wird eingesetzt, damit Druckertreiber nicht auf
+ // unseren Daten arbeiten, da es durch Konfigurationsprobleme
+ // sein kann, das der Druckertreiber bei uns Daten ueberschreibt.
+ // Durch diese vorgehensweise werden einige Abstuerze vermieden, bzw.
+ // sind dadurch leichter zu finden
+
+ if ( !pDrivData || !pDrivData->cb )
+ {
+ if ( pSetupData->mpDriverData )
+ delete pSetupData->mpDriverData;
+ pSetupData->mnDriverDataLen = 0;
+ }
+ else
+ {
+ // Alle Bytes hinter dem DeviceNamen auf 0 initialisieren, damit
+ // ein memcmp vom JobSetup auch funktioniert
+ if ( pDrivData->cb >= sizeof( pDrivData ) )
+ {
+ int nDeviceNameLen = strlen( pDrivData->szDeviceName );
+ memset( pDrivData->szDeviceName+nDeviceNameLen,
+ 0,
+ sizeof( pDrivData->szDeviceName )-nDeviceNameLen );
+ }
+
+ if ( pSetupData->mpDriverData )
+ {
+ if ( pSetupData->mnDriverDataLen != pDrivData->cb )
+ delete pSetupData->mpDriverData;
+ pSetupData->mpDriverData = new BYTE[pDrivData->cb];
+ }
+ else
+ pSetupData->mpDriverData = new BYTE[pDrivData->cb];
+ pSetupData->mnDriverDataLen = pDrivData->cb;
+ memcpy( pSetupData->mpDriverData, pDrivData, pDrivData->cb );
+ }
+
+ if ( pDrivData )
+ ImplFreePrnMemory( pDrivData );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplPaperSizeEqual( long nPaperWidth1, long nPaperHeight1,
+ long nPaperWidth2, long nPaperHeight2 )
+{
+ return (((nPaperWidth1 >= nPaperWidth2-1) && (nPaperWidth1 <= nPaperWidth2+1)) &&
+ ((nPaperHeight1 >= nPaperHeight2-1) && (nPaperHeight1 <= nPaperHeight2+1)));
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplIsDriverDJPEnabled( HDC hDC )
+{
+#ifdef NO_DJP
+ return FALSE;
+#else
+ // Ueber OS2-Ini kann DJP disablte werden
+ if ( !PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_USEDJP, 1 ) )
+ return FALSE;
+
+ // Testen, ob DJP-Interface am Drucker vorhanden
+ LONG lQuery;
+ APIRET rc;
+
+ lQuery = DEVESC_QUERYSIZE;
+ rc = DevEscape( hDC,
+ DEVESC_QUERYESCSUPPORT,
+ sizeof( lQuery ),
+ (PBYTE)&lQuery,
+ 0,
+ (PBYTE)NULL );
+ if ( DEV_OK != rc )
+ return FALSE;
+
+ lQuery = DEVESC_QUERYJOBPROPERTIES;
+ rc = DevEscape( hDC,
+ DEVESC_QUERYESCSUPPORT,
+ sizeof( lQuery ),
+ (PBYTE)&lQuery,
+ 0,
+ (PBYTE)NULL );
+ if ( DEV_OK != rc )
+ return FALSE;
+
+ lQuery = DEVESC_SETJOBPROPERTIES;
+ rc = DevEscape( hDC,
+ DEVESC_QUERYESCSUPPORT,
+ sizeof( lQuery ),
+ (PBYTE)&lQuery,
+ 0,
+ (PBYTE)NULL );
+ if ( DEV_OK != rc )
+ return FALSE;
+
+ return TRUE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplFormatInputList( PDJP_ITEM pDJP, PQUERYTUPLE pTuple )
+{
+ // Loop through the query elements
+ BOOL fContinue = TRUE;
+ do
+ {
+ pDJP->cb = sizeof (DJP_ITEM);
+ pDJP->ulProperty = pTuple->ulProperty;
+ pDJP->lType = pTuple->lType;
+ pDJP->ulNumReturned = 0;
+ pDJP->ulValue = DJP_NONE;
+
+ // at EOL?
+ fContinue = DJP_NONE != pTuple->ulProperty;
+
+ // Move to next item structure and tuplet
+ pDJP++;
+ pTuple++;
+ }
+ while ( fContinue );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplFreeFormAndTrayList( SalInfoPrinter* pSalInfoPrinter )
+{
+ if ( pSalInfoPrinter->maPrinterData.mnFormCount )
+ {
+ for ( USHORT i = 0; i < pSalInfoPrinter->maPrinterData.mnFormCount; i++ )
+ delete pSalInfoPrinter->maPrinterData.mpFormArray[i];
+ delete [] pSalInfoPrinter->maPrinterData.mpFormArray;
+ pSalInfoPrinter->maPrinterData.mnFormCount = 0;
+ }
+
+ if ( pSalInfoPrinter->maPrinterData.mnTrayCount )
+ {
+ for ( USHORT i = 0; i < pSalInfoPrinter->maPrinterData.mnTrayCount; i++ )
+ delete pSalInfoPrinter->maPrinterData.mpTrayArray[i];
+ delete [] pSalInfoPrinter->maPrinterData.mpTrayArray;
+ pSalInfoPrinter->maPrinterData.mnTrayCount = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetFormAndTrayList( SalInfoPrinter* pSalInfoPrinter, const ImplJobSetup* pSetupData )
+{
+ ImplFreeFormAndTrayList( pSalInfoPrinter );
+
+ LONG alQuery[] =
+ {
+ 0, 0, // First two members of QUERYSIZE
+ DJP_CJ_FORM, DJP_ALL,
+ DJP_CJ_TRAYNAME, DJP_ALL,
+ DJP_NONE, DJP_NONE // EOL marker
+ };
+
+ APIRET rc;
+ PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery;
+ PBYTE pBuffer = NULL;
+ LONG nAlloc = 0;
+ PDRIVDATA pCopyDrivData = ImplPrnDrivData( pSetupData );
+ LONG nDrivDataSize = pCopyDrivData->cb;
+ PBYTE pDrivData = (PBYTE)pCopyDrivData;
+
+ // find out how many bytes to allocate
+ pQuerySize->cb = sizeof( alQuery );
+ rc = DevEscape( pSalInfoPrinter->maPrinterData.mhDC,
+ DEVESC_QUERYSIZE,
+ sizeof( alQuery ),
+ (PBYTE)pQuerySize,
+ &nDrivDataSize,
+ pDrivData );
+ if ( DEV_OK != rc )
+ {
+ ImplFreePrnMemory( pCopyDrivData );
+ return;
+ }
+
+ // allocate the memory
+ nAlloc = pQuerySize->ulSizeNeeded;
+ pBuffer = (PBYTE)new BYTE[nAlloc];
+
+ // set up the input
+ PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
+ ImplFormatInputList( pDJP, pQuerySize->aTuples );
+
+ // do it!
+ rc = DevEscape( pSalInfoPrinter->maPrinterData.mhDC,
+ DEVESC_QUERYJOBPROPERTIES,
+ nAlloc,
+ pBuffer,
+ &nDrivDataSize,
+ pDrivData );
+ ImplFreePrnMemory( pCopyDrivData );
+
+ if ( (DEV_OK == rc) || (DEV_WARNING == rc) )
+ {
+ // Loop through the query elements
+ PQUERYTUPLE pTuple = pQuerySize->aTuples;
+ while ( DJP_NONE != pTuple->ulProperty )
+ {
+ if ( pDJP->ulProperty == DJP_CJ_FORM )
+ {
+ if ( pDJP->ulNumReturned )
+ {
+ PDJPT_FORM pElm = DJP_ELEMENTP( *pDJP, DJPT_FORM );
+
+ pSalInfoPrinter->maPrinterData.mnFormCount = pDJP->ulNumReturned;
+ pSalInfoPrinter->maPrinterData.mpFormArray = new PIMPLFORMINFO[pSalInfoPrinter->maPrinterData.mnFormCount];
+ for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ )
+ {
+ ImplFormInfo* pInfo = new ImplFormInfo;
+ pInfo->mnPaperWidth = pElm->hcInfo.cx;
+ pInfo->mnPaperHeight = pElm->hcInfo.cy;
+ pInfo->mnId = pElm->djppsFormID;
+ pSalInfoPrinter->maPrinterData.mpFormArray[i] = pInfo;
+ }
+ }
+ }
+ else if ( pDJP->ulProperty == DJP_CJ_TRAYNAME )
+ {
+ if ( pDJP->ulNumReturned )
+ {
+ PDJPT_TRAYNAME pElm = DJP_ELEMENTP( *pDJP, DJPT_TRAYNAME );
+
+ pSalInfoPrinter->maPrinterData.mnTrayCount = pDJP->ulNumReturned;
+ pSalInfoPrinter->maPrinterData.mpTrayArray = new PIMPLTRAYINFO[pSalInfoPrinter->maPrinterData.mnTrayCount];
+ for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ )
+ {
+ ImplTrayInfo* pInfo = new ImplTrayInfo( pElm->szTrayname, pElm->szDisplayTrayname );
+ pInfo->mnId = pElm->djpttTrayID;
+ pSalInfoPrinter->maPrinterData.mpTrayArray[i] = pInfo;
+ }
+ }
+ }
+
+ pDJP = DJP_NEXT_STRUCTP( pDJP );
+ pTuple++;
+ }
+ }
+
+ delete [] pBuffer;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplGetCurrentSettings( SalInfoPrinter* pSalInfoPrinter, ImplJobSetup* pSetupData )
+{
+ // Um den aktuellen Tray zu ermitteln, brauchen wir auch die Listen dazu
+ if ( !pSalInfoPrinter->maPrinterData.mnFormCount )
+ ImplGetFormAndTrayList( pSalInfoPrinter, pSetupData );
+
+ LONG alQuery[] =
+ {
+ 0, 0, // First two members of QUERYSIZE
+ DJP_SJ_ORIENTATION, DJP_CURRENT,
+ DJP_CJ_FORM, DJP_CURRENT,
+ DJP_NONE, DJP_NONE // EOL marker
+ };
+
+ APIRET rc;
+ PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery;
+ PBYTE pBuffer = NULL;
+ LONG nAlloc = 0;
+ PDRIVDATA pCopyDrivData = ImplPrnDrivData( pSetupData );
+ LONG nDrivDataSize = pCopyDrivData->cb;
+ PBYTE pDrivData = (PBYTE)pCopyDrivData;
+ BOOL bResult;
+
+ // find out how many bytes to allocate
+ pQuerySize->cb = sizeof( alQuery );
+ rc = DevEscape( pSalInfoPrinter->maPrinterData.mhDC,
+ DEVESC_QUERYSIZE,
+ sizeof( alQuery ),
+ (PBYTE)pQuerySize,
+ &nDrivDataSize,
+ pDrivData );
+ if ( DEV_OK != rc )
+ {
+ ImplFreePrnMemory( pCopyDrivData );
+ return FALSE;
+ }
+
+ // allocate the memory
+ nAlloc = pQuerySize->ulSizeNeeded;
+ pBuffer = (PBYTE)new BYTE[nAlloc];
+
+ // set up the input
+ PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
+ ImplFormatInputList( pDJP, pQuerySize->aTuples );
+
+ rc = DevEscape( pSalInfoPrinter->maPrinterData.mhDC,
+ DEVESC_QUERYJOBPROPERTIES,
+ nAlloc,
+ pBuffer,
+ &nDrivDataSize,
+ pDrivData );
+ if ( (DEV_OK == rc) || (DEV_WARNING == rc) )
+ {
+ // aktuelle Setup-Daten uebernehmen
+ ImplUpdateSetupData( pCopyDrivData, pSetupData );
+
+ // Loop through the query elements
+ PQUERYTUPLE pTuple = pQuerySize->aTuples;
+ while ( DJP_NONE != pTuple->ulProperty )
+ {
+ if ( pDJP->ulProperty == DJP_SJ_ORIENTATION )
+ {
+ if ( pDJP->ulNumReturned )
+ {
+ PDJPT_ORIENTATION pElm = DJP_ELEMENTP( *pDJP, DJPT_ORIENTATION );
+ if ( (DJP_ORI_PORTRAIT == *pElm) || (DJP_ORI_REV_PORTRAIT == *pElm) )
+ pSetupData->meOrientation = ORIENTATION_PORTRAIT;
+ else
+ pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
+ }
+ }
+ else if ( pDJP->ulProperty == DJP_CJ_FORM )
+ {
+ if ( pDJP->ulNumReturned )
+ {
+ PDJPT_FORM pElm = DJP_ELEMENTP( *pDJP, DJPT_FORM );
+
+ pSetupData->mnPaperWidth = pElm->hcInfo.cx*100;
+ pSetupData->mnPaperHeight = pElm->hcInfo.cy*100;
+ switch( pElm->djppsFormID )
+ {
+ case DJP_PSI_A3:
+ pSetupData->mePaperFormat = PAPER_A3;
+ break;
+
+ case DJP_PSI_A4:
+ pSetupData->mePaperFormat = PAPER_A4;
+ break;
+
+ case DJP_PSI_A5:
+ pSetupData->mePaperFormat = PAPER_A5;
+ break;
+
+ case DJP_PSI_B4:
+ pSetupData->mePaperFormat = PAPER_B4;
+ break;
+
+ case DJP_PSI_B5:
+ pSetupData->mePaperFormat = PAPER_B5;
+ break;
+
+ case DJP_PSI_LETTER:
+ pSetupData->mePaperFormat = PAPER_LETTER;
+ break;
+
+ case DJP_PSI_LEGAL:
+ pSetupData->mePaperFormat = PAPER_LEGAL;
+ break;
+
+ case DJP_PSI_TABLOID:
+ pSetupData->mePaperFormat = PAPER_TABLOID;
+ break;
+
+ default:
+ pSetupData->mePaperFormat = PAPER_USER;
+ break;
+ }
+
+ // Wir suchen zuerst ueber den Namen/Id und dann ueber die Id
+ BOOL bTrayFound = FALSE;
+ USHORT j;
+ for ( j = 0; j < pSalInfoPrinter->maPrinterData.mnTrayCount; j++ )
+ {
+ if ( (pSalInfoPrinter->maPrinterData.mpTrayArray[j]->mnId == pElm->djpttTrayID) &&
+ (pSalInfoPrinter->maPrinterData.mpTrayArray[j]->maName == pElm->szTrayname) )
+ {
+ pSetupData->mnPaperBin = j;
+ bTrayFound = TRUE;
+ break;
+ }
+ }
+ if ( !bTrayFound )
+ {
+ for ( j = 0; j < pSalInfoPrinter->maPrinterData.mnTrayCount; j++ )
+ {
+ if ( pSalInfoPrinter->maPrinterData.mpTrayArray[j]->mnId == pElm->djpttTrayID )
+ {
+ pSetupData->mnPaperBin = j;
+ bTrayFound = TRUE;
+ break;
+ }
+ }
+ }
+ // Wenn wir Ihn immer noch nicht gefunden haben, setzen
+ // wir ihn auf DontKnow
+ if ( !bTrayFound )
+ pSetupData->mnPaperBin = 0xFFFF;
+ }
+ }
+
+ pDJP = DJP_NEXT_STRUCTP( pDJP );
+ pTuple++;
+ }
+
+ bResult = TRUE;
+ }
+ else
+ {
+ ImplFreePrnMemory( pCopyDrivData );
+ bResult = FALSE;
+ }
+
+ delete [] pBuffer;
+
+ return bResult;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplSetOrientation( HDC hPrinterDC, PDRIVDATA pDriverData,
+ Orientation eOrientation )
+{
+ LONG alQuery[] =
+ {
+ 0, 0, // First two members of QUERYSIZE
+ DJP_SJ_ORIENTATION, DJP_CURRENT,
+ DJP_NONE, DJP_NONE // EOL marker
+ };
+
+ APIRET rc;
+ PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery;
+ PBYTE pBuffer = NULL;
+ LONG nAlloc = 0;
+ LONG nDrivDataSize = pDriverData->cb;
+
+ // find out how many bytes to allocate
+ pQuerySize->cb = sizeof( alQuery );
+ rc = DevEscape( hPrinterDC,
+ DEVESC_QUERYSIZE,
+ sizeof( alQuery ),
+ (PBYTE)pQuerySize,
+ &nDrivDataSize,
+ (PBYTE)pDriverData );
+ if ( DEV_OK != rc )
+ return FALSE;
+
+ // allocate the memory
+ nAlloc = pQuerySize->ulSizeNeeded;
+ pBuffer = (PBYTE)new BYTE[nAlloc];
+
+ // set up the input
+ PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
+ ImplFormatInputList( pDJP, pQuerySize->aTuples );
+
+ pDJP->cb = sizeof( DJP_ITEM );
+ pDJP->ulProperty = DJP_SJ_ORIENTATION;
+ pDJP->lType = DJP_CURRENT;
+ pDJP->ulValue = (eOrientation == ORIENTATION_PORTRAIT)
+ ? DJP_ORI_PORTRAIT
+ : DJP_ORI_LANDSCAPE;
+
+ // do it!
+ rc = DevEscape( hPrinterDC,
+ DEVESC_SETJOBPROPERTIES,
+ nAlloc,
+ pBuffer,
+ &nDrivDataSize,
+ (PBYTE)pDriverData );
+
+ delete [] pBuffer;
+
+ return ((DEV_OK == rc) || (DEV_WARNING == rc));
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplSetPaperSize( HDC hPrinterDC, PDRIVDATA pDriverData,
+ DJPT_PAPERSIZE nOS2PaperFormat )
+{
+ LONG alQuery[] =
+ {
+ 0, 0, // First two members of QUERYSIZE
+ DJP_SJ_PAPERSIZE, DJP_CURRENT,
+ DJP_NONE, DJP_NONE // EOL marker
+ };
+
+ APIRET rc;
+ PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery;
+ PBYTE pBuffer = NULL;
+ LONG nAlloc = 0;
+ LONG nDrivDataSize = pDriverData->cb;
+
+ // find out how many bytes to allocate
+ pQuerySize->cb = sizeof( alQuery );
+ rc = DevEscape( hPrinterDC,
+ DEVESC_QUERYSIZE,
+ sizeof( alQuery ),
+ (PBYTE)pQuerySize,
+ &nDrivDataSize,
+ (PBYTE)pDriverData );
+ if ( DEV_OK != rc )
+ return FALSE;
+
+ // allocate the memory
+ nAlloc = pQuerySize->ulSizeNeeded;
+ pBuffer = (PBYTE)new BYTE[nAlloc];
+
+ // set up the input
+ PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
+ PDJP_ITEM pStartDJP = pDJP;
+ ImplFormatInputList( pDJP, pQuerySize->aTuples );
+
+ // Neue Daten zuweisen
+ pDJP->cb = sizeof( DJP_ITEM );
+ pDJP->ulProperty = DJP_SJ_PAPERSIZE;
+ pDJP->lType = DJP_CURRENT;
+ pDJP->ulValue = nOS2PaperFormat;
+
+ // und setzen
+ rc = DevEscape( hPrinterDC,
+ DEVESC_SETJOBPROPERTIES,
+ nAlloc,
+ pBuffer,
+ &nDrivDataSize,
+ (PBYTE)pDriverData );
+
+ delete [] pBuffer;
+
+ return ((DEV_OK == rc) || (DEV_WARNING == rc));
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplSetPaperBin( HDC hPrinterDC, PDRIVDATA pDriverData,
+ ImplTrayInfo* pTrayInfo )
+{
+ LONG alQuery[] =
+ {
+ 0, 0, // First two members of QUERYSIZE
+ DJP_SJ_TRAYTYPE, DJP_CURRENT,
+ DJP_NONE, DJP_NONE // EOL marker
+ };
+
+ APIRET rc;
+ PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery;
+ PBYTE pBuffer = NULL;
+ LONG nAlloc = 0;
+ LONG nDrivDataSize = pDriverData->cb;
+
+ // find out how many bytes to allocate
+ pQuerySize->cb = sizeof( alQuery );
+ rc = DevEscape( hPrinterDC,
+ DEVESC_QUERYSIZE,
+ sizeof( alQuery ),
+ (PBYTE)pQuerySize,
+ &nDrivDataSize,
+ (PBYTE)pDriverData );
+ if ( DEV_OK != rc )
+ return FALSE;
+
+ // allocate the memory
+ nAlloc = pQuerySize->ulSizeNeeded;
+ pBuffer = (PBYTE)new BYTE[nAlloc];
+
+ // set up the input
+ PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
+ ImplFormatInputList( pDJP, pQuerySize->aTuples );
+
+ // Neue Daten zuweisen
+ pDJP->cb = sizeof( DJP_ITEM );
+ pDJP->ulProperty = DJP_SJ_TRAYTYPE;
+ pDJP->lType = DJP_CURRENT;
+ pDJP->ulValue = pTrayInfo->mnId;
+
+ // und setzen
+ rc = DevEscape( hPrinterDC,
+ DEVESC_SETJOBPROPERTIES,
+ nAlloc,
+ pBuffer,
+ &nDrivDataSize,
+ (PBYTE)pDriverData );
+
+ delete [] pBuffer;
+
+ return ((DEV_OK == rc) || (DEV_WARNING == rc));
+}
+
+// =======================================================================
+
+static BOOL ImplSalCreateInfoPrn( SalInfoPrinter* pPrinter, PDRIVDATA pDriverData,
+ HDC& rDC, HPS& rPS )
+{
+ SalData* pSalData = GetSalData();
+
+ // create info context
+ DEVOPENSTRUC devOpenStruc;
+ memset( &devOpenStruc, 0, sizeof( devOpenStruc ) );
+ devOpenStruc.pszLogAddress = (char*)(const char*)pPrinter->maPrinterData.maName;
+ devOpenStruc.pszDriverName = (char*)(const char*)pPrinter->maPrinterData.maDriverName;
+ devOpenStruc.pdriv = pDriverData;
+ devOpenStruc.pszDataType = "PM_Q_STD";
+
+ HDC hDC = DevOpenDC( pSalData->mhAB, OD_INFO, "*",
+ 4, (PDEVOPENDATA)&devOpenStruc, (HDC)NULL);
+ if ( !hDC )
+ return FALSE;
+
+ // create presentation space
+ SIZEL sizel;
+ sizel.cx = 0;
+ sizel.cy = 0;
+ HPS hPS = GpiCreatePS( pSalData->mhAB, hDC, &sizel, GPIA_ASSOC | GPIT_MICRO | PU_PELS );
+ if ( !hPS )
+ {
+ DevCloseDC( hDC );
+ return FALSE;
+ }
+
+ rDC = hDC;
+ rPS = hPS;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalDestroyInfoPrn( SalInfoPrinter* pPrinter )
+{
+ ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) );
+ GpiAssociate( pPrinter->maPrinterData.mhPS, 0 );
+ GpiDestroyPS( pPrinter->maPrinterData.mhPS );
+ DevCloseDC( pPrinter->maPrinterData.mhDC );
+}
+
+// =======================================================================
+
+SalInfoPrinter* SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
+ ImplJobSetup* pSetupData )
+{
+ ImplQueueSalSysData* pSysQueueData = (ImplQueueSalSysData*)(pQueueInfo->mpSysData);
+ SalInfoPrinter* pPrinter = new SalInfoPrinter;
+ pPrinter->maPrinterData.maPrinterName = pSysQueueData->maPrinterName;
+ pPrinter->maPrinterData.maName = pSysQueueData->maName;
+ pPrinter->maPrinterData.maDriverName = pSysQueueData->maDriverName;
+ pPrinter->maPrinterData.maDeviceName = pSysQueueData->maDeviceName;
+
+ // Nur Setup-Daten uebernehmen, wenn Treiber und Laenge der Treiberdaten
+ // uebereinstimmt
+ PDRIVDATA pDriverData;
+ BOOL bUpdateDriverData;
+ if ( pSetupData->mpDriverData && pSysQueueData->mpDrivData &&
+ (pSetupData->mnSystem == JOBSETUP_SYSTEM_OS2) &&
+ (pSetupData->mnDriverDataLen == pSysQueueData->mpDrivData->cb) &&
+ (strcmp( ((PDRIVDATA)pSetupData->mpDriverData)->szDeviceName,
+ pSysQueueData->mpDrivData->szDeviceName ) == 0) )
+ {
+ pDriverData = PDRIVDATA( pSetupData->mpDriverData );
+ bUpdateDriverData = FALSE;
+ }
+ else
+ {
+ pDriverData = pSysQueueData->mpDrivData;
+ bUpdateDriverData = TRUE;
+ }
+ if ( pDriverData )
+ pPrinter->maPrinterData.maJobSetupDeviceName = pDriverData->szDeviceName;
+
+ if ( !ImplSalCreateInfoPrn( pPrinter, pDriverData,
+ pPrinter->maPrinterData.mhDC,
+ pPrinter->maPrinterData.mhPS ) )
+ {
+ delete pPrinter;
+ return NULL;
+ }
+
+ // create graphics object for output
+ SalGraphics* pGraphics = new SalGraphics;
+ pGraphics->maGraphicsData.mhDC = pPrinter->maPrinterData.mhDC;
+ pGraphics->maGraphicsData.mhPS = pPrinter->maPrinterData.mhPS;
+ pGraphics->maGraphicsData.mhWnd = 0;
+ pGraphics->maGraphicsData.mbPrinter = TRUE;
+ pGraphics->maGraphicsData.mbVirDev = FALSE;
+ pGraphics->maGraphicsData.mbWindow = FALSE;
+ pGraphics->maGraphicsData.mbScreen = FALSE;
+
+ ImplSalInitGraphics( &(pGraphics->maGraphicsData) );
+ pPrinter->maPrinterData.mpGraphics = pGraphics;
+
+ // check printer driver for DJP support
+ pPrinter->maPrinterData.mbDJPSupported = ImplIsDriverDJPEnabled( pPrinter->maPrinterData.mhDC );
+
+ if ( bUpdateDriverData )
+ {
+ if ( pSetupData->mpDriverData )
+ delete pSetupData->mpDriverData;
+ pSetupData->mpDriverData = new BYTE[pDriverData->cb];
+ memcpy( pSetupData->mpDriverData, pDriverData, pDriverData->cb );
+ pSetupData->mnDriverDataLen = pDriverData->cb;
+ }
+
+ // retrieve current settings from printer driver and store them to system independend data!
+ if ( pPrinter->maPrinterData.mbDJPSupported )
+ ImplGetCurrentSettings( pPrinter, pSetupData );
+ pSetupData->mnSystem = JOBSETUP_SYSTEM_OS2;
+
+ return pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
+{
+ delete pPrinter;
+}
+
+// =======================================================================
+
+SalInfoPrinter::SalInfoPrinter()
+{
+ maPrinterData.mhDC = 0;
+ maPrinterData.mhPS = 0;
+ maPrinterData.mpGraphics = NULL;
+ maPrinterData.mbGraphics = FALSE;
+ maPrinterData.mbDJPSupported = FALSE;
+ maPrinterData.mnFormCount = 0;
+ maPrinterData.mpFormArray = NULL;
+ maPrinterData.mnTrayCount = 0;
+ maPrinterData.mpTrayArray = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+SalInfoPrinter::~SalInfoPrinter()
+{
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDestroyInfoPrn( this );
+ delete maPrinterData.mpGraphics;
+ }
+
+ ImplFreeFormAndTrayList( this );
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalInfoPrinter::GetGraphics()
+{
+ if ( maPrinterData.mbGraphics )
+ return NULL;
+
+ if ( maPrinterData.mpGraphics )
+ maPrinterData.mbGraphics = TRUE;
+
+ return maPrinterData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInfoPrinter::ReleaseGraphics( SalGraphics* )
+{
+ maPrinterData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData )
+{
+ PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData );
+ if ( !pDrivData )
+ return FALSE;
+
+ APIRET rc = DevPostDeviceModes( GetSalData()->mhAB, pDrivData,
+ maPrinterData.maDriverName.GetStr(),
+ maPrinterData.maDeviceName.GetStr(),
+ maPrinterData.maPrinterName.GetStr(),
+ DPDM_POSTJOBPROP );
+ if ( rc == DEV_OK )
+ {
+ ImplUpdateSetupData( pDrivData, pSetupData );
+
+ // update DC and PS
+ HDC hDC;
+ HPS hPS;
+ if ( !ImplSalCreateInfoPrn( this, (PDRIVDATA)(pSetupData->mpDriverData), hDC, hPS ) )
+ return FALSE;
+
+ // Alten Printer DC/PS zerstoeren
+ ImplSalDestroyInfoPrn( this );
+
+ // Neue Daten setzen und initialisieren
+ maPrinterData.mhDC = hDC;
+ maPrinterData.mhPS = hPS;
+ maPrinterData.mpGraphics->maGraphicsData.mhDC = maPrinterData.mhDC;
+ maPrinterData.mpGraphics->maGraphicsData.mhPS = maPrinterData.mhPS;
+ ImplSalInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+
+ // retrieve current settings from printer driver and store them to system independend data!
+ ImplFreeFormAndTrayList( this );
+ if ( maPrinterData.mbDJPSupported )
+ ImplGetCurrentSettings( this, pSetupData );
+
+ return TRUE;
+ }
+ else
+ {
+ ImplFreePrnMemory( pDrivData );
+ return FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::SetPrinterData( ImplJobSetup* pSetupData )
+{
+ // Wir koennen nur Treiberdaten von OS2 setzen
+ if ( pSetupData->mnSystem != JOBSETUP_SYSTEM_OS2 )
+ return FALSE;
+
+ PDRIVDATA pNewDrivData = (PDRIVDATA)(pSetupData->mpDriverData);
+ if ( !pNewDrivData )
+ return FALSE;
+
+ // Testen, ob Printerdaten fuer den gleichen Printer uebergeben werden,
+ // da einige Treiber zu Abstuerzen neigen, wenn Daten von einem anderen
+ // Printer gesetzt werden
+ if ( strcmp( maPrinterData.maJobSetupDeviceName, pNewDrivData->szDeviceName ) != 0 )
+ return FALSE;
+
+ // update DC and PS
+ HDC hDC;
+ HPS hPS;
+ if ( !ImplSalCreateInfoPrn( this, pNewDrivData, hDC, hPS ) )
+ return FALSE;
+
+ // Alten Printer DC/PS zerstoeren
+ ImplSalDestroyInfoPrn( this );
+
+ // Neue Daten setzen und initialisieren
+ maPrinterData.mhDC = hDC;
+ maPrinterData.mhPS = hPS;
+ maPrinterData.mpGraphics->maGraphicsData.mhDC = maPrinterData.mhDC;
+ maPrinterData.mpGraphics->maGraphicsData.mhPS = maPrinterData.mhPS;
+ ImplSalInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+
+ // retrieve current settings from printer driver and store them to system independend data!
+ ImplFreeFormAndTrayList( this );
+ if ( maPrinterData.mbDJPSupported )
+ ImplGetCurrentSettings( this, pSetupData );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::SetData( ULONG nFlags, ImplJobSetup* pSetupData )
+{
+ // needs DJP support
+ if ( !maPrinterData.mbDJPSupported )
+ return FALSE;
+
+ PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData );
+
+ if ( !pDrivData )
+ return FALSE;
+
+ BOOL bOK = FALSE;
+
+ // set orientation
+ if ( nFlags & SAL_JOBSET_ORIENTATION )
+ {
+ if ( ImplSetOrientation( maPrinterData.mhDC, pDrivData, pSetupData->meOrientation ) )
+ bOK = TRUE;
+ }
+
+ // set paper size
+ if ( nFlags & SAL_JOBSET_PAPERSIZE )
+ {
+ // Papierformat ermitteln
+ DJPT_PAPERSIZE nOS2PaperFormat;
+ switch ( pSetupData->mePaperFormat )
+ {
+ case PAPER_A3:
+ nOS2PaperFormat = DJP_PSI_A3;
+ break;
+
+ case PAPER_A4:
+ nOS2PaperFormat = DJP_PSI_A4;
+ break;
+
+ case PAPER_A5:
+ nOS2PaperFormat = DJP_PSI_A5;
+ break;
+
+ case PAPER_B4:
+ nOS2PaperFormat = DJP_PSI_B4;
+ break;
+
+ case PAPER_B5:
+ nOS2PaperFormat = DJP_PSI_B5;
+ break;
+
+ case PAPER_LETTER:
+ nOS2PaperFormat = DJP_PSI_LETTER;
+ break;
+
+ case PAPER_LEGAL:
+ nOS2PaperFormat = DJP_PSI_LEGAL;
+ break;
+
+ case PAPER_TABLOID:
+ nOS2PaperFormat = DJP_PSI_TABLOID;
+ break;
+
+ default:
+ {
+ nOS2PaperFormat = DJP_PSI_NONE;
+ // OS2 rechnet in Millimetern
+ long nPaperWidth = pSetupData->mnPaperWidth / 100;
+ long nPaperHeight = pSetupData->mnPaperHeight / 100;
+ // Ansonsten ueber die Papiergroesse suchen
+ for( int i = 0; i < maPrinterData.mnFormCount; i++ )
+ {
+ ImplFormInfo* pFormInfo = maPrinterData.mpFormArray[i];
+ if ( ImplPaperSizeEqual( nPaperWidth, nPaperHeight,
+ pFormInfo->mnPaperWidth, pFormInfo->mnPaperHeight ) )
+ {
+ nOS2PaperFormat = pFormInfo->mnId;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ if ( nOS2PaperFormat != DJP_PSI_NONE )
+ {
+ if ( ImplSetPaperSize( maPrinterData.mhDC, pDrivData, nOS2PaperFormat ) )
+ bOK = TRUE;
+ }
+ }
+
+ // set paper tray
+ if ( (nFlags & SAL_JOBSET_PAPERBIN) && (pSetupData->mnPaperBin < maPrinterData.mnTrayCount) )
+ {
+ if ( ImplSetPaperBin( maPrinterData.mhDC, pDrivData,
+ maPrinterData.mpTrayArray[pSetupData->mnPaperBin] ) )
+ bOK = TRUE;
+ }
+
+ if ( bOK )
+ {
+ ImplUpdateSetupData( pDrivData, pSetupData );
+
+ // query current driver settings
+ ImplFreeFormAndTrayList( this );
+ if ( ImplGetCurrentSettings( this, pSetupData ) )
+ {
+ // update DC and PS
+ HDC hDC;
+ HPS hPS;
+ if ( ImplSalCreateInfoPrn( this, (PDRIVDATA)(pSetupData->mpDriverData), hDC, hPS ) )
+ {
+ // Alten Printer DC/PS zerstoeren
+ ImplSalDestroyInfoPrn( this );
+
+ // Neue Daten setzen und initialisieren
+ maPrinterData.mhDC = hDC;
+ maPrinterData.mhPS = hPS;
+ maPrinterData.mpGraphics->maGraphicsData.mhDC = maPrinterData.mhDC;
+ maPrinterData.mpGraphics->maGraphicsData.mhPS = maPrinterData.mhPS;
+ ImplSalInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ }
+ else
+ bOK = FALSE;
+ }
+ else
+ bOK = FALSE;
+ }
+
+ return bOK;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pJobSetup )
+{
+ if ( !maPrinterData.mbDJPSupported )
+ return 1;
+
+ // init paperbinlist if empty
+ if ( !maPrinterData.mnTrayCount )
+ ImplGetFormAndTrayList( this, pJobSetup );
+
+ // Wir haben immer einen PaperTray und wenn, das eben einen ohne
+ // Namen
+ if ( !maPrinterData.mnTrayCount )
+ return 1;
+ else
+ return maPrinterData.mnTrayCount;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup,
+ ULONG nPaperBin )
+{
+ XubString aPaperBinName;
+
+ if ( maPrinterData.mbDJPSupported )
+ {
+ // init paperbinlist if empty
+ if ( !maPrinterData.mnTrayCount )
+ ImplGetFormAndTrayList( this, pJobSetup );
+
+ if ( nPaperBin < maPrinterData.mnTrayCount )
+ aPaperBinName = maPrinterData.mpTrayArray[nPaperBin]->maDisplayName;
+ }
+
+ return aPaperBinName;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInfoPrinter::GetCapabilities( const ImplJobSetup*, USHORT nType )
+{
+ switch ( nType )
+ {
+ case PRINTER_CAPABILITIES_SUPPORTDIALOG:
+ return TRUE;
+ case PRINTER_CAPABILITIES_COPIES:
+ return 0xFFFF;
+ case PRINTER_CAPABILITIES_COLLATECOPIES:
+ return 0;
+ case PRINTER_CAPABILITIES_SETORIENTATION:
+ case PRINTER_CAPABILITIES_SETPAPERBIN:
+ case PRINTER_CAPABILITIES_SETPAPERSIZE:
+ case PRINTER_CAPABILITIES_SETPAPER:
+ return maPrinterData.mbDJPSupported;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInfoPrinter::GetPageInfo( const ImplJobSetup*,
+ long& rOutWidth, long& rOutHeight,
+ long& rPageOffX, long& rPageOffY,
+ long& rPageWidth, long& rPageHeight )
+{
+ HDC hDC = maPrinterData.mhDC;
+
+ // search current form
+ HCINFO aInfo;
+ int nForms = DevQueryHardcopyCaps( hDC, 0, 0, &aInfo );
+ for( int i = 0; i < nForms; i++ )
+ {
+ if ( DevQueryHardcopyCaps( hDC, i, 1, &aInfo ) >= 0 )
+ {
+ if ( aInfo.flAttributes & HCAPS_CURRENT )
+ {
+ // query resolution
+ long nXResolution;
+ long nYResolution;
+ DevQueryCaps( hDC, CAPS_HORIZONTAL_RESOLUTION, 1, &nXResolution );
+ DevQueryCaps( hDC, CAPS_VERTICAL_RESOLUTION, 1, &nYResolution );
+ rPageOffX = aInfo.xLeftClip * nXResolution / 1000;
+ rPageOffY = (aInfo.cy-aInfo.yTopClip) * nYResolution / 1000;
+ rPageWidth = aInfo.cx * nXResolution / 1000;
+ rPageHeight = aInfo.cy * nYResolution / 1000;
+ rOutWidth = aInfo.xPels;
+ rOutHeight = aInfo.yPels;
+ return;
+ }
+ }
+ }
+
+ // use device caps if no form selected/found
+ long lCapsWidth = 0;
+ long lCapsHeight = 0;
+ DevQueryCaps( hDC, CAPS_WIDTH, 1L, &lCapsWidth );
+ DevQueryCaps( hDC, CAPS_HEIGHT, 1L, &lCapsHeight );
+ rPageOffX = 0;
+ rPageOffY = 0;
+ rOutWidth = lCapsWidth;
+ rOutHeight = lCapsHeight;
+ rPageWidth = rOutWidth;
+ rPageHeight = rOutHeight;
+}
+
+// =======================================================================
+
+static BOOL ImplIsDriverPrintDJPEnabled( HDC hDC )
+{
+#ifdef NO_DJP
+ return FALSE;
+#else
+ // Ueber OS2-Ini kann DJP disablte werden
+ if ( !PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_PRINTDJP, 1 ) )
+ return FALSE;
+
+ // Testen, ob DJP-Interface am Drucker vorhanden
+ LONG lQuery;
+ APIRET rc;
+
+ lQuery = DEVESC_QUERYSIZE;
+ rc = DevEscape( hDC,
+ DEVESC_QUERYESCSUPPORT,
+ sizeof( lQuery ),
+ (PBYTE)&lQuery,
+ 0,
+ (PBYTE)NULL );
+ if ( DEV_OK != rc )
+ return FALSE;
+
+ return TRUE;
+#endif
+}
+
+// =======================================================================
+
+SalPrinter* SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
+{
+ SalPrinter* pPrinter = new SalPrinter;
+ pPrinter->maPrinterData.mpInfoPrinter = pInfoPrinter;
+ return pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyPrinter( SalPrinter* pPrinter )
+{
+ delete pPrinter;
+}
+
+// =======================================================================
+
+SalPrinter::SalPrinter()
+{
+ maPrinterData.mhDC = 0;
+ maPrinterData.mhPS = 0;
+ maPrinterData.mpGraphics = NULL;
+ maPrinterData.mbAbort = FALSE;
+ maPrinterData.mbPrintDJPSupported = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SalPrinter::~SalPrinter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::StartJob( const XubString* pFileName,
+ const XubString& rJobName,
+ const XubString& rAppName,
+ ULONG nCopies, BOOL bCollate,
+ ImplJobSetup* pSetupData )
+{
+ DEVOPENSTRUC aDevOpenStruc;
+ LONG lType;
+ APIRET rc;
+
+ // prepare queue information
+ memset( &aDevOpenStruc, 0, sizeof( aDevOpenStruc ) );
+ aDevOpenStruc.pszDriverName = (PSZ)(maPrinterData.mpInfoPrinter->maPrinterData.maDriverName.GetStr());
+
+ // print into file?
+ if ( pFileName )
+ {
+ aDevOpenStruc.pszLogAddress = (PSZ)pFileName->GetStr();
+ aDevOpenStruc.pszDataType = "PM_Q_RAW";
+ lType = OD_DIRECT;
+ }
+ else
+ {
+ aDevOpenStruc.pszLogAddress = (PSZ)(maPrinterData.mpInfoPrinter->maPrinterData.maName.GetStr());
+ if ( PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_PRINTRAW, 0 ) )
+ aDevOpenStruc.pszDataType = "PM_Q_RAW";
+ else
+ aDevOpenStruc.pszDataType = "PM_Q_STD";
+ lType = OD_QUEUED;
+ }
+
+ // Set comment (AppName nur bis zum 1. Space-Zeichen nehmen)
+ const xub_Unicode* pComment = rAppName;
+ USHORT nCommentLen = 0;
+ memset( maPrinterData.maCommentBuf, 0, sizeof( maPrinterData.maCommentBuf ) );
+ while ( (nCommentLen < 32) &&
+ (((*pComment >= 'a') && (*pComment <= 'z')) ||
+ ((*pComment >= 'A') && (*pComment <= 'Z')) ||
+ ((*pComment >= '0') && (*pComment <= '9')) ||
+ (*pComment == '-')))
+ {
+ maPrinterData.maCommentBuf[nCommentLen] = (char)(*pComment);
+ nCommentLen++;
+ pComment++;
+ }
+ aDevOpenStruc.pszComment = (PSZ)maPrinterData.maCommentBuf;
+
+ // Kopien
+ if ( nCopies > 1 )
+ {
+ // OS2 kann maximal 999 Kopien
+ if ( nCopies > 999 )
+ nCopies = 999;
+ String aCopyStr( nCopies );
+ strcpy( maPrinterData.maCopyBuf, "COP=" );
+ strcat( maPrinterData.maCopyBuf+4, aCopyStr.GetStr() );
+ aDevOpenStruc.pszQueueProcParams = (PSZ)maPrinterData.maCopyBuf;
+ }
+
+ // open device context
+ SalData* pSalData = GetSalData();
+ HAB hAB = pSalData->mhAB;
+ aDevOpenStruc.pdriv = (PDRIVDATA)pSetupData->mpDriverData;
+ maPrinterData.mhDC = DevOpenDC( hAB,
+ lType,
+ "*",
+ 7,
+ (PDEVOPENDATA)&aDevOpenStruc,
+ 0 );
+ if ( maPrinterData.mhDC == 0 )
+ {
+ ERRORID nLastError = WinGetLastError( hAB );
+ if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT )
+ maPrinterData.mnError = SAL_PRINTER_ERROR_ABORT;
+ else
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ // open presentation space
+ SIZEL sizel;
+ sizel.cx = 0;
+ sizel.cy = 0;
+ maPrinterData.mhPS = GpiCreatePS( hAB, maPrinterData.mhDC, &sizel, GPIA_ASSOC | GPIT_MICRO | PU_PELS );
+ if ( !maPrinterData.mhPS )
+ {
+ DevCloseDC( maPrinterData.mhDC );
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return NULL;
+ }
+
+ // Can we print with DJP
+ maPrinterData.mbPrintDJPSupported = ImplIsDriverPrintDJPEnabled( maPrinterData.mhDC );
+
+ // JobName ermitteln und Job starten
+ PSZ pszJobName = NULL;
+ int nJobNameLen = 0;
+ if ( rJobName.Len() > 0 )
+ {
+ pszJobName = (PSZ)rJobName.GetStr();
+ nJobNameLen = rJobName.Len();
+ }
+ rc = DevEscape( maPrinterData.mhDC,
+ DEVESC_STARTDOC,
+ nJobNameLen, pszJobName,
+ 0, NULL );
+
+ if ( rc != DEV_OK )
+ {
+ ERRORID nLastError = WinGetLastError( hAB );
+ if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT )
+ maPrinterData.mnError = SAL_PRINTER_ERROR_ABORT;
+ else
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ GpiAssociate( maPrinterData.mhPS, NULL );
+ GpiDestroyPS( maPrinterData.mhPS );
+ DevCloseDC( maPrinterData.mhDC );
+ return FALSE;
+ }
+
+ // init for first page
+ maPrinterData.mbFirstPage = TRUE;
+ maPrinterData.mnError = 0;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::EndJob()
+{
+ APIRET rc;
+ rc = DevEscape( maPrinterData.mhDC,
+ DEVESC_ENDDOC,
+ 0, NULL,
+ 0, NULL);
+
+ // destroy presentation space and device context
+ GpiAssociate( maPrinterData.mhPS, NULL );
+ GpiDestroyPS( maPrinterData.mhPS );
+ DevCloseDC( maPrinterData.mhDC );
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::AbortJob()
+{
+ APIRET rc;
+
+ rc = DevEscape( maPrinterData.mhDC,
+ DEVESC_ABORTDOC,
+ 0, NULL,
+ 0, NULL );
+
+ // destroy SalGraphics
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ maPrinterData.mpGraphics = NULL;
+ }
+
+ // destroy presentation space and device context
+ GpiAssociate( maPrinterData.mhPS, NULL );
+ GpiDestroyPS( maPrinterData.mhPS );
+ DevCloseDC( maPrinterData.mhDC );
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalPrinter::StartPage( ImplJobSetup* pSetupData, BOOL bNewJobSetup )
+{
+ APIRET rc;
+
+ if ( maPrinterData.mbFirstPage )
+ maPrinterData.mbFirstPage = FALSE;
+ else
+ {
+ PBYTE pJobData;
+ LONG nJobDataSize;
+ LONG nEscape;
+ if ( maPrinterData.mbPrintDJPSupported && bNewJobSetup )
+ {
+ nEscape = DEVESC_NEWFRAME_WPROP;
+ nJobDataSize = ((PDRIVDATA)(pSetupData->mpDriverData))->cb;
+ pJobData = (PBYTE)(pSetupData->mpDriverData);
+ }
+ else
+ {
+ nEscape = DEVESC_NEWFRAME;
+ nJobDataSize = 0;
+ pJobData = NULL;
+ }
+ rc = DevEscape( maPrinterData.mhDC,
+ nEscape,
+ 0, NULL,
+ &nJobDataSize, pJobData );
+
+ if ( rc != DEV_OK )
+ {
+ DevEscape( maPrinterData.mhDC, DEVESC_ENDDOC, 0, NULL, 0, NULL);
+ GpiAssociate( maPrinterData.mhPS, NULL );
+ GpiDestroyPS( maPrinterData.mhPS );
+ DevCloseDC( maPrinterData.mhDC );
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return NULL;
+ }
+ }
+
+ // create SalGraphics with copy of hPS
+ SalGraphics* pGraphics = new SalGraphics;
+ pGraphics->maGraphicsData.mhDC = maPrinterData.mhDC;
+ pGraphics->maGraphicsData.mhPS = maPrinterData.mhPS;
+ pGraphics->maGraphicsData.mhWnd = 0;
+ pGraphics->maGraphicsData.mbPrinter = TRUE;
+ pGraphics->maGraphicsData.mbVirDev = FALSE;
+ pGraphics->maGraphicsData.mbWindow = FALSE;
+ pGraphics->maGraphicsData.mbScreen = FALSE;
+ pGraphics->maGraphicsData.mnHeight = 0;
+ // search current form for actual page height
+ HCINFO aInfo;
+ int nForms = DevQueryHardcopyCaps( maPrinterData.mhDC, 0, 0, &aInfo );
+ for( int i = 0; i < nForms; i++ )
+ {
+ if ( DevQueryHardcopyCaps( maPrinterData.mhDC, i, 1, &aInfo ) >= 0 )
+ {
+ if ( aInfo.flAttributes & HCAPS_CURRENT )
+ pGraphics->maGraphicsData.mnHeight = aInfo.yPels;
+ }
+ }
+ // use device caps if no form selected/found
+ if ( !pGraphics->maGraphicsData.mnHeight )
+ DevQueryCaps( maPrinterData.mhDC, CAPS_HEIGHT, 1L, &pGraphics->maGraphicsData.mnHeight );
+
+ ImplSalInitGraphics( &(pGraphics->maGraphicsData) );
+ maPrinterData.mpGraphics = pGraphics;
+
+ return pGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::EndPage()
+{
+ if ( maPrinterData.mpGraphics )
+ {
+ // destroy SalGraphics
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ maPrinterData.mpGraphics = NULL;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalPrinter::GetErrorCode()
+{
+ return maPrinterData.mnError;
+}
diff --git a/vcl/os2/source/gdi/salvd.cxx b/vcl/os2/source/gdi/salvd.cxx
new file mode 100644
index 000000000000..9014913f7415
--- /dev/null
+++ b/vcl/os2/source/gdi/salvd.cxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * $RCSfile: salvd.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#include <tools/svpm.h>
+
+#define _SV_SALVD_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+
+// =======================================================================
+
+HBITMAP ImplCreateVirDevBitmap( HDC hDC, HPS hPS, long nDX, long nDY,
+ USHORT nBitCount )
+{
+ if( !nBitCount )
+ {
+ LONG nDevBitCount;
+ DevQueryCaps( hDC, CAPS_COLOR_BITCOUNT, 1, &nDevBitCount );
+ nBitCount = nDevBitCount;
+ }
+
+ LONG nPlanes;
+ DevQueryCaps( hDC, CAPS_COLOR_PLANES, 1, &nPlanes );
+
+ // entsprechende Bitmap zum OutputDevice erzeugen
+ HBITMAP hBitmap;
+ BITMAPINFOHEADER2 aBitmapInfo;
+ memset( &aBitmapInfo, 0, sizeof( BITMAPINFOHEADER2 ) );
+ aBitmapInfo.cbFix = sizeof( BITMAPINFOHEADER2 );
+ aBitmapInfo.cx = nDX;
+ aBitmapInfo.cy = nDY;
+ aBitmapInfo.cPlanes = nPlanes;
+ aBitmapInfo.cBitCount = (nBitCount < 4) ? 4 : nBitCount;
+ hBitmap = GpiCreateBitmap( hPS, &aBitmapInfo, 0, NULL, NULL );
+ return hBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+SalVirtualDevice* SalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ USHORT nBitCount )
+{
+ HAB hAB = GetSalData()->mhAB;
+ SIZEL size;
+
+ // create device context (at this time allways display compatible)
+ DEVOPENSTRUC aDevOpenStruc = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+ HDC hDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5, (PDEVOPENDATA)&aDevOpenStruc, 0 );
+ if ( !hDC )
+ return NULL;
+
+ // create presentation space
+ size.cx = nDX;
+ size.cy = nDY;
+ HPS hPS = GpiCreatePS( hAB, hDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
+ if ( !hPS )
+ {
+ DevCloseDC( hDC );
+ return NULL;
+ }
+
+ // create bitmap for the virtual device
+ HBITMAP hBmp = ImplCreateVirDevBitmap( hDC, hPS, nDX, nDY, nBitCount );
+ if ( !hBmp )
+ {
+ GpiDestroyPS( hPS );
+ DevCloseDC( hDC );
+ return NULL;
+ }
+
+ // init data
+ SalVirtualDevice* pVDev = new SalVirtualDevice;
+ SalGraphics* pVirGraphics = new SalGraphics;
+
+ pVirGraphics->maGraphicsData.mhDC = hDC;
+ pVirGraphics->maGraphicsData.mhPS = hPS;
+ pVirGraphics->maGraphicsData.mhWnd = 0;
+ pVirGraphics->maGraphicsData.mnHeight = nDY;
+ pVirGraphics->maGraphicsData.mbPrinter = FALSE;
+ pVirGraphics->maGraphicsData.mbVirDev = TRUE;
+ pVirGraphics->maGraphicsData.mbWindow = FALSE;
+ pVirGraphics->maGraphicsData.mbScreen = pGraphics->maGraphicsData.mbScreen;
+ ImplSalInitGraphics( &(pVirGraphics->maGraphicsData) );
+
+ pVDev->maVirDevData.mhDC = hDC;
+ pVDev->maVirDevData.mhPS = hPS;
+ pVDev->maVirDevData.mhBmp = hBmp;
+ pVDev->maVirDevData.mhDefBmp = GpiSetBitmap( hPS, hBmp );
+ pVDev->maVirDevData.mpGraphics = pVirGraphics;
+ pVDev->maVirDevData.mnBitCount = nBitCount;
+ pVDev->maVirDevData.mbGraphics = FALSE;
+ return pVDev;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
+{
+ delete pDevice;
+}
+
+// =======================================================================
+
+SalVirtualDevice::SalVirtualDevice()
+{
+}
+
+// -----------------------------------------------------------------------
+
+SalVirtualDevice::~SalVirtualDevice()
+{
+ ImplSalDeInitGraphics( &(maVirDevData.mpGraphics->maGraphicsData) );
+
+ GpiSetBitmap( maVirDevData.mpGraphics->maGraphicsData.mhPS, maVirDevData.mhDefBmp );
+ GpiDeleteBitmap( maVirDevData.mhBmp );
+ GpiDestroyPS( maVirDevData.mpGraphics->maGraphicsData.mhPS );
+ DevCloseDC( maVirDevData.mpGraphics->maGraphicsData.mhDC );
+ delete maVirDevData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalVirtualDevice::GetGraphics()
+{
+ if ( maVirDevData.mbGraphics )
+ return NULL;
+
+ if ( maVirDevData.mpGraphics )
+ maVirDevData.mbGraphics = TRUE;
+
+ return maVirDevData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{
+ maVirDevData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalVirtualDevice::SetSize( long nDX, long nDY )
+{
+ HBITMAP hNewBmp = ImplCreateVirDevBitmap( maVirDevData.mhDC,
+ maVirDevData.mhPS, nDX, nDY,
+ maVirDevData.mnBitCount );
+ if ( hNewBmp )
+ {
+ GpiSetBitmap( maVirDevData.mhPS, hNewBmp );
+ GpiDeleteBitmap( maVirDevData.mhBmp );
+ maVirDevData.mhBmp = hNewBmp;
+ maVirDevData.mpGraphics->maGraphicsData.mnHeight = nDY;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
diff --git a/vcl/os2/source/src/makefile.mk b/vcl/os2/source/src/makefile.mk
new file mode 100644
index 000000000000..f9c8e73f40af
--- /dev/null
+++ b/vcl/os2/source/src/makefile.mk
@@ -0,0 +1,147 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=SV
+TARGET=salsrc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+RCDEPN= nullptr.ptr \
+ help.ptr \
+ cross.ptr \
+ move.ptr \
+ hsplit.ptr \
+ vsplit.ptr \
+ hsizebar.ptr \
+ vsizebar.ptr \
+ hand.ptr \
+ refhand.ptr \
+ pen.ptr \
+ magnify.ptr \
+ fill.ptr \
+ rotate.ptr \
+ hshear.ptr \
+ vshear.ptr \
+ mirror.ptr \
+ crook.ptr \
+ crop.ptr \
+ movept.ptr \
+ movebw.ptr \
+ movedata.ptr \
+ copydata.ptr \
+ linkdata.ptr \
+ movedlnk.ptr \
+ copydlnk.ptr \
+ movef.ptr \
+ copyf.ptr \
+ linkf.ptr \
+ moveflnk.ptr \
+ copyflnk.ptr \
+ movef2.ptr \
+ copyf2.ptr \
+ dline.ptr \
+ drect.ptr \
+ dpolygon.ptr \
+ dbezier.ptr \
+ darc.ptr \
+ dpie.ptr \
+ dcirccut.ptr \
+ dellipse.ptr \
+ dfree.ptr \
+ dconnect.ptr \
+ dtext.ptr \
+ dcapt.ptr \
+ chart.ptr \
+ detectiv.ptr \
+ pivotcol.ptr \
+ pivotrow.ptr \
+ pivotfld.ptr \
+ chain.ptr \
+ chainnot.ptr \
+ timemove.ptr \
+ timesize.ptr \
+ asn.ptr \
+ ass.ptr \
+ asw.ptr \
+ ase.ptr \
+ asnw.ptr \
+ asne.ptr \
+ assw.ptr \
+ asse.ptr \
+ asns.ptr \
+ aswe.ptr \
+ asnswe.ptr \
+ sd.ico
+
+RCFILES= salsrc.rc
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/os2/source/src/salsrc.rc b/vcl/os2/source/src/salsrc.rc
new file mode 100644
index 000000000000..26b936bd4e44
--- /dev/null
+++ b/vcl/os2/source/src/salsrc.rc
@@ -0,0 +1,134 @@
+/*************************************************************************
+*
+* $RCSfile: salsrc.rc,v $
+*
+* $Revision: 1.1.1.1 $
+*
+* last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $
+*
+* The Contents of this file are made available subject to the terms of
+* either of the following licenses
+*
+* - GNU Lesser General Public License Version 2.1
+* - Sun Industry Standards Source License Version 1.1
+*
+* Sun Microsystems Inc., October, 2000
+*
+* GNU Lesser General Public License Version 2.1
+* =============================================
+* Copyright 2000 by Sun Microsystems, Inc.
+* 901 San Antonio Road, Palo Alto, CA 94303, USA
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License version 2.1, as published by the Free Software Foundation.
+*
+* This library 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+* MA 02111-1307 USA
+*
+*
+* Sun Industry Standards Source License Version 1.1
+* =================================================
+* The contents of this file are subject to the Sun Industry Standards
+* Source License Version 1.1 (the "License"); You may not use this file
+* except in compliance with the License. You may obtain a copy of the
+* License at http://www.openoffice.org/license.html.
+*
+* Software provided under this License is provided on an "AS IS" basis,
+* WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+* WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+* See the License for the specific provisions governing your rights and
+* obligations concerning the Software.
+*
+* The Initial Developer of the Original Code is: Sun Microsystems, Inc..
+*
+* Copyright: 2000 by Sun Microsystems, Inc.
+*
+* All Rights Reserved.
+*
+* Contributor(s): _______________________________________
+*
+*
+*
+**************************************************************************/
+
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+
+POINTER SAL_RESID_POINTER_NULL NULLPTR.PTR
+POINTER SAL_RESID_POINTER_HELP HELP.PTR
+POINTER SAL_RESID_POINTER_CROSS CROSS.PTR
+POINTER SAL_RESID_POINTER_MOVE MOVE.PTR
+POINTER SAL_RESID_POINTER_HSPLIT HSPLIT.PTR
+POINTER SAL_RESID_POINTER_VSPLIT VSPLIT.PTR
+POINTER SAL_RESID_POINTER_HSIZEBAR HSIZEBAR.PTR
+POINTER SAL_RESID_POINTER_VSIZEBAR VSIZEBAR.PTR
+POINTER SAL_RESID_POINTER_HAND HAND.PTR
+POINTER SAL_RESID_POINTER_REFHAND REFHAND.PTR
+POINTER SAL_RESID_POINTER_PEN PEN.PTR
+POINTER SAL_RESID_POINTER_MAGNIFY MAGNIFY.PTR
+POINTER SAL_RESID_POINTER_FILL FILL.PTR
+POINTER SAL_RESID_POINTER_ROTATE ROTATE.PTR
+POINTER SAL_RESID_POINTER_HSHEAR HSHEAR.PTR
+POINTER SAL_RESID_POINTER_VSHEAR VSHEAR.PTR
+POINTER SAL_RESID_POINTER_MIRROR MIRROR.PTR
+POINTER SAL_RESID_POINTER_CROOK CROOK.PTR
+POINTER SAL_RESID_POINTER_CROP CROP.PTR
+POINTER SAL_RESID_POINTER_MOVEPOINT MOVEPT.PTR
+POINTER SAL_RESID_POINTER_MOVEBEZIERWEIGHT MOVEBW.PTR
+POINTER SAL_RESID_POINTER_MOVEDATA MOVEDATA.PTR
+POINTER SAL_RESID_POINTER_COPYDATA COPYDATA.PTR
+POINTER SAL_RESID_POINTER_LINKDATA LINKDATA.PTR
+POINTER SAL_RESID_POINTER_MOVEDATALINK MOVEDLNK.PTR
+POINTER SAL_RESID_POINTER_COPYDATALINK COPYDLNK.PTR
+POINTER SAL_RESID_POINTER_MOVEFILE MOVEF.PTR
+POINTER SAL_RESID_POINTER_COPYFILE COPYF.PTR
+POINTER SAL_RESID_POINTER_LINKFILE LINKF.PTR
+POINTER SAL_RESID_POINTER_MOVEFILELINK MOVEFLNK.PTR
+POINTER SAL_RESID_POINTER_COPYFILELINK COPYFLNK.PTR
+POINTER SAL_RESID_POINTER_MOVEFILES MOVEF2.PTR
+POINTER SAL_RESID_POINTER_COPYFILES COPYF2.PTR
+POINTER SAL_RESID_POINTER_DRAW_LINE DLINE.PTR
+POINTER SAL_RESID_POINTER_DRAW_RECT DRECT.PTR
+POINTER SAL_RESID_POINTER_DRAW_POLYGON DPOLYGON.PTR
+POINTER SAL_RESID_POINTER_DRAW_BEZIER DBEZIER.PTR
+POINTER SAL_RESID_POINTER_DRAW_ARC DARC.PTR
+POINTER SAL_RESID_POINTER_DRAW_PIE DPIE.PTR
+POINTER SAL_RESID_POINTER_DRAW_CIRCLECUT DCIRCCUT.PTR
+POINTER SAL_RESID_POINTER_DRAW_ELLIPSE DELLIPSE.PTR
+POINTER SAL_RESID_POINTER_DRAW_FREEHAND DFREE.PTR
+POINTER SAL_RESID_POINTER_DRAW_CONNECT DCONNECT.PTR
+POINTER SAL_RESID_POINTER_DRAW_TEXT DTEXT.PTR
+POINTER SAL_RESID_POINTER_DRAW_CAPTION DCAPT.PTR
+POINTER SAL_RESID_POINTER_CHART CHART.PTR
+POINTER SAL_RESID_POINTER_DETECTIVE DETECTIV.PTR
+POINTER SAL_RESID_POINTER_PIVOT_COL PIVOTCOL.PTR
+POINTER SAL_RESID_POINTER_PIVOT_ROW PIVOTROW.PTR
+POINTER SAL_RESID_POINTER_PIVOT_FIELD PIVOTFLD.PTR
+POINTER SAL_RESID_POINTER_CHAIN CHAIN.PTR
+POINTER SAL_RESID_POINTER_CHAIN_NOTALLOWED CHAINNOT.PTR
+POINTER SAL_RESID_POINTER_TIMEEVENT_MOVE TIMEMOVE.PTR
+POINTER SAL_RESID_POINTER_TIMEEVENT_SIZE TIMESIZE.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_N ASN.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_S ASS.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_W ASW.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_E ASE.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_NW ASNW.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_NE ASNE.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_SW ASSW.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_SE ASSE.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_NS ASNS.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_WE ASWE.PTR
+POINTER SAL_RESID_POINTER_AUTOSCROLL_NSWE ASNSWE.PTR
+
+ICON SAL_RESID_ICON_SD SD.ICO
+
diff --git a/vcl/os2/source/window/makefile b/vcl/os2/source/window/makefile
new file mode 100644
index 000000000000..4b811da766cd
--- /dev/null
+++ b/vcl/os2/source/window/makefile
@@ -0,0 +1,40 @@
+#*************************************************************************
+#*
+#* $Workfile: makefile $
+#*
+#* Ersterstellung TH 01.04.97
+#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:35 $
+#* $Revision: 1.1.1.1 $
+#*
+#* $Logfile: T:/vcl/os2/source/window/makefile.__v $
+#*
+#* Copyright (c) 1990 - 1998, STAR DIVISION
+#*
+#*************************************************************************
+
+PRJ=..\..\..
+
+PRJNAME=SV
+TARGET=salwin
+
+# --- Settings -----------------------------------------------------
+
+!INCLUDE <svpre.mak>
+!INCLUDE <settings.mak>
+!INCLUDE <sv.mak>
+
+!IF "$(COM)"=="ICC"
+ENVCFLAGS=$(ENVCFLAGS) -D_STD_NO_NAMESPACE -D_VOS_NO_NAMESPACE -D_UNO_NO_NAMESPACE
+!ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= salframe.cxx \
+ salobj.cxx
+
+SLOFILES= $(SLO)\salframe.obj \
+ $(SLO)\salobj.obj
+
+# --- Targets ------------------------------------------------------
+
+!INCLUDE <target.mak>
diff --git a/vcl/os2/source/window/makefile.mk b/vcl/os2/source/window/makefile.mk
new file mode 100644
index 000000000000..71f60055e8ef
--- /dev/null
+++ b/vcl/os2/source/window/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=SV
+TARGET=salwin
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= salframe.cxx \
+ salobj.cxx
+
+SLOFILES= $(SLO)$/salframe.obj \
+ $(SLO)$/salobj.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/os2/source/window/salframe.cxx b/vcl/os2/source/window/salframe.cxx
new file mode 100644
index 000000000000..f17d3c5ecd8c
--- /dev/null
+++ b/vcl/os2/source/window/salframe.cxx
@@ -0,0 +1,2762 @@
+/*************************************************************************
+ *
+ * $RCSfile: salframe.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __ZTC__
+#define _Seg16 _far16
+#define _Far16 _far16
+#define _System _syscall
+#define _Pascal _pascal
+#define _Cdecl _cdecl
+#endif
+
+#define BOOL PM_BOOL
+#define BYTE PM_BYTE
+#define USHORT PM_USHORT
+#define ULONG PM_ULONG
+
+#define INCL_DOS
+#define INCL_PM
+#include <os2.h>
+#include <os2im.h>
+
+#undef BOOL
+#undef BYTE
+#undef USHORT
+#undef ULONG
+
+#ifdef __cplusplus
+}
+#endif
+
+// =======================================================================
+
+#define _SV_SALFRAME_CXX
+
+#ifndef DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#define private public
+
+#ifndef _SV_SALLANG_HXX
+#include <sallang.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_KEYCOES_HXX
+#include <keycodes.hxx>
+#endif
+
+// =======================================================================
+
+// Toolkit4 defines
+#ifndef SV_FULLWINDOWDRAG
+#define SV_FULLWINDOWDRAG 99
+#endif
+
+// =======================================================================
+
+static eImplKeyboardLanguage = LANGUAGE_DONTKNOW;
+
+// =======================================================================
+
+#ifdef ENABLE_IME
+
+struct ImplSalIMEProc
+{
+ ULONG nOrd;
+ PFN* pProc;
+};
+
+#define SAL_IME_PROC_COUNT 12
+
+// -----------------------------------------------------------------------
+
+static SalIMEData* GetSalIMEData()
+{
+ SalData* pSalData = GetSalData();
+
+ if ( !pSalData->mbIMEInit )
+ {
+ pSalData->mbIMEInit = TRUE;
+
+ HMODULE hMod = 0;
+ if ( 0 == DosLoadModule( NULL, 0, "OS2IM", &hMod ) )
+ {
+ SalIMEData* pIMEData = new SalIMEData;
+ BOOL bError = FALSE;
+ ImplSalIMEProc aProcAry[SAL_IME_PROC_COUNT] =
+ {
+ { 101, (PFN*)&(pIMEData->mpAssocIME) },
+ { 104, (PFN*)&(pIMEData->mpGetIME) },
+ { 106, (PFN*)&(pIMEData->mpReleaseIME) },
+ { 117, (PFN*)&(pIMEData->mpSetConversionFont) },
+ { 144, (PFN*)&(pIMEData->mpSetConversionFontSize) },
+ { 118, (PFN*)&(pIMEData->mpGetConversionString) },
+ { 122, (PFN*)&(pIMEData->mpGetResultString) },
+ { 115, (PFN*)&(pIMEData->mpSetCandidateWin) },
+ { 130, (PFN*)&(pIMEData->mpQueryIMEProperty) },
+ { 131, (PFN*)&(pIMEData->mpRequestIME) },
+ { 128, (PFN*)&(pIMEData->mpSetIMEMode) },
+ { 127, (PFN*)&(pIMEData->mpQueryIMEMode) }
+ };
+
+ pIMEData->mhModIME = hMod;
+ for ( USHORT i = 0; i < SAL_IME_PROC_COUNT; i++ )
+ {
+ if ( 0 != DosQueryProcAddr( pIMEData->mhModIME, aProcAry[i].nOrd, 0, aProcAry[i].pProc ) )
+ {
+ bError = TRUE;
+ break;
+ }
+ }
+
+ if ( bError )
+ {
+ DosFreeModule( pIMEData->mhModIME );
+ delete pIMEData;
+ }
+ else
+ pSalData->mpIMEData = pIMEData;
+ }
+ }
+
+ return pSalData->mpIMEData;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplReleaseSALIMEData()
+{
+ SalData* pSalData = GetSalData();
+
+ if ( pSalData->mpIMEData )
+ {
+ DosFreeModule( pSalData->mpIMEData->mhModIME );
+ delete pSalData->mpIMEData;
+ }
+}
+
+#endif
+
+// =======================================================================
+
+static void ImplSaveFrameState( SalFrame* pFrame )
+{
+ if ( !pFrame->maFrameData.mbFullScreen )
+ {
+ SWP aSWP;
+
+ // Query actual state
+ WinQueryWindowPos( pFrame->maFrameData.mhWndFrame, &aSWP );
+
+ if ( aSWP.fl & SWP_MINIMIZE )
+ pFrame->maFrameData.maState.mnState |= SAL_FRAMESTATE_MINIMIZED;
+ else if ( aSWP.fl & SWP_MAXIMIZE )
+ {
+ pFrame->maFrameData.maState.mnState &= ~SAL_FRAMESTATE_MINIMIZED;
+ pFrame->maFrameData.maState.mnState |= SAL_FRAMESTATE_MAXIMIZED;
+ pFrame->maFrameData.mbRestoreMaximize = TRUE;
+ }
+ else
+ {
+ pFrame->maFrameData.maState.mnState &= ~(SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED);
+ pFrame->maFrameData.maState.mnX = aSWP.x;
+ pFrame->maFrameData.maState.mnY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN )-(aSWP.y+aSWP.cy);
+ pFrame->maFrameData.maState.mnWidth = aSWP.cx;
+ pFrame->maFrameData.maState.mnHeight = aSWP.cy;
+ pFrame->maFrameData.mbRestoreMaximize = FALSE;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ImplSalCallbackDummy( void*, SalFrame*, USHORT, const void* )
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* GetSalDefaultFrame()
+{
+ SalData* pSalData = GetSalData();
+
+ // Wenn kein Dummy-Frame existiert, dann legen wir uns einen an
+ if ( !pSalData->mpDummyFrame )
+ pSalData->mpDummyFrame = pSalData->mpFirstInstance->CreateFrame( NULL, 0 );
+
+ return pSalData->mpDummyFrame;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalCalcFrameSize( const SalFrame* pFrame,
+ LONG& rFrameX, LONG& rFrameY, LONG& rCaptionY )
+{
+ if ( pFrame->maFrameData.mnOS2Style & FCF_SIZEBORDER )
+ {
+ rFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER );
+ rFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER );
+ }
+ else if ( pFrame->maFrameData.mnOS2Style & FCF_DLGBORDER )
+ {
+ rFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXDLGFRAME );
+ rFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME );
+ }
+ else if ( pFrame->maFrameData.mnOS2Style & FCF_BORDER )
+ {
+ rFrameX = WinQuerySysValue( HWND_DESKTOP, SV_CXBORDER );
+ rFrameY = WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER );
+ }
+ else
+ {
+ rFrameX = 0;
+ rFrameY = 0;
+ }
+ if ( pFrame->maFrameData.mnOS2Style & (FCF_TITLEBAR | FCF_SYSMENU) )
+ rCaptionY = WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR );
+ else
+ rCaptionY = 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalCalcFullScreenSize( const SalFrame* pFrame,
+ LONG& rX, LONG& rY, LONG& rDX, LONG& rDY )
+{
+ // set window to screen size
+ LONG nFrameX;
+ LONG nFrameY;
+ LONG nCaptionY;
+ LONG nScreenDX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
+ LONG nScreenDY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
+
+ // Framegroessen berechnen
+ ImplSalCalcFrameSize( pFrame, nFrameX, nFrameY, nCaptionY );
+
+ rX = -nFrameX;
+ rY = -nFrameY;
+ rDX = nScreenDX+(nFrameX*2);
+ rDY = nScreenDY+(nFrameY*2)+nCaptionY;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalFrameFullScreenPos( SalFrame* pFrame, BOOL bAlways = FALSE )
+{
+ SWP aSWP;
+ WinQueryWindowPos( pFrame->maFrameData.mhWndFrame, &aSWP );
+ if ( bAlways || !(aSWP.fl & SWP_MINIMIZE) )
+ {
+ // set window to screen size
+ LONG nX;
+ LONG nY;
+ LONG nWidth;
+ LONG nHeight;
+ ImplSalCalcFullScreenSize( pFrame, nX, nY, nWidth, nHeight );
+ WinSetWindowPos( pFrame->maFrameData.mhWndFrame, 0,
+ nX, nY, nWidth, nHeight,
+ SWP_MOVE | SWP_SIZE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+// Uebersetzungstabelle von System-Keycodes in StarView-Keycodes
+#define KEY_TAB_SIZE (VK_ENDDRAG+1)
+
+static USHORT TranslateKey[KEY_TAB_SIZE] =
+{
+ // StarView-Code System-Code Index
+ 0, // 0x00
+ 0, // VK_BUTTON1 0x01
+ 0, // VK_BUTTON2 0x02
+ 0, // VK_BUTTON3 0x03
+ 0, // VK_BREAK 0x04
+ KEY_BACKSPACE, // VK_BACKSPACE 0x05
+ KEY_TAB, // VK_TAB 0x06
+ KEY_TAB, // VK_BACKTAB 0x07
+ KEY_RETURN, // VK_NEWLINE 0x08
+ 0, // VK_SHIFT 0x09
+ 0, // VK_CTRL 0x0A
+ 0, // VK_ALT 0x0B
+ 0, // VK_ALTGRAF 0x0C
+ 0, // VK_PAUSE 0x0D
+ 0, // VK_CAPSLOCK 0x0E
+ KEY_ESCAPE, // VK_ESC 0x0F
+ KEY_SPACE, // VK_SPACE 0x10
+ KEY_PAGEUP, // VK_PAGEUP 0x11
+ KEY_PAGEDOWN, // VK_PAGEDOWN 0x12
+ KEY_END, // VK_END 0x13
+ KEY_HOME, // VK_HOME 0x14
+ KEY_LEFT, // VK_LEFT 0x15
+ KEY_UP, // VK_UP 0x16
+ KEY_RIGHT, // VK_RIGHT 0x17
+ KEY_DOWN, // VK_DOWN 0x18
+ 0, // VK_PRINTSCRN 0x19
+ KEY_INSERT, // VK_INSERT 0x1A
+ KEY_DELETE, // VK_DELETE 0x1B
+ 0, // VK_SCRLLOCK 0x1C
+ 0, // VK_NUMLOCK 0x1D
+ KEY_RETURN, // VK_ENTER 0x1E
+ 0, // VK_SYSRQ 0x1F
+ KEY_F1, // VK_F1 0x20
+ KEY_F2, // VK_F2 0x21
+ KEY_F3, // VK_F3 0x22
+ KEY_F4, // VK_F4 0x23
+ KEY_F5, // VK_F5 0x24
+ KEY_F6, // VK_F6 0x25
+ KEY_F7, // VK_F7 0x26
+ KEY_F8, // VK_F8 0x27
+ KEY_F9, // VK_F9 0x28
+ KEY_F10, // VK_F10 0x29
+ KEY_F11, // VK_F11 0x2A
+ KEY_F12, // VK_F12 0x2B
+ KEY_F13, // VK_F13 0x2C
+ KEY_F14, // VK_F14 0x2D
+ KEY_F15, // VK_F15 0x2E
+ KEY_F16, // VK_F16 0x2F
+ KEY_F17, // VK_F17 0x30
+ KEY_F18, // VK_F18 0x31
+ KEY_F19, // VK_F19 0x32
+ KEY_F20, // VK_F20 0x33
+ KEY_F21, // VK_F21 0x34
+ KEY_F22, // VK_F22 0x35
+ KEY_F23, // VK_F23 0x36
+ KEY_F24, // VK_F24 0x37
+ 0 // VK_ENDDRAG 0x38
+};
+
+// =======================================================================
+
+SalFrame* ImplSalCreateFrame( SalInstance* pInst, SalFrame* pParent, ULONG nSalFrameStyle )
+{
+ SalData* pSalData = GetSalData();
+ SalFrame* pFrame = new SalFrame;
+ HWND hWndFrame;
+ HWND hWndClient;
+ PM_ULONG nFrameFlags = FCF_NOBYTEALIGN | FCF_NOMOVEWITHOWNER | FCF_SCREENALIGN;
+ PM_ULONG nFrameStyle = 0;
+ PM_ULONG nClientStyle = WS_CLIPSIBLINGS;
+
+ // determine creation data (bei Moveable nehmen wir DLG-Border, damit
+ // es besser aussieht)
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE )
+ nFrameFlags |= FCF_SIZEBORDER | FCF_SYSMENU;
+ else if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE )
+ nFrameFlags |= FCF_DLGBORDER;
+ else if ( nSalFrameStyle & SAL_FRAME_STYLE_BORDER )
+ nFrameFlags |= FCF_BORDER;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE )
+ nFrameFlags |= FCF_TITLEBAR | FCF_SYSMENU;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MINABLE )
+ nFrameFlags |= FCF_MINBUTTON | FCF_SYSMENU;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MAXABLE )
+ nFrameFlags |= FCF_MAXBUTTON | FCF_SYSMENU;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
+ nFrameFlags |= FCF_TASKLIST;
+
+ // create frame
+ pSalData->mpCreateFrame = pFrame;
+ hWndFrame = WinCreateStdWindow( HWND_DESKTOP, nFrameStyle, &nFrameFlags,
+ (PSZ)SAL_FRAME_CLASSNAME, (PSZ)"",
+ nClientStyle, 0, 0, &hWndClient );
+
+ if ( !hWndFrame )
+ {
+ delete pFrame;
+ return NULL;
+ }
+
+ // Parent setzen (Owner)
+ if ( pParent )
+ WinSetOwner( hWndFrame, pParent->maFrameData.mhWndClient );
+
+ // Icon setzen
+ if ( nFrameFlags & FCF_MINBUTTON )
+ WinSendMsg( hWndFrame, WM_SETICON, (MPARAM)pInst->maInstData.mhAppIcon, (MPARAM)0 );
+
+ // Frames subclassen, da wir auch dort die eine oder andere Message
+ // abfangen wollen oder anders behandeln wollen
+ aSalShlData.mpOldFrameProc = WinSubclassWindow( hWndFrame, SalFrameFrameProc );
+
+ // init frame data
+ pFrame->maFrameData.mhWndFrame = hWndFrame;
+ pFrame->maFrameData.mhWndClient = hWndClient;
+ pFrame->maFrameData.mhAB = pInst->maInstData.mhAB;
+ pFrame->maFrameData.mnStyle = nSalFrameStyle;
+ pFrame->maFrameData.mnOS2Style = nFrameFlags;
+ pFrame->maFrameData.maSysData.hWnd = hWndClient;
+
+ // determine show style
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
+ {
+ pSalData->mpDefaultFrame = pFrame;
+
+ // restore saved position
+ SWP aSWP;
+ memset( &aSWP, 0, sizeof( aSWP ) );
+ WinQueryTaskSizePos( pInst->maInstData.mhAB, 0, &aSWP );
+ WinSetWindowPos( hWndFrame, HWND_TOP,
+ aSWP.x, aSWP.y, aSWP.cx, aSWP.cy,
+ SWP_ZORDER | SWP_MOVE | SWP_SIZE |
+ (aSWP.fl & (SWP_RESTORE | SWP_MINIMIZE | SWP_MAXIMIZE)) );
+ if ( aSWP.fl & (SWP_MINIMIZE | SWP_MAXIMIZE) )
+ pFrame->maFrameData.mbOverwriteState = FALSE;
+ if ( !(aSWP.fl & SWP_MINIMIZE) )
+ WinSetWindowPos( hWndFrame, 0, 0, 0, 0, 0, SWP_MAXIMIZE );
+ }
+ else
+ {
+ SWP aSWP;
+ RECTL rectl;
+ memset( &aSWP, 0, sizeof( aSWP ) );
+ WinQueryWindowRect( HWND_DESKTOP, &rectl );
+ aSWP.x = rectl.xLeft + 10;
+ aSWP.y = rectl.yBottom + 10;
+ aSWP.cx = rectl.xRight - rectl.xLeft - 20;
+ aSWP.cy = rectl.yTop - rectl.yBottom - 20;
+ WinSetWindowPos( hWndFrame, HWND_TOP,
+ aSWP.x, aSWP.y, aSWP.cx, aSWP.cy,
+ SWP_MOVE | SWP_SIZE | SWP_ZORDER );
+ }
+
+ // disable close
+ if ( !(nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE) )
+ {
+ HWND hSysMenu = WinWindowFromID( hWndFrame, FID_SYSMENU );
+ if ( hSysMenu )
+ {
+ WinSendMsg( hSysMenu,
+ MM_SETITEMATTR,
+ MPFROM2SHORT( SC_CLOSE, TRUE ),
+ MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED ) );
+ }
+ }
+
+#ifdef ENABLE_IME
+/*
+ // Input-Context einstellen
+ SalIMEData* pIMEData = GetSalIMEData();
+ if ( pIMEData )
+ {
+ pFrame->maFrameData.mhIMEContext = 0;
+ if ( 0 != pIMEData->mpAssocIME( hWndClient, pFrame->maFrameData.mhIMEContext, &pFrame->maFrameData.mhDefIMEContext ) )
+ pFrame->maFrameData.mhDefIMEContext = 0;
+ }
+ else
+ {
+ pFrame->maFrameData.mhIMEContext = 0;
+ pFrame->maFrameData.mhDefIMEContext = 0;
+ }
+*/
+#endif
+
+ ImplSaveFrameState( pFrame );
+ pFrame->maFrameData.mbDefPos = TRUE;
+
+ return pFrame;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyFrame( SalFrame* pFrame )
+{
+ delete pFrame;
+}
+
+// =======================================================================
+
+SalFrame::SalFrame()
+{
+ SalData* pSalData = GetSalData();
+
+ maFrameData.mbGraphics = NULL;
+ maFrameData.mhPointer = WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE );
+ maFrameData.mpGraphics = NULL;
+ maFrameData.mpInst = NULL;
+ maFrameData.mpProc = ImplSalCallbackDummy;
+ maFrameData.mbFullScreen = FALSE;
+ maFrameData.mbAllwayOnTop = FALSE;
+ maFrameData.mbVisible = FALSE;
+ maFrameData.mbMinHide = FALSE;
+ maFrameData.mbInShow = FALSE;
+ maFrameData.mbRestoreMaximize = FALSE;
+ maFrameData.mbInMoveMsg = FALSE;
+ maFrameData.mbInSizeMsg = FALSE;
+ maFrameData.mbDefPos = TRUE;
+ maFrameData.mbOverwriteState = TRUE;
+ maFrameData.mbHandleIME = FALSE;
+ maFrameData.mbConversionMode = FALSE;
+ maFrameData.mbCandidateMode = FALSE;
+ memset( &maFrameData.maState, 0, sizeof( SalFrameState ) );
+ maFrameData.maSysData.nSize = sizeof( SystemEnvData );
+
+ // insert frame in framelist
+ maFrameData.mpNextFrame = pSalData->mpFirstFrame;
+ pSalData->mpFirstFrame = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame::~SalFrame()
+{
+ SalData* pSalData = GetSalData();
+
+ // destroy DC
+ if ( maFrameData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maFrameData.mpGraphics->maGraphicsData) );
+ WinReleasePS( maFrameData.mpGraphics->maGraphicsData.mhPS );
+ delete maFrameData.mpGraphics;
+ }
+
+ // destroy system frame
+ WinDestroyWindow( maFrameData.mhWndFrame );
+
+ // reset default and dummy frame
+ if ( pSalData->mpDefaultFrame == this )
+ pSalData->mpDefaultFrame = 0;
+ if ( pSalData->mpDummyFrame == this )
+ pSalData->mpDummyFrame = 0;
+
+ // remove frame from framelist
+ if ( this == pSalData->mpFirstFrame )
+ pSalData->mpFirstFrame = maFrameData.mpNextFrame;
+ else
+ {
+ SalFrame* pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame->maFrameData.mpNextFrame != this )
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+
+ pTempFrame->maFrameData.mpNextFrame = maFrameData.mpNextFrame;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static HDC ImplWinGetDC( HWND hWnd )
+{
+ HDC hDC = WinQueryWindowDC( hWnd );
+ if ( !hDC )
+ hDC = WinOpenWindowDC( hWnd );
+ return hDC;
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalFrame::GetGraphics()
+{
+ if ( maFrameData.mbGraphics )
+ return NULL;
+
+ if ( !maFrameData.mpGraphics )
+ {
+ SalData* pSalData = GetSalData();
+ maFrameData.mpGraphics = new SalGraphics;
+ maFrameData.mpGraphics->maGraphicsData.mhPS = WinGetPS( maFrameData.mhWndClient );
+ maFrameData.mpGraphics->maGraphicsData.mhDC = ImplWinGetDC( maFrameData.mhWndClient );
+ maFrameData.mpGraphics->maGraphicsData.mhWnd = maFrameData.mhWndClient;
+ maFrameData.mpGraphics->maGraphicsData.mnHeight = maFrameData.mnHeight;
+ maFrameData.mpGraphics->maGraphicsData.mbPrinter = FALSE;
+ maFrameData.mpGraphics->maGraphicsData.mbVirDev = FALSE;
+ maFrameData.mpGraphics->maGraphicsData.mbWindow = TRUE;
+ maFrameData.mpGraphics->maGraphicsData.mbScreen = TRUE;
+ ImplSalInitGraphics( &(maFrameData.mpGraphics->maGraphicsData) );
+ maFrameData.mbGraphics = TRUE;
+ }
+ else
+ maFrameData.mbGraphics = TRUE;
+
+ return maFrameData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ReleaseGraphics( SalGraphics* )
+{
+ maFrameData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalFrame::PostEvent( void* pData )
+{
+ return (BOOL)WinPostMsg( maFrameData.mhWndClient, SAL_MSG_USEREVENT, 0, (MPARAM)pData );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetTitle( const XubString& rTitle )
+{
+ // set window title
+ WinSetWindowText( maFrameData.mhWndFrame, (PSZ)(const char*)rTitle );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Show( BOOL bVisible )
+{
+ maFrameData.mbVisible = bVisible;
+ if ( bVisible )
+ {
+ maFrameData.mbOverwriteState = TRUE;
+ maFrameData.mbInShow = TRUE;
+ WinSetWindowPos( maFrameData.mhWndFrame, 0, 0, 0, 0, 0, SWP_SHOW | SWP_ACTIVATE );
+ maFrameData.mbInShow = FALSE;
+ WinUpdateWindow( maFrameData.mhWndClient );
+ }
+ else
+ {
+ maFrameData.mbInShow = TRUE;
+ WinSetWindowPos( maFrameData.mhWndFrame, 0, 0, 0, 0, 0, SWP_HIDE );
+ maFrameData.mbInShow = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetClientSize( long nWidth, long nHeight )
+{
+ // calculation frame size
+ LONG nX;
+ LONG nY;
+ LONG nFrameX;
+ LONG nFrameY;
+ LONG nCaptionY;
+ LONG nScreenWidth = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
+ LONG nScreenHeight = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
+
+ // Framegroessen berechnen
+ ImplSalCalcFrameSize( this, nFrameX, nFrameY, nCaptionY );
+
+ // adjust give size
+ nWidth += 2*nFrameX;
+ nHeight += 2*nFrameY + nCaptionY;
+
+ // Default-Position, dann zentrieren, ansonsten Position beibehalten
+ if ( maFrameData.mbDefPos )
+ {
+ // calculate bottom left corner of frame
+ nX = (nScreenWidth-nWidth)/2;
+ nY = (nScreenHeight-nHeight)/2;
+ maFrameData.mbDefPos = FALSE;
+ }
+ else
+ {
+ SWP aSWP;
+ WinQueryWindowPos( maFrameData.mhWndFrame, &aSWP );
+
+ nX = aSWP.x;
+ nY = aSWP.y+(aSWP.cy-nHeight);
+
+ // Fenster einpassen
+ if ( nX + nWidth > nScreenWidth )
+ nX = nScreenWidth - nWidth;
+ if ( nY < 0 )
+ nY = 0;
+ }
+
+ // Fenster einpassen
+ if ( nX < 0 )
+ nX = 0;
+ if ( nY > nScreenHeight-nHeight )
+ nY = nScreenHeight-nHeight;
+
+ // set new position
+ WinSetWindowPos( maFrameData.mhWndFrame,
+ 0,
+ nX, nY,
+ nWidth, nHeight,
+ SWP_MOVE | SWP_SIZE | SWP_RESTORE );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::GetClientSize( long& rWidth, long& rHeight )
+{
+ // Wenn wir von aussen gehidet werden (beispielsweise Hide-Button)
+ // muessen wir eine Groesse von 0,0 vorgaukeln, damit Dialoge noch
+ // als System-Fenster angezeigt werden
+ if ( maFrameData.mbMinHide )
+ {
+ rWidth = 0;
+ rHeight = 0;
+ }
+ else
+ {
+ rWidth = maFrameData.mnWidth;
+ rHeight = maFrameData.mnHeight;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetWindowState( const SalFrameState* pState )
+{
+ LONG nX = pState->mnX;
+ LONG nY = pState->mnY;
+ LONG nCX = pState->mnWidth;
+ LONG nCY = pState->mnHeight;
+
+ // Fenster-Position/Groesse in den Bildschirm einpassen
+ LONG nScreenWidth = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
+ LONG nScreenHeight = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
+ if ( nCX > nScreenWidth )
+ {
+ nX = 0;
+ nCX = nScreenWidth;
+ }
+ if ( nCY > nScreenHeight )
+ {
+ nY = 0;
+ nCY = nScreenHeight;
+ }
+
+ // Y is under OS2 bottom align
+ nY = nScreenHeight-(nY+nCY);
+
+ if ( !maFrameData.mbOverwriteState ||
+ (pState->mnState & (SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED)) )
+ {
+ if ( maFrameData.mbOverwriteState )
+ {
+ PM_ULONG nSizeStyle;
+ if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
+ nSizeStyle = SWP_MINIMIZE;
+ else
+ nSizeStyle = SWP_MAXIMIZE;
+ WinSetWindowPos( maFrameData.mhWndFrame, 0, 0, 0, 0, 0, nSizeStyle );
+ }
+
+ WinSetWindowUShort( maFrameData.mhWndFrame, QWS_XRESTORE, nX );
+ WinSetWindowUShort( maFrameData.mhWndFrame, QWS_YRESTORE, nY );
+ WinSetWindowUShort( maFrameData.mhWndFrame, QWS_CXRESTORE, nCX );
+ WinSetWindowUShort( maFrameData.mhWndFrame, QWS_CYRESTORE, nCY );
+ }
+ else
+ {
+ PM_ULONG nSizeStyle = SWP_MOVE | SWP_SIZE | SWP_RESTORE;
+ WinSetWindowPos( maFrameData.mhWndFrame, 0, nX, nY, nCX, nCY, nSizeStyle );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalFrame::GetWindowState( SalFrameState* pState )
+{
+ if ( maFrameData.maState.mnWidth && maFrameData.maState.mnHeight )
+ {
+ *pState = maFrameData.maState;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ShowFullScreen( BOOL bFullScreen )
+{
+ if ( maFrameData.mbFullScreen == bFullScreen )
+ return;
+
+ maFrameData.mbFullScreen = bFullScreen;
+ if ( bFullScreen )
+ {
+ // save old position
+ memset( &maFrameData.maFullScreenRect, 0, sizeof( SWP ) );
+ WinQueryWindowPos( maFrameData.mhWndFrame, &maFrameData.maFullScreenRect );
+
+ // set window to screen size
+ ImplSalFrameFullScreenPos( this, TRUE );
+ }
+ else
+ {
+ WinSetWindowPos( maFrameData.mhWndFrame,
+ 0,
+ maFrameData.maFullScreenRect.x, maFrameData.maFullScreenRect.y,
+ maFrameData.maFullScreenRect.cx, maFrameData.maFullScreenRect.cy,
+ SWP_MOVE | SWP_SIZE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::StartPresentation( BOOL bStart )
+{
+ // SysSetObjectData("<WP_DESKTOP>","Autolockup=no"); oder OS2.INI: PM_Lockup
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetAlwaysOnTop( BOOL bOnTop )
+{
+ maFrameData.mbAllwayOnTop = bOnTop;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ToTop( USHORT nFlags )
+{
+ PM_ULONG nStyle = 0;
+ SWP aSWP;
+ WinQueryWindowPos( maFrameData.mhWndFrame, &aSWP );
+ if ( aSWP.fl & SWP_MINIMIZE )
+ {
+ if ( !(nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN) )
+ return;
+
+ if ( maFrameData.mbRestoreMaximize )
+ nStyle |= SWP_MAXIMIZE;
+ else
+ nStyle |= SWP_RESTORE;
+ }
+
+ WinSetWindowPos( maFrameData.mhWndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER | nStyle );
+ WinSetFocus( HWND_DESKTOP, maFrameData.mhWndClient );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetPointer( PointerStyle ePointerStyle )
+{
+ struct ImplPtrData
+ {
+ HPOINTER mhPointer;
+ PM_ULONG mnSysId;
+ PM_ULONG mnOwnId;
+ };
+
+ static ImplPtrData aImplPtrTab[POINTER_COUNT] =
+ {
+ { 0, SPTR_ARROW, 0 }, // POINTER_ARROW
+ { 0, 0, SAL_RESID_POINTER_NULL }, // POINTER_NULL
+ { 0, SPTR_WAIT, 0 }, // POINTER_WAIT
+ { 0, SPTR_TEXT, 0 }, // POINTER_BEAM
+ { 0, 0, SAL_RESID_POINTER_HELP }, // POINTER_HELP
+ { 0, 0, SAL_RESID_POINTER_CROSS }, // POINTER_CROSS
+ { 0, 0, SAL_RESID_POINTER_MOVE }, // POINTER_MOVE
+ { 0, SPTR_SIZENS, 0 }, // POINTER_NSIZE
+ { 0, SPTR_SIZENS, 0 }, // POINTER_SSIZE
+ { 0, SPTR_SIZEWE, 0 }, // POINTER_WSIZE
+ { 0, SPTR_SIZEWE, 0 }, // POINTER_ESIZE
+ { 0, SPTR_SIZENWSE, 0 }, // POINTER_NWSIZE
+ { 0, SPTR_SIZENESW, 0 }, // POINTER_NESIZE
+ { 0, SPTR_SIZENESW, 0 }, // POINTER_SWSIZE
+ { 0, SPTR_SIZENWSE, 0 }, // POINTER_SESIZE
+ { 0, SPTR_SIZENS, 0 }, // POINTER_WINDOW_NSIZE
+ { 0, SPTR_SIZENS, 0 }, // POINTER_WINDOW_SSIZE
+ { 0, SPTR_SIZEWE, 0 }, // POINTER_WINDOW_WSIZE
+ { 0, SPTR_SIZEWE, 0 }, // POINTER_WINDOW_ESIZE
+ { 0, SPTR_SIZENWSE, 0 }, // POINTER_WINDOW_NWSIZE
+ { 0, SPTR_SIZENESW, 0 }, // POINTER_WINDOW_NESIZE
+ { 0, SPTR_SIZENESW, 0 }, // POINTER_WINDOW_SWSIZE
+ { 0, SPTR_SIZENWSE, 0 }, // POINTER_WINDOW_SESIZE
+ { 0, 0, SAL_RESID_POINTER_HSPLIT }, // POINTER_HSPLIT
+ { 0, 0, SAL_RESID_POINTER_VSPLIT }, // POINTER_VSPLIT
+ { 0, 0, SAL_RESID_POINTER_HSIZEBAR }, // POINTER_HSIZEBAR
+ { 0, 0, SAL_RESID_POINTER_VSIZEBAR }, // POINTER_VSIZEBAR
+ { 0, 0, SAL_RESID_POINTER_HAND }, // POINTER_HAND
+ { 0, 0, SAL_RESID_POINTER_REFHAND }, // POINTER_REFHAND
+ { 0, 0, SAL_RESID_POINTER_PEN }, // POINTER_PEN
+ { 0, 0, SAL_RESID_POINTER_MAGNIFY }, // POINTER_MAGNIFY
+ { 0, 0, SAL_RESID_POINTER_FILL }, // POINTER_FILL
+ { 0, 0, SAL_RESID_POINTER_ROTATE }, // POINTER_ROTATE
+ { 0, 0, SAL_RESID_POINTER_HSHEAR }, // POINTER_HSHEAR
+ { 0, 0, SAL_RESID_POINTER_VSHEAR }, // POINTER_VSHEAR
+ { 0, 0, SAL_RESID_POINTER_MIRROR }, // POINTER_MIRROR
+ { 0, 0, SAL_RESID_POINTER_CROOK }, // POINTER_CROOK
+ { 0, 0, SAL_RESID_POINTER_CROP }, // POINTER_CROP
+ { 0, 0, SAL_RESID_POINTER_MOVEPOINT }, // POINTER_MOVEPOINT
+ { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT }, // POINTER_MOVEBEZIERWEIGHT
+ { 0, 0, SAL_RESID_POINTER_MOVEDATA }, // POINTER_MOVEDATA
+ { 0, 0, SAL_RESID_POINTER_COPYDATA }, // POINTER_COPYDATA
+ { 0, 0, SAL_RESID_POINTER_LINKDATA }, // POINTER_LINKDATA
+ { 0, 0, SAL_RESID_POINTER_MOVEDATALINK }, // POINTER_MOVEDATALINK
+ { 0, 0, SAL_RESID_POINTER_COPYDATALINK }, // POINTER_COPYDATALINK
+ { 0, 0, SAL_RESID_POINTER_MOVEFILE }, // POINTER_MOVEFILE
+ { 0, 0, SAL_RESID_POINTER_COPYFILE }, // POINTER_COPYFILE
+ { 0, 0, SAL_RESID_POINTER_LINKFILE }, // POINTER_LINKFILE
+ { 0, 0, SAL_RESID_POINTER_MOVEFILELINK }, // POINTER_MOVEFILELINK
+ { 0, 0, SAL_RESID_POINTER_COPYFILELINK }, // POINTER_COPYFILELINK
+ { 0, 0, SAL_RESID_POINTER_MOVEFILES }, // POINTER_MOVEFILES
+ { 0, 0, SAL_RESID_POINTER_COPYFILES }, // POINTER_COPYFILES
+ { 0, SPTR_ILLEGAL, 0 }, // POINTER_NOTALLOWED
+ { 0, 0, SAL_RESID_POINTER_DRAW_LINE }, // POINTER_DRAW_LINE
+ { 0, 0, SAL_RESID_POINTER_DRAW_RECT }, // POINTER_DRAW_RECT
+ { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON }, // POINTER_DRAW_POLYGON
+ { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER }, // POINTER_DRAW_BEZIER
+ { 0, 0, SAL_RESID_POINTER_DRAW_ARC }, // POINTER_DRAW_ARC
+ { 0, 0, SAL_RESID_POINTER_DRAW_PIE }, // POINTER_DRAW_PIE
+ { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT }, // POINTER_DRAW_CIRCLECUT
+ { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE }, // POINTER_DRAW_ELLIPSE
+ { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND }, // POINTER_DRAW_FREEHAND
+ { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT }, // POINTER_DRAW_CONNECT
+ { 0, 0, SAL_RESID_POINTER_DRAW_TEXT }, // POINTER_DRAW_TEXT
+ { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION }, // POINTER_DRAW_CAPTION
+ { 0, 0, SAL_RESID_POINTER_CHART }, // POINTER_CHART
+ { 0, 0, SAL_RESID_POINTER_DETECTIVE }, // POINTER_DETECTIVE
+ { 0, 0, SAL_RESID_POINTER_PIVOT_COL }, // POINTER_PIVOT_COL
+ { 0, 0, SAL_RESID_POINTER_PIVOT_ROW }, // POINTER_PIVOT_ROW
+ { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD }, // POINTER_PIVOT_FIELD
+ { 0, 0, SAL_RESID_POINTER_CHAIN }, // POINTER_CHAIN
+ { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED }, // POINTER_CHAIN_NOTALLOWED
+ { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE }, // POINTER_TIMEEVENT_MOVE
+ { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE }, // POINTER_TIMEEVENT_SIZE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N }, // POINTER_AUTOSCROLL_N
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S }, // POINTER_AUTOSCROLL_S
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W }, // POINTER_AUTOSCROLL_W
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E }, // POINTER_AUTOSCROLL_E
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW }, // POINTER_AUTOSCROLL_NW
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE }, // POINTER_AUTOSCROLL_NE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW }, // POINTER_AUTOSCROLL_SW
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE }, // POINTER_AUTOSCROLL_SE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS }, // POINTER_AUTOSCROLL_NS
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE }, // POINTER_AUTOSCROLL_WE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE } // POINTER_AUTOSCROLL_NSWE
+ };
+
+#if POINTER_COUNT != 85
+#error New Pointer must be defined!
+#endif
+
+ // Mousepointer loaded ?
+ if ( !aImplPtrTab[ePointerStyle].mhPointer )
+ {
+ if ( aImplPtrTab[ePointerStyle].mnOwnId )
+ aImplPtrTab[ePointerStyle].mhPointer = ImplLoadPointer( aImplPtrTab[ePointerStyle].mnOwnId );
+ else
+ aImplPtrTab[ePointerStyle].mhPointer = WinQuerySysPointer( HWND_DESKTOP, aImplPtrTab[ePointerStyle].mnSysId, FALSE );
+ }
+
+ // Unterscheidet sich der Mauspointer, dann den neuen setzen
+ if ( maFrameData.mhPointer != aImplPtrTab[ePointerStyle].mhPointer )
+ {
+ maFrameData.mhPointer = aImplPtrTab[ePointerStyle].mhPointer;
+ WinSetPointer( HWND_DESKTOP, maFrameData.mhPointer );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::CaptureMouse( BOOL bCapture )
+{
+ if ( bCapture )
+ WinSetCapture( HWND_DESKTOP, maFrameData.mhWndClient );
+ else
+ WinSetCapture( HWND_DESKTOP, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetPointerPos( long nX, long nY )
+{
+ POINTL aPt;
+ aPt.x = nX;
+ aPt.y = maFrameData.mnHeight - nY - 1; // convert sal coords to sys
+ WinMapWindowPoints( maFrameData.mhWndClient, HWND_DESKTOP, &aPt, 1 );
+ WinSetPointerPos( HWND_DESKTOP, aPt.x, aPt.y );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Flush()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Sync()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetInputContext( SalInputContext* pContext )
+{
+#ifdef ENABLE_IME
+ SalIMEData* pIMEData = GetSalIMEData();
+ if ( pIMEData )
+ {
+ HWND hWnd = maFrameData.mhWndClient;
+ HIMI hIMI = 0;
+ pIMEData->mpGetIME( hWnd, &hIMI );
+ if ( hIMI )
+ {
+ PM_ULONG nInputMode;
+ PM_ULONG nConversionMode;
+ if ( 0 == pIMEData->mpQueryIMEMode( hIMI, &nInputMode, &nConversionMode ) )
+ {
+ if ( pContext->mnOptions & SAL_INPUTCONTEXT_TEXT )
+ {
+ nInputMode &= ~IMI_IM_IME_DISABLE;
+ if ( pContext->mnOptions & SAL_INPUTCONTEXT_EXTTEXTINPUT_OFF )
+ nInputMode &= ~IMI_IM_IME_ON;
+// !!! Da derzeit ueber das OS2-IME-UI der IME-Mode nicht einschaltbar ist !!!
+// if ( SAL_INPUTCONTEXT_EXTTEXTINPUT_ON )
+ nInputMode |= IMI_IM_IME_ON;
+ }
+ else
+ nInputMode |= IMI_IM_IME_DISABLE;
+ pIMEData->mpSetIMEMode( hIMI, nInputMode, nConversionMode );
+ }
+
+ pIMEData->mpReleaseIME( hWnd, hIMI );
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::UpdateExtTextInputArea()
+{
+#ifdef ENABLE_IME
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::EndExtTextInput( USHORT nFlags )
+{
+#ifdef ENABLE_IME
+ SalIMEData* pIMEData = GetSalIMEData();
+ if ( pIMEData )
+ {
+ HWND hWnd = maFrameData.mhWndClient;
+ HIMI hIMI = 0;
+ pIMEData->mpGetIME( hWnd, &hIMI );
+ if ( hIMI )
+ {
+ PM_ULONG nIndex;
+ if ( nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE )
+ nIndex = CNV_COMPLETE;
+ else
+ nIndex = CNV_CANCEL;
+
+ pIMEData->mpRequestIME( hIMI, REQ_CONVERSIONSTRING, nIndex, 0 );
+ pIMEData->mpReleaseIME( hWnd, hIMI );
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalFrame::GetKeyName( USHORT nCode )
+{
+ if ( eImplKeyboardLanguage == LANGUAGE_DONTKNOW )
+ eImplKeyboardLanguage = GetSystemLanguage();
+
+ XubString aKeyCode;
+ XubString aCode;
+ const char** pLangTab = ImplGetLangTab( eImplKeyboardLanguage );
+
+ if ( nCode & KEY_SHIFT )
+ aKeyCode = pLangTab[LSTR_KEY_SHIFT];
+
+ if ( nCode & KEY_MOD1 )
+ {
+ if ( !aKeyCode )
+ aKeyCode = pLangTab[LSTR_KEY_CTRL];
+ else
+ {
+ aKeyCode += '+';
+ aKeyCode += pLangTab[LSTR_KEY_CTRL];
+ }
+ }
+
+ if ( nCode & KEY_MOD2 )
+ {
+ if ( !aKeyCode )
+ aKeyCode = pLangTab[LSTR_KEY_ALT];
+ else
+ {
+ aKeyCode += '+';
+ aKeyCode += pLangTab[LSTR_KEY_ALT];
+ }
+ }
+
+ USHORT nKeyCode = nCode & 0x0FFF;
+ switch ( nKeyCode )
+ {
+ case KEY_0:
+ case KEY_1:
+ case KEY_2:
+ case KEY_3:
+ case KEY_4:
+ case KEY_5:
+ case KEY_6:
+ case KEY_7:
+ case KEY_8:
+ case KEY_9:
+ aCode += (char)('0' + (nKeyCode - KEY_0));
+ break;
+
+ case KEY_A:
+ case KEY_B:
+ case KEY_C:
+ case KEY_D:
+ case KEY_E:
+ case KEY_F:
+ case KEY_G:
+ case KEY_H:
+ case KEY_I:
+ case KEY_J:
+ case KEY_K:
+ case KEY_L:
+ case KEY_M:
+ case KEY_N:
+ case KEY_O:
+ case KEY_P:
+ case KEY_Q:
+ case KEY_R:
+ case KEY_S:
+ case KEY_T:
+ case KEY_U:
+ case KEY_V:
+ case KEY_W:
+ case KEY_X:
+ case KEY_Y:
+ case KEY_Z:
+ aCode += (char)('A' + (nKeyCode - KEY_A));
+ break;
+
+ case KEY_F1:
+ case KEY_F2:
+ case KEY_F3:
+ case KEY_F4:
+ case KEY_F5:
+ case KEY_F6:
+ case KEY_F7:
+ case KEY_F8:
+ case KEY_F9:
+ case KEY_F10:
+ case KEY_F11:
+ case KEY_F12:
+ case KEY_F13:
+ case KEY_F14:
+ case KEY_F15:
+ case KEY_F16:
+ case KEY_F17:
+ case KEY_F18:
+ case KEY_F19:
+ case KEY_F20:
+ case KEY_F21:
+ case KEY_F22:
+ case KEY_F23:
+ case KEY_F24:
+ case KEY_F25:
+ case KEY_F26:
+ aCode += 'F';
+ aCode += (USHORT)nKeyCode - KEY_F1 + 1;
+ break;
+
+ case KEY_DOWN:
+ aCode = pLangTab[LSTR_KEY_DOWN];
+ break;
+ case KEY_UP:
+ aCode = pLangTab[LSTR_KEY_UP];
+ break;
+ case KEY_LEFT:
+ aCode = pLangTab[LSTR_KEY_LEFT];
+ break;
+ case KEY_RIGHT:
+ aCode = pLangTab[LSTR_KEY_RIGHT];
+ break;
+ case KEY_HOME:
+ aCode = pLangTab[LSTR_KEY_HOME];
+ break;
+ case KEY_END:
+ aCode = pLangTab[LSTR_KEY_END];
+ break;
+ case KEY_PAGEUP:
+ aCode = pLangTab[LSTR_KEY_PAGEUP];
+ break;
+ case KEY_PAGEDOWN:
+ aCode = pLangTab[LSTR_KEY_PAGEDOWN];
+ break;
+ case KEY_RETURN:
+ aCode = pLangTab[LSTR_KEY_RETURN];
+ break;
+ case KEY_ESCAPE:
+ aCode = pLangTab[LSTR_KEY_ESC];
+ break;
+ case KEY_TAB:
+ aCode = pLangTab[LSTR_KEY_TAB];
+ break;
+ case KEY_BACKSPACE:
+ aCode = pLangTab[LSTR_KEY_BACKSPACE];
+ break;
+ case KEY_SPACE:
+ aCode = pLangTab[LSTR_KEY_SPACE];
+ break;
+ case KEY_INSERT:
+ aCode = pLangTab[LSTR_KEY_INSERT];
+ break;
+ case KEY_DELETE:
+ aCode = pLangTab[LSTR_KEY_DELETE];
+ break;
+
+ case KEY_ADD:
+ aCode += '+';
+ break;
+ case KEY_SUBTRACT:
+ aCode += '-';
+ break;
+ case KEY_MULTIPLY:
+ aCode += '*';
+ break;
+ case KEY_DIVIDE:
+ aCode += '/';
+ break;
+ case KEY_POINT:
+ aCode += '.';
+ break;
+ case KEY_COMMA:
+ aCode += ',';
+ break;
+ case KEY_LESS:
+ aCode += '<';
+ break;
+ case KEY_GREATER:
+ aCode += '>';
+ break;
+ case KEY_EQUAL:
+ aCode += '=';
+ break;
+ }
+
+ if ( aCode.Len() )
+ {
+ if ( !aKeyCode )
+ aKeyCode = aCode;
+ else
+ {
+ aKeyCode += '+';
+ aKeyCode += aCode;
+ }
+ }
+
+ return aKeyCode;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode )
+{
+ return GetKeyName( nKeyCode );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplOS2ColorToSal( long nOS2Color )
+{
+ return MAKE_SALCOLOR( (BYTE)( nOS2Color>>16), (BYTE)(nOS2Color>>8), (BYTE)nOS2Color );
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplMouseSysValueToSAL( int iSysValue, USHORT& rCode, USHORT& rClicks, BOOL& rDown )
+{
+ LONG lValue = WinQuerySysValue( HWND_DESKTOP, iSysValue );
+
+ rCode = 0;
+ rClicks = 1;
+ rDown = TRUE;
+
+ switch ( lValue & 0xFFFF )
+ {
+ case WM_BUTTON1UP:
+ case WM_BUTTON1CLICK:
+ rCode = MOUSE_LEFT;
+ rDown = FALSE;
+ break;
+ case WM_BUTTON1DOWN:
+ case WM_BUTTON1MOTIONSTART:
+ rCode = MOUSE_LEFT;
+ break;
+ case WM_BUTTON1DBLCLK:
+ rCode = MOUSE_LEFT;
+ rClicks = 2;
+ break;
+
+ case WM_BUTTON2UP:
+ case WM_BUTTON2CLICK:
+ rCode = MOUSE_RIGHT;
+ rDown = FALSE;
+ break;
+ case WM_BUTTON2DOWN:
+ case WM_BUTTON2MOTIONSTART:
+ rCode = MOUSE_RIGHT;
+ break;
+ case WM_BUTTON2DBLCLK:
+ rCode = MOUSE_RIGHT;
+ rClicks = 2;
+ break;
+
+ case WM_BUTTON3UP:
+ case WM_BUTTON3CLICK:
+ rCode = MOUSE_MIDDLE;
+ rDown = FALSE;
+ break;
+ case WM_BUTTON3DOWN:
+ case WM_BUTTON3MOTIONSTART:
+ rCode = MOUSE_MIDDLE;
+ break;
+ case WM_BUTTON3DBLCLK:
+ rCode = MOUSE_MIDDLE;
+ rClicks = 2;
+ break;
+ }
+
+ if ( !rCode )
+ return FALSE;
+
+ lValue = (lValue & 0xFFFF0000) >> 16;
+ if ( lValue != 0xFFFF )
+ {
+ if ( lValue & KC_SHIFT )
+ rCode |= KEY_SHIFT;
+ if ( lValue & KC_CTRL )
+ rCode |= KEY_MOD1;
+ if ( lValue & KC_ALT )
+ rCode |= KEY_MOD2;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplSalIsSameColor( const Color& rColor1, const Color& rColor2 )
+{
+ ULONG nWrong = 0;
+ nWrong += Abs( (short)rColor1.GetRed()-(short)rColor2.GetRed() );
+ nWrong += Abs( (short)rColor1.GetGreen()-(short)rColor2.GetGreen() );
+ nWrong += Abs( (short)rColor1.GetBlue()-(short)rColor2.GetBlue() );
+ return (nWrong < 30);
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplOS2NameFontToVCLFont( const char* pFontName, Font& rFont )
+{
+ char aNumBuf[10];
+ int nNumBufLen = 0;
+
+ while ( *pFontName && (*pFontName != '.') &&
+ (nNumBufLen < sizeof(aNumBuf)-1) )
+ {
+ aNumBuf[nNumBufLen] = *pFontName;
+ nNumBufLen++;
+ pFontName++;
+ }
+ aNumBuf[nNumBufLen] = '\0';
+
+ pFontName++;
+ while ( *pFontName == ' ' )
+ pFontName++;
+
+ int nFontHeight = atoi( aNumBuf );
+ int nFontNameLen = strlen( pFontName );
+ if ( nFontHeight && nFontNameLen )
+ {
+ rFont.SetName( pFontName );
+ rFont.SetSize( Size( 0, nFontHeight ) );
+ rFont.SetFamily( FAMILY_DONTKNOW );
+ rFont.SetWeight( WEIGHT_NORMAL );
+ rFont.SetItalic( ITALIC_NONE );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::UpdateSettings( AllSettings& rSettings )
+{
+ static char aControlPanel[] = "PM_ControlPanel";
+ static char aSystemFonts[] = "PM_SystemFonts";
+ char aDummyStr[] = "";
+
+ // --- Mouse setting ---
+ USHORT nCode;
+ USHORT nClicks;
+ BOOL bDown;
+ MouseSettings aMouseSettings = rSettings.GetMouseSettings();
+ aMouseSettings.SetDoubleClickTime( WinQuerySysValue( HWND_DESKTOP, SV_DBLCLKTIME ) );
+ if ( ImplMouseSysValueToSAL( SV_BEGINDRAG, nCode, nClicks, bDown ) )
+ aMouseSettings.SetStartDragCode( nCode );
+ if ( ImplMouseSysValueToSAL( SV_CONTEXTMENU, nCode, nClicks, bDown ) )
+ {
+ aMouseSettings.SetContextMenuCode( nCode );
+ aMouseSettings.SetContextMenuClicks( nClicks );
+ aMouseSettings.SetContextMenuDown( bDown );
+ }
+ aMouseSettings.SetButtonStartRepeat( WinQuerySysValue( HWND_DESKTOP, SV_FIRSTSCROLLRATE ) );
+ aMouseSettings.SetButtonRepeat( WinQuerySysValue( HWND_DESKTOP, SV_SCROLLRATE ) );
+ rSettings.SetMouseSettings( aMouseSettings );
+
+ // --- Style settings ---
+ StyleSettings aStyleSettings = rSettings.GetStyleSettings();
+ BOOL bCompBorder = (aStyleSettings.GetOptions() & (STYLE_OPTION_MACSTYLE | STYLE_OPTION_UNIXSTYLE)) == 0;
+
+ // General settings
+ LONG nDisplayTime = PrfQueryProfileInt( HINI_PROFILE, (PSZ)aControlPanel, (PSZ)"LogoDisplayTime", -1 );
+ ULONG nSalDisplayTime;
+ if ( nDisplayTime < 0 )
+ nSalDisplayTime = LOGO_DISPLAYTIME_STARTTIME;
+ else if ( !nDisplayTime )
+ nSalDisplayTime = LOGO_DISPLAYTIME_NOLOGO;
+ else
+ nSalDisplayTime = (ULONG)nDisplayTime;
+ aStyleSettings.SetLogoDisplayTime( nSalDisplayTime );
+
+ aStyleSettings.SetCursorBlinkTime( WinQuerySysValue( HWND_DESKTOP, SV_CURSORRATE ) );
+ ULONG nDragFullOptions = aStyleSettings.GetDragFullOptions();
+ if ( WinQuerySysValue( HWND_DESKTOP, SV_FULLWINDOWDRAG ) )
+ nDragFullOptions |= DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT;
+ else
+ nDragFullOptions &= ~(DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT);
+ aStyleSettings.SetDragFullOptions( nDragFullOptions );
+
+ // Size settings
+ aStyleSettings.SetScrollBarSize( WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL ) );
+ if ( bCompBorder )
+ {
+ aStyleSettings.SetTitleHeight( WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) );
+ }
+
+ // Color settings
+ if ( bCompBorder )
+ {
+ aStyleSettings.SetFaceColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) );
+ aStyleSettings.SetLightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONLIGHT, 0 ) ) );
+ aStyleSettings.SetLightBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) );
+ aStyleSettings.SetShadowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONDARK, 0 ) ) );
+ aStyleSettings.SetDarkShadowColor( Color( COL_BLACK ) );
+ aStyleSettings.SetDialogColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0 ) ) );
+ aStyleSettings.SetButtonTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) );
+ aStyleSettings.SetActiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLE, 0 ) ) );
+ aStyleSettings.SetActiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLETEXT, 0 ) ) );
+ aStyleSettings.SetActiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVEBORDER, 0 ) ) );
+ aStyleSettings.SetDeactiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLE, 0 ) ) );
+ aStyleSettings.SetDeactiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLETEXT, 0 ) ) );
+ aStyleSettings.SetDeactiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVEBORDER, 0 ) ) );
+ aStyleSettings.SetMenuColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENU, 0 ) ) );
+ aStyleSettings.SetMenuTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) );
+ }
+ aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() );
+ aStyleSettings.SetRadioCheckTextColor( aStyleSettings.GetButtonTextColor() );
+ aStyleSettings.SetGroupTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOWSTATICTEXT, 0 ) ) );
+ aStyleSettings.SetLabelTextColor( aStyleSettings.GetGroupTextColor() );
+ aStyleSettings.SetInfoTextColor( aStyleSettings.GetGroupTextColor() );
+ aStyleSettings.SetWindowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOW, 0 ) ) );
+ aStyleSettings.SetWindowTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOWTEXT, 0 ) ) );
+ aStyleSettings.SetFieldColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ENTRYFIELD, 0 ) ) );
+ aStyleSettings.SetFieldTextColor( aStyleSettings.GetWindowTextColor() );
+ aStyleSettings.SetDisableColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUDISABLEDTEXT, 0 ) ) );
+ aStyleSettings.SetHighlightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_HILITEBACKGROUND, 0 ) ) );
+ aStyleSettings.SetHighlightTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_HILITEFOREGROUND, 0 ) ) );
+ Color aMenuHighColor = ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUHILITEBGND, 0 ) );
+ if ( ImplSalIsSameColor( aMenuHighColor, aStyleSettings.GetMenuColor() ) )
+ {
+ if ( bCompBorder )
+ {
+ aStyleSettings.SetMenuHighlightColor( Color( COL_BLUE ) );
+ aStyleSettings.SetMenuHighlightTextColor( Color( COL_WHITE ) );
+ }
+ }
+ else
+ {
+ aStyleSettings.SetMenuHighlightColor( aMenuHighColor );
+ aStyleSettings.SetMenuHighlightTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUHILITE, 0 ) ) );
+ }
+ // Checked-Color berechnen
+ Color aColor1 = aStyleSettings.GetFaceColor();
+ Color aColor2 = aStyleSettings.GetLightColor();
+ BYTE nRed = (BYTE)(((USHORT)aColor1.GetRed() + (USHORT)aColor2.GetRed())/2);
+ BYTE nGreen = (BYTE)(((USHORT)aColor1.GetGreen() + (USHORT)aColor2.GetGreen())/2);
+ BYTE nBlue = (BYTE)(((USHORT)aColor1.GetBlue() + (USHORT)aColor2.GetBlue())/2);
+ aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) );
+
+ // Fonts updaten
+ Font aFont;
+ char aFontNameBuf[255];
+ aFont = aStyleSettings.GetMenuFont();
+ if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"Menus", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 )
+ {
+ if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) )
+ aStyleSettings.SetMenuFont( aFont );
+ }
+ aFont = aStyleSettings.GetIconFont();
+ if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"IconText", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 )
+ {
+ if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) )
+ aStyleSettings.SetIconFont( aFont );
+ }
+ aFont = aStyleSettings.GetTitleFont();
+ if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"WindowTitles", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 )
+ {
+ if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) )
+ {
+ aStyleSettings.SetTitleFont( aFont );
+ aStyleSettings.SetFloatTitleFont( aFont );
+ }
+ }
+ aFont = aStyleSettings.GetAppFont();
+ if ( PrfQueryProfileString( HINI_PROFILE, (PSZ)aSystemFonts, (PSZ)"WindowText", aDummyStr, aFontNameBuf, sizeof( aFontNameBuf ) ) > 5 )
+ {
+ if ( ImplOS2NameFontToVCLFont( aFontNameBuf, aFont ) )
+ {
+ Font aHelpFont = aFont;
+ aHelpFont.SetName( "Helv;WarpSans" );
+ aHelpFont.SetSize( Size( 0, 8 ) );
+ aHelpFont.SetWeight( WEIGHT_NORMAL );
+ aHelpFont.SetItalic( ITALIC_NONE );
+ aStyleSettings.SetHelpFont( aHelpFont );
+
+ // Bei System mappen wir direkt auf WarpSans/Helv, da diese
+ // unserer Meinung besser aussehen
+ if ( aFont.GetName().Search( "System" ) != STRING_NOTFOUND )
+ {
+ XubString aFontName = aFont.GetName();
+ aFontName.Insert( "WarpSans;Helv;" );
+ aFont.SetName( aFontName );
+ aFont.SetSize( Size( 0, 9 ) );
+ }
+ aStyleSettings.SetAppFont( aFont );
+ aStyleSettings.SetToolFont( aFont );
+ aStyleSettings.SetLabelFont( aFont );
+ aStyleSettings.SetInfoFont( aFont );
+ aStyleSettings.SetRadioCheckFont( aFont );
+ aStyleSettings.SetPushButtonFont( aFont );
+ aStyleSettings.SetFieldFont( aFont );
+ aStyleSettings.SetGroupFont( aFont );
+ }
+ }
+
+ rSettings.SetStyleSettings( aStyleSettings );
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* SalFrame::GetSystemData() const
+{
+ return &maFrameData.maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Beep( SoundType eSoundType )
+{
+ static PM_ULONG aImplSoundTab[5] =
+ {
+ WA_NOTE, // SOUND_DEFAULT
+ WA_NOTE, // SOUND_INFO
+ WA_WARNING, // SOUND_WARNING
+ WA_ERROR, // SOUND_ERROR
+ WA_NOTE // SOUND_QUERY
+ };
+
+#if SOUND_COUNT != 5
+#error New Sound must be defined!
+#endif
+
+ WinAlarm( HWND_DESKTOP, aImplSoundTab[eSoundType] );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetCallback( void* pInst, SALFRAMEPROC pProc )
+{
+ if( pProc == NULL )
+ maFrameData.mpProc = ImplSalCallbackDummy;
+ else
+ {
+ maFrameData.mpInst = pInst;
+ maFrameData.mpProc = pProc;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void SalTestMouseLeave()
+{
+ SalData* pSalData = GetSalData();
+
+ if ( pSalData->mhWantLeaveMsg && !::WinQueryCapture( HWND_DESKTOP ) )
+ {
+ POINTL aPt;
+ WinQueryPointerPos( HWND_DESKTOP, &aPt );
+ if ( pSalData->mhWantLeaveMsg != WinWindowFromPoint( HWND_DESKTOP, &aPt, TRUE ) )
+ WinSendMsg( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MPFROM2SHORT( aPt.x, aPt.y ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleMouseMsg( SalFrame* pFrame,
+ UINT nMsg, MPARAM nMP1, MPARAM nMP2 )
+{
+ SalMouseEvent aMouseEvt;
+ long nRet;
+ USHORT nEvent;
+ BOOL bRetTRUE = FALSE;
+ BOOL bCall = TRUE;
+ BOOL bActivate = FALSE;
+ USHORT nFlags = SHORT2FROMMP( nMP2 );
+
+ aMouseEvt.mnX = (short)SHORT1FROMMP( nMP1 );
+ aMouseEvt.mnY = pFrame->maFrameData.mnHeight - (short)SHORT2FROMMP( nMP1 ) - 1;
+ aMouseEvt.mnCode = 0;
+ aMouseEvt.mnTime = WinQueryMsgTime( pFrame->maFrameData.mhAB );
+
+ // MausModus feststellen und setzen
+ if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_LEFT;
+ if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_RIGHT;
+ if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_MIDDLE;
+ // Modifier-Tasten setzen
+ if ( WinGetKeyState( HWND_DESKTOP, VK_SHIFT ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_SHIFT;
+ if ( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_MOD1;
+ if ( WinGetKeyState( HWND_DESKTOP, VK_ALT ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_MOD2;
+
+ switch ( nMsg )
+ {
+ case WM_MOUSEMOVE:
+ {
+ SalData* pSalData = GetSalData();
+
+ // Da bei Druecken von Modifier-Tasten die MouseEvents
+ // nicht zusammengefast werden (da diese durch KeyEvents
+ // unterbrochen werden), machen wir dieses hier selber
+ if ( aMouseEvt.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2) )
+ {
+ QMSG aTempMsg;
+ if ( WinPeekMsg( pSalData->mhAB, &aTempMsg,
+ pFrame->maFrameData.mhWndClient,
+ WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE ) )
+ {
+ if ( (aTempMsg.msg == WM_MOUSEMOVE) &&
+ (aTempMsg.mp2 == nMP2) )
+ return 1;
+ }
+ }
+
+ // Test for MouseLeave
+ if ( pSalData->mhWantLeaveMsg &&
+ (pSalData->mhWantLeaveMsg != pFrame->maFrameData.mhWndClient) )
+ {
+ POINTL aMousePoint;
+ WinQueryMsgPos( pFrame->maFrameData.mhAB, &aMousePoint );
+ WinSendMsg( pSalData->mhWantLeaveMsg,
+ SAL_MSG_MOUSELEAVE,
+ 0, MPFROM2SHORT( aMousePoint.x, aMousePoint.y ) );
+ }
+ pSalData->mhWantLeaveMsg = pFrame->maFrameData.mhWndClient;
+ // Start MouseLeave-Timer
+ if ( !pSalData->mpMouseLeaveTimer )
+ {
+ pSalData->mpMouseLeaveTimer = new AutoTimer;
+ pSalData->mpMouseLeaveTimer->SetTimeout( SAL_MOUSELEAVE_TIMEOUT );
+ pSalData->mpMouseLeaveTimer->Start();
+ // We dont need to set a timeout handler, because we test
+ // for mouseleave in the timeout callback
+ }
+ aMouseEvt.mnButton = 0;
+ nEvent = SALEVENT_MOUSEMOVE;
+ }
+ break;
+
+ case SAL_MSG_MOUSELEAVE:
+ {
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mhWantLeaveMsg == pFrame->maFrameData.mhWndClient )
+ {
+ pSalData->mhWantLeaveMsg = 0;
+ if ( pSalData->mpMouseLeaveTimer )
+ {
+ delete pSalData->mpMouseLeaveTimer;
+ pSalData->mpMouseLeaveTimer = NULL;
+ }
+
+ // Mouse-Coordinaates are relativ to the screen
+ POINTL aPt;
+ aPt.x = (short)SHORT1FROMMP( nMP2 );
+ aPt.y = (short)SHORT2FROMMP( nMP2 );
+ WinMapWindowPoints( HWND_DESKTOP, pFrame->maFrameData.mhWndClient, &aPt, 1 );
+ aPt.y = pFrame->maFrameData.mnHeight - aPt.y - 1;
+ aMouseEvt.mnX = aPt.x;
+ aMouseEvt.mnY = aPt.y;
+ aMouseEvt.mnButton = 0;
+ nEvent = SALEVENT_MOUSELEAVE;
+ }
+ else
+ bCall = FALSE;
+ }
+ break;
+
+ case WM_BUTTON1DBLCLK:
+ case WM_BUTTON1DOWN:
+ aMouseEvt.mnButton = MOUSE_LEFT;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ bActivate = TRUE;
+ break;
+
+ case WM_BUTTON2DBLCLK:
+ case WM_BUTTON2DOWN:
+ aMouseEvt.mnButton = MOUSE_RIGHT;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ bActivate = TRUE;
+ break;
+
+ case WM_BUTTON3DBLCLK:
+ case WM_BUTTON3DOWN:
+ aMouseEvt.mnButton = MOUSE_MIDDLE;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ bActivate = TRUE;
+ break;
+
+ case WM_BUTTON1UP:
+ aMouseEvt.mnButton = MOUSE_LEFT;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+
+ case WM_BUTTON2UP:
+ aMouseEvt.mnButton = MOUSE_RIGHT;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+
+ case WM_BUTTON3UP:
+ aMouseEvt.mnButton = MOUSE_MIDDLE;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+ }
+
+ // Vorsichtshalber machen wir dies hier noch und gehen ueber
+ // den neuen SAL-Event. Eigentlich muesste dies immer durch
+ // den unabhaengigen Teil ausgeloest werden!
+ if ( bActivate )
+ {
+ SalMouseActivateEvent aMouseActivateEvt;
+ aMouseActivateEvt.mnX = aMouseEvt.mnX;
+ aMouseActivateEvt.mnY = aMouseEvt.mnY;
+ if ( !pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_MOUSEACTIVATE, &aMouseActivateEvt ) )
+ WinSetWindowPos( pFrame->maFrameData.mhWndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER );
+ else
+ bRetTRUE = TRUE;
+ }
+
+ if ( bCall )
+ {
+ if ( nEvent == SALEVENT_MOUSEBUTTONDOWN )
+ WinUpdateWindow( pFrame->maFrameData.mhWndClient );
+
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aMouseEvt );
+ if ( nMsg == WM_MOUSEMOVE )
+ {
+ WinSetPointer( HWND_DESKTOP, pFrame->maFrameData.mhPointer );
+ nRet = TRUE;
+ }
+ }
+ else
+ nRet = 0;
+
+ if ( bRetTRUE )
+ nRet = TRUE;
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplConvertKey( MPARAM aMP1, MPARAM aMP2, USHORT& rSVCode, xub_Unicode& rSVCharCode )
+{
+ USHORT nKeyFlags = SHORT1FROMMP( aMP1 );
+ UCHAR nCharCode = (UCHAR)SHORT1FROMMP( aMP2 );
+ USHORT nKeyCode = (UCHAR)SHORT2FROMMP( aMP2 );
+
+ // Ist virtueller KeyCode gesetzt und befindet sich der KeyCode in der
+ // Tabelle, dann mappen
+ if ( (nKeyFlags & KC_VIRTUALKEY) && (nKeyCode < KEY_TAB_SIZE) )
+ rSVCode = TranslateKey[nKeyCode];
+
+ // Ist Character-Code gesetzt
+ // !!! Bei CTRL/ALT ist KC_CHAR nicht gesetzt, jedoch moechten wir
+ // !!! dann auch einen CharCode und machen die Behandlung deshalb
+ // !!! selber
+ if ( (nKeyFlags & KC_CHAR) || (nKeyFlags & KC_CTRL) || (nKeyFlags & KC_ALT) )
+ rSVCharCode = (xub_Unicode)nCharCode;
+
+ // Bei KeyUp muessen wir ein paar andere Ausnahmen machen, da
+ // uns in den meisten Faellen kein KeyCode geliefert wird, aber
+ // dafuer ein CharCode, wo jedoch nicht KC_CHAR gesetzt ist.
+ if ( nKeyFlags & KC_KEYUP )
+ {
+ if ( !rSVCode )
+ {
+ // Hier nur CharCode zuweisen, der KeyCode wird im unteren
+ // Teil dieser Function dann aus dem CharCode ermittelt
+ if ( !rSVCharCode && nCharCode )
+ rSVCharCode = (xub_Unicode)nCharCode;
+ }
+ }
+
+ // Wenn kein KeyCode ermittelt werden konnte, versuchen wir aus dem
+ // CharCode einen zu erzeugen
+ if ( !rSVCode && rSVCharCode )
+ {
+ // Bei 0-9, a-z und A-Z auch KeyCode setzen
+ if ( (rSVCharCode >= '0') && (rSVCharCode <= '9') && (!rSVCode || !(nKeyFlags & KC_SHIFT)) )
+ rSVCode = KEY_0 + (rSVCharCode-'0');
+ else if ( (rSVCharCode >= 'a') && (rSVCharCode <= 'z') )
+ rSVCode = KEY_A + (rSVCharCode-'a');
+ else if ( (rSVCharCode >= 'A') && (rSVCharCode <= 'Z') )
+ rSVCode = KEY_A + (rSVCharCode-'A');
+ else
+ {
+ switch ( rSVCharCode )
+ {
+ case '+':
+ rSVCode = KEY_ADD;
+ break;
+ case '-':
+ rSVCode = KEY_SUBTRACT;
+ break;
+ case '*':
+ rSVCode = KEY_MULTIPLY;
+ break;
+ case '/':
+ rSVCode = KEY_DIVIDE;
+ break;
+ case '.':
+ rSVCode = KEY_POINT;
+ break;
+ case ',':
+ rSVCode = KEY_COMMA;
+ break;
+ case '<':
+ rSVCode = KEY_LESS;
+ break;
+ case '>':
+ rSVCode = KEY_GREATER;
+ break;
+ case '=':
+ rSVCode = KEY_EQUAL;
+ break;
+ }
+ }
+ }
+
+ // "Numlock-Hack": we want to get correct keycodes from the numpad
+ if ( (rSVCharCode >= '0') && (rSVCharCode <= '9') )
+ rSVCode = KEY_0 + (rSVCharCode-'0');
+ if ( rSVCharCode == ',' )
+ rSVCode = KEY_COMMA;
+ if ( rSVCharCode == '.' )
+ rSVCode = KEY_POINT;
+
+ if ( nKeyFlags & KC_CTRL )
+ {
+ // Ist CTRL-Taste gedrueckt, dann Char-Code korrigieren
+ if ( (rSVCharCode >= 'a') && (rSVCharCode <= 'z') )
+ rSVCharCode -= ('a' - 1);
+
+ // Ist CTRL-Taste gedrueckt, dann Char-Code auf 0 setzen, wenn
+ // der CharCode nicht < 32 ist
+ if ( ((unsigned char)rSVCharCode) >= 32 )
+ rSVCharCode = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleKeyMsg( SalFrame* pFrame,
+ UINT nMsg, MPARAM nMP1, MPARAM nMP2 )
+{
+ static USHORT nLastOS2KeyChar = 0;
+ static xub_Unicode nLastChar = 0;
+ USHORT nRepeat = CHAR3FROMMP( nMP1 ) - 1;
+ SHORT nFlags = SHORT1FROMMP( nMP1 );
+ USHORT nModCode = 0;
+ USHORT nSVCode = 0;
+ USHORT nOS2KeyCode = (UCHAR)SHORT2FROMMP( nMP2 );
+ xub_Unicode nSVCharCode = 0;
+ long nRet = 0;
+
+ // determine modifiers
+ if ( nFlags & KC_SHIFT )
+ nModCode |= KEY_SHIFT;
+ if ( nFlags & KC_CTRL )
+ nModCode |= KEY_MOD1;
+ if ( nFlags & KC_ALT )
+ {
+ nModCode |= KEY_MOD2;
+ // Nur wenn nicht Control und kein auswertbarer CharCode
+ // Wegen AltGr (vorallem wegen 122-Tastaturen auch KC_CHAR testen)
+ if ( !(nModCode & KEY_MOD1) && !(nFlags & KC_CHAR) )
+ nModCode |= KEY_CONTROLMOD;
+ }
+
+ // Bei Shift, Control und Alt schicken wir einen KeyModChange-Event
+ if ( (nOS2KeyCode == VK_SHIFT) || (nOS2KeyCode == VK_CTRL) ||
+ (nOS2KeyCode == VK_ALT) || (nOS2KeyCode == VK_ALTGRAF) )
+ {
+ SalKeyModEvent aModEvt;
+ aModEvt.mnTime = WinQueryMsgTime( pFrame->maFrameData.mhAB );
+ aModEvt.mnCode = nModCode;
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYMODCHANGE, &aModEvt );
+ }
+ else
+ {
+ ImplConvertKey( nMP1, nMP2, nSVCode, nSVCharCode );
+
+ // Fuer Java muessen wir bei KeyUp einen CharCode liefern
+ if ( nFlags & KC_KEYUP )
+ {
+ if ( !nSVCharCode )
+ {
+ if ( nLastOS2KeyChar == nOS2KeyCode )
+ {
+ nSVCharCode = nLastChar;
+ nLastOS2KeyChar = 0;
+ nLastChar = 0;
+ }
+ }
+ else
+ {
+ nLastOS2KeyChar = 0;
+ nLastChar = 0;
+ }
+ }
+ else
+ {
+ nLastOS2KeyChar = nOS2KeyCode;
+ nLastChar = nSVCharCode;
+ }
+
+ if ( nSVCode || nSVCharCode )
+ {
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnCode = nSVCode;
+ aKeyEvt.mnTime = WinQueryMsgTime( pFrame->maFrameData.mhAB );
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = nSVCharCode;
+ aKeyEvt.mnRepeat = nRepeat;
+
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ (nFlags & KC_KEYUP) ? SALEVENT_KEYUP : SALEVENT_KEYINPUT,
+ &aKeyEvt );
+ }
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandlePaintMsg( SalFrame* pFrame )
+{
+ HPS hPS;
+ RECTL aRect;
+
+ hPS = WinBeginPaint( pFrame->maFrameData.mhWndClient, NULLHANDLE, &aRect );
+
+ // convert rectangle sys -> sal
+ aRect.yTop = pFrame->maFrameData.mnHeight - aRect.yTop;
+ aRect.yBottom = pFrame->maFrameData.mnHeight - aRect.yBottom;
+
+ // Paint
+ SalPaintEvent aPEvt;
+ aPEvt.mnBoundX = aRect.xLeft;
+ aPEvt.mnBoundY = aRect.yTop;
+ aPEvt.mnBoundWidth = aRect.xRight - aRect.xLeft;
+ aPEvt.mnBoundHeight = aRect.yBottom - aRect.yTop;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_PAINT, &aPEvt );
+
+ WinEndPaint( hPS );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleMoveMsg( SalFrame* pFrame )
+{
+ pFrame->maFrameData.mbDefPos = FALSE;
+
+ // Gegen moegliche Rekursionen sichern
+ if ( !pFrame->maFrameData.mbInMoveMsg )
+ {
+ // Fenster im FullScreenModus wieder einpassen
+ pFrame->maFrameData.mbInMoveMsg = TRUE;
+ if ( pFrame->maFrameData.mbFullScreen )
+ ImplSalFrameFullScreenPos( pFrame );
+ pFrame->maFrameData.mbInMoveMsg = FALSE;
+ }
+
+ // Status merken
+ ImplSaveFrameState( pFrame );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleSizeMsg( SalFrame* pFrame, MPARAM nMP2 )
+{
+ pFrame->maFrameData.mbDefPos = FALSE;
+ pFrame->maFrameData.mnWidth = (short)SHORT1FROMMP( nMP2 );
+ pFrame->maFrameData.mnHeight = (short)SHORT2FROMMP( nMP2 );
+ if ( pFrame->maFrameData.mpGraphics )
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mnHeight = (int)SHORT2FROMMP(nMP2);
+ // Status merken
+ ImplSaveFrameState( pFrame );
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_RESIZE, 0 );
+ if ( WinIsWindowVisible( pFrame->maFrameData.mhWndFrame ) && !pFrame->maFrameData.mbInShow )
+ WinUpdateWindow( pFrame->maFrameData.mhWndClient );
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleShowMsg( SalFrame* pFrame, MPARAM nMP1 )
+{
+ if ( !pFrame->maFrameData.mbInShow )
+ {
+ // Wenn wir von aussen gehidet/geshowed werden (beispielsweise
+ // Hide-Button oder Taskleiste), loesen wir einen Resize mit 0,0 aus,
+ // damit Dialoge trotzdem als System-Fenster angezeigt werden, oder
+ // lehnen das Show ab
+ if ( SHORT1FROMMP( nMP1 ) )
+ {
+ // Show ablehen, wenn wir garnicht sichtbar sind
+ if ( !pFrame->maFrameData.mbVisible )
+ {
+ pFrame->maFrameData.mbInShow = TRUE;
+ WinSetWindowPos( pFrame->maFrameData.mhWndFrame, 0, 0, 0, 0, 0, SWP_HIDE );
+ pFrame->maFrameData.mbInShow = FALSE;
+ }
+ else
+ {
+ // Resize ausloesen, damit alter Status wieder
+ // hergestellt wird
+ pFrame->maFrameData.mbMinHide = FALSE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_RESIZE, 0 );
+ }
+ }
+ else
+ {
+ // Resize ausloesen, damit VCL mitbekommt, das Fenster
+ // gehidet ist, bzw. keine Groesse mehr hat
+ pFrame->maFrameData.mbMinHide = TRUE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_RESIZE, 0 );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleFocusMsg( SalFrame* pFrame, MPARAM nMP2 )
+{
+ if ( SHORT1FROMMP( nMP2 ) )
+ {
+ if ( WinIsWindowVisible( pFrame->maFrameData.mhWndFrame ) && !pFrame->maFrameData.mbInShow )
+ WinUpdateWindow( pFrame->maFrameData.mhWndClient );
+ return pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_GETFOCUS, 0 );
+ }
+ else
+ {
+ return pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_LOSEFOCUS, 0 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleCloseMsg( SalFrame* pFrame )
+{
+ return pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_CLOSE, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+inline void ImplHandleUserEvent( SalFrame* pFrame, MPARAM nMP2 )
+{
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_USEREVENT, (void*)nMP2 );
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef ENABLE_IME
+
+static long ImplHandleIMEStartConversion( SalFrame* pFrame )
+{
+ long nRet = FALSE;
+ SalIMEData* pIMEData = GetSalIMEData();
+ if ( pIMEData )
+ {
+ HWND hWnd = pFrame->maFrameData.mhWndClient;
+ HIMI hIMI = 0;
+ pIMEData->mpGetIME( hWnd, &hIMI );
+ if ( hIMI )
+ {
+ PM_ULONG nProp;
+ if ( 0 != pIMEData->mpQueryIMEProperty( hIMI, QIP_PROPERTY, &nProp ) )
+ pFrame->maFrameData.mbHandleIME = FALSE;
+ else
+ {
+ pFrame->maFrameData.mbHandleIME = !(nProp & PRP_SPECIALUI);
+
+ }
+ if ( pFrame->maFrameData.mbHandleIME )
+ {
+/* Windows-Code, der noch nicht angepasst wurde !!!
+ // Cursor-Position ermitteln und aus der die Default-Position fuer
+ // das Composition-Fenster berechnen
+ SalCursorPosEvent aCursorPosEvt;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_CURSORPOS, (void*)&aCursorPosEvt );
+ COMPOSITIONFORM aForm;
+ memset( &aForm, 0, sizeof( aForm ) );
+ if ( !aCursorPosEvt.mnWidth || !aCursorPosEvt.mnHeight )
+ aForm.dwStyle |= CFS_DEFAULT;
+ else
+ {
+ aForm.dwStyle |= CFS_POINT;
+ aForm.ptCurrentPos.x = aCursorPosEvt.mnX;
+ aForm.ptCurrentPos.y = aCursorPosEvt.mnY;
+ }
+ ImmSetCompositionWindow( hIMC, &aForm );
+
+ // Den InputContect-Font ermitteln und diesem dem Composition-Fenster
+ // bekannt machen
+*/
+
+ pFrame->maFrameData.mbConversionMode = TRUE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_STARTEXTTEXTINPUT, (void*)NULL );
+ nRet = TRUE;
+ }
+
+ pIMEData->mpReleaseIME( hWnd, hIMI );
+ }
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleIMEConversion( SalFrame* pFrame, MPARAM nMP2Param )
+{
+ long nRet = FALSE;
+ SalIMEData* pIMEData = GetSalIMEData();
+ if ( pIMEData )
+ {
+ HWND hWnd = pFrame->maFrameData.mhWndClient;
+ HIMI hIMI = 0;
+ PM_ULONG nMP2 = (PM_ULONG)nMP2Param;
+ pIMEData->mpGetIME( hWnd, &hIMI );
+ if ( hIMI )
+ {
+ if ( nMP2 & (IMR_RESULT_RESULTSTRING |
+ IMR_CONV_CONVERSIONSTRING | IMR_CONV_CONVERSIONATTR |
+ IMR_CONV_CURSORPOS | IMR_CONV_CURSORATTR) )
+ {
+ SalExtTextInputEvent aEvt;
+ aEvt.mnTime = WinQueryMsgTime( pFrame->maFrameData.mhAB );
+ aEvt.mpTextAttr = NULL;
+ aEvt.mnCursorPos = 0;
+ aEvt.mnDeltaStart = 0;
+ aEvt.mbOnlyCursor = FALSE;
+ aEvt.mbCursorVisible = TRUE;
+
+ PM_ULONG nBufLen = 0;
+ xub_Unicode* pBuf = NULL;
+ PM_ULONG nAttrBufLen = 0;
+ PM_BYTE* pAttrBuf = NULL;
+ BOOL bLastCursor = FALSE;
+ if ( nMP2 & IMR_RESULT_RESULTSTRING )
+ {
+ pIMEData->mpGetResultString( hIMI, IMR_RESULT_RESULTSTRING, 0, &nBufLen );
+ if ( nBufLen > 0 )
+ {
+ pBuf = new xub_Unicode[nBufLen];
+ pIMEData->mpGetResultString( hIMI, IMR_RESULT_RESULTSTRING, pBuf, &nBufLen );
+ }
+
+ bLastCursor = TRUE;
+ aEvt.mbCursorVisible = TRUE;
+ }
+ else if ( nMP2 & (IMR_CONV_CONVERSIONSTRING | IMR_CONV_CONVERSIONATTR |
+ IMR_CONV_CURSORPOS | IMR_CONV_CURSORATTR) )
+ {
+ pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, 0, &nBufLen );
+ if ( nBufLen > 0 )
+ {
+ pBuf = new xub_Unicode[nBufLen];
+ pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, pBuf, &nBufLen );
+ }
+
+ pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONATTR, 0, &nAttrBufLen );
+ if ( nAttrBufLen > 0 )
+ {
+ pAttrBuf = new PM_BYTE[nAttrBufLen];
+ pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONATTR, pAttrBuf, &nAttrBufLen );
+ }
+
+/* !!! Wir bekommen derzeit nur falsche Daten, deshalb zeigen wir derzeit
+ !!! auch keine Cursor an
+ PM_ULONG nTempBufLen;
+ PM_ULONG nCursorPos = 0;
+ PM_ULONG nCursorAttr = 0;
+ PM_ULONG nChangePos = 0;
+ nTempBufLen = sizeof( PM_ULONG );
+ pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORPOS, &nCursorPos, &nTempBufLen );
+ nTempBufLen = sizeof( PM_ULONG );
+ pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORATTR, &nCursorAttr, &nTempBufLen );
+ nTempBufLen = sizeof( PM_ULONG );
+ pIMEData->mpGetConversionString( hIMI, IMR_CONV_CHANGESTART, &nChangePos, &nTempBufLen );
+
+ aEvt.mnCursorPos = nCursorPos;
+ aEvt.mnDeltaStart = nChangePos;
+ if ( nCursorAttr & CP_CURSORATTR_INVISIBLE )
+ aEvt.mbCursorVisible = FALSE;
+*/
+ aEvt.mnCursorPos = 0;
+ aEvt.mnDeltaStart = 0;
+ aEvt.mbCursorVisible = FALSE;
+
+ if ( (nMP2 == IMR_CONV_CURSORPOS) ||
+ (nMP2 == IMR_CONV_CURSORATTR) )
+ aEvt.mbOnlyCursor = TRUE;
+ }
+
+ USHORT* pSalAttrAry = NULL;
+ if ( pBuf )
+ {
+ aEvt.maText = XubString( pBuf, (USHORT)nBufLen );
+ delete pBuf;
+ if ( pAttrBuf )
+ {
+ USHORT nTextLen = aEvt.maText.Len();
+ if ( nTextLen )
+ {
+ pSalAttrAry = new USHORT[nTextLen];
+ memset( pSalAttrAry, 0, nTextLen*sizeof( USHORT ) );
+ for ( USHORT i = 0; (i < nTextLen) && (i < nAttrBufLen); i++ )
+ {
+ PM_BYTE nOS2Attr = pAttrBuf[i];
+ USHORT nSalAttr;
+ if ( nOS2Attr == CP_ATTR_TARGET_CONVERTED )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETCONVERTED | SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
+ else if ( nOS2Attr == CP_ATTR_CONVERTED )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_CONVERTED | SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE;
+ else if ( nOS2Attr == CP_ATTR_TARGET_NOTCONVERTED )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETNOTCONVERTED | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ else if ( nOS2Attr == CP_ATTR_INPUT_ERROR )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUTERROR | SAL_EXTTEXTINPUT_ATTR_REDTEXT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ else /* ( nOS2Attr == CP_ATTR_INPUT ) */
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ pSalAttrAry[i] = nSalAttr;
+ }
+ aEvt.mpTextAttr = pSalAttrAry;
+ }
+ delete pAttrBuf;
+ }
+ if ( bLastCursor )
+ aEvt.mnCursorPos = aEvt.maText.Len();
+ }
+
+ pIMEData->mpReleaseIME( hWnd, hIMI );
+
+ // Handler rufen und wenn wir ein Attribute-Array haben, danach
+ // wieder zerstoeren
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_EXTTEXTINPUT, (void*)&aEvt );
+ if ( pSalAttrAry )
+ delete pSalAttrAry;
+ }
+ else
+ pIMEData->mpReleaseIME( hWnd, hIMI );
+ }
+
+ nRet = TRUE;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleIMEEndConversion( SalFrame* pFrame )
+{
+ pFrame->maFrameData.mbConversionMode = FALSE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_ENDEXTTEXTINPUT, (void*)NULL );
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleIMEOpenCandidate( SalFrame* pFrame )
+{
+ pFrame->maFrameData.mbCandidateMode = TRUE;
+
+ long nRet = FALSE;
+ SalIMEData* pIMEData = GetSalIMEData();
+ if ( pIMEData )
+ {
+ HWND hWnd = pFrame->maFrameData.mhWndClient;
+ HIMI hIMI = 0;
+ pIMEData->mpGetIME( hWnd, &hIMI );
+ if ( hIMI )
+ {
+ PM_ULONG nBufLen = 0;
+ pIMEData->mpGetConversionString( hIMI, IMR_CONV_CONVERSIONSTRING, 0, &nBufLen );
+ if ( nBufLen > 0 )
+ {
+/* !!! Wir bekommen derzeit nur falsche Daten steht der Cursor immer bei 0
+ PM_ULONG nTempBufLen = sizeof( PM_ULONG );
+ PM_ULONG nCursorPos = 0;
+ pIMEData->mpGetConversionString( hIMI, IMR_CONV_CURSORPOS, &nCursorPos, &nTempBufLen );
+*/
+ PM_ULONG nCursorPos = 0;
+
+ SalExtTextInputPosEvent aEvt;
+ aEvt.mnTime = WinQueryMsgTime( pFrame->maFrameData.mhAB );
+ aEvt.mnFirstPos = nCursorPos;
+ aEvt.mnChars = nBufLen-nCursorPos;
+ aEvt.mpPosAry = new SalExtCharPos[aEvt.mnChars];
+ memset( aEvt.mpPosAry, 0, aEvt.mnChars*sizeof(SalExtCharPos) );
+
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_EXTTEXTINPUTPOS, (void*)&aEvt );
+
+ long nMinLeft = aEvt.mpPosAry[0].mnX;
+ long nMinTop = aEvt.mpPosAry[0].mnY;
+ long nMaxBottom = aEvt.mpPosAry[0].mnY+aEvt.mpPosAry[0].mnHeight;
+ long nMaxRight = nMinLeft;
+ USHORT i = 0;
+ while ( i < aEvt.mnChars )
+ {
+ // Solange wir uns auf der gleichen Zeile bewegen,
+ // ermitteln wir die Rechteck-Grenzen
+ if ( !aEvt.mpPosAry[i].mnHeight ||
+ (aEvt.mpPosAry[i].mnY < nMaxBottom-1) )
+ {
+ if ( aEvt.mpPosAry[i].mnX < nMinLeft )
+ nMinLeft = aEvt.mpPosAry[i].mnX;
+ if ( aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth > nMaxRight )
+ nMaxRight = aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth;
+ if ( aEvt.mpPosAry[i].mnY < nMinTop )
+ nMinTop = aEvt.mpPosAry[i].mnY;
+ i++;
+ }
+ else
+ break;
+ }
+
+ CANDIDATEPOS aForm;
+ aForm.ulIndex = 0;
+ aForm.ulStyle = CPS_EXCLUDE;
+ aForm.ptCurrentPos.x = aEvt.mpPosAry[0].mnX;
+ aForm.ptCurrentPos.y = pFrame->maFrameData.mnHeight - (nMaxBottom+1) - 1;
+ aForm.rcArea.xLeft = nMinLeft;
+ aForm.rcArea.yBottom = pFrame->maFrameData.mnHeight - nMaxBottom - 1;
+ aForm.rcArea.xRight = nMaxRight+1;
+ aForm.rcArea.yTop = pFrame->maFrameData.mnHeight - nMinTop - 1;
+ pIMEData->mpSetCandidateWin( hIMI, &aForm );
+
+ delete aEvt.mpPosAry;
+ }
+
+ pIMEData->mpReleaseIME( hWnd, hIMI );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline void ImplHandleIMECloseCandidate( SalFrame* pFrame )
+{
+ pFrame->maFrameData.mbCandidateMode = FALSE;
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+MRESULT EXPENTRY SalFrameWndProc( HWND hWnd, PM_ULONG nMsg,
+ MPARAM nMP1, MPARAM nMP2 )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ MRESULT nRet = (MRESULT)0;
+ BOOL bDef = TRUE;
+
+ switch( nMsg )
+ {
+ case WM_MOUSEMOVE:
+ case WM_BUTTON1DOWN:
+ case WM_BUTTON2DOWN:
+ case WM_BUTTON3DOWN:
+ case WM_BUTTON1DBLCLK:
+ case WM_BUTTON2DBLCLK:
+ case WM_BUTTON3DBLCLK:
+ case WM_BUTTON1UP:
+ case WM_BUTTON2UP:
+ case WM_BUTTON3UP:
+ case SAL_MSG_MOUSELEAVE:
+ // ButtonUp/Down nie an die WinDefWindowProc weiterleiten, weil sonst
+ // die Message an den Owner weitergeleitet wird
+ bDef = !ImplHandleMouseMsg( pFrame, nMsg, nMP1, nMP2 );
+ break;
+
+ case WM_CHAR:
+ if ( pFrame->maFrameData.mbConversionMode )
+ bDef = FALSE;
+ else
+ bDef = !ImplHandleKeyMsg( pFrame, nMsg, nMP1, nMP2 );
+ break;
+
+ case WM_ERASEBACKGROUND:
+ nRet = (MRESULT)FALSE;
+ bDef = FALSE;
+ break;
+
+ case WM_PAINT:
+ ImplSalYieldMutexAcquire();
+ ImplHandlePaintMsg( pFrame );
+ ImplSalYieldMutexRelease();
+ bDef = FALSE;
+ break;
+
+ case WM_TIMER:
+ {
+ SalData* pSalData = GetSalData();
+ // Test for MouseLeave
+ SalTestMouseLeave();
+ if ( pSalData->mnTimerId == SHORT1FROMMP( nMP1 ) )
+ pSalData->mpTimerProc();
+ }
+ break;
+
+ case WM_MOVE:
+ ImplHandleMoveMsg( pFrame );
+ bDef = FALSE;
+ break;
+
+ case WM_SIZE:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ ImplHandleSizeMsg( pFrame, nMP2 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ WinPostMsg( hWnd, SAL_MSG_POSTSIZE, nMP1, nMP2 );
+ break;
+ case SAL_MSG_POSTSIZE:
+ ImplHandleSizeMsg( pFrame, nMP2 );
+ break;
+
+ case WM_CALCVALIDRECTS:
+ return (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
+
+ case WM_SETFOCUS:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ ImplHandleFocusMsg( pFrame, nMP2 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ WinPostMsg( hWnd, SAL_MSG_POSTFOCUS, 0, nMP2 );
+ break;
+ case SAL_MSG_POSTFOCUS:
+ ImplHandleFocusMsg( pFrame, nMP2 );
+ break;
+
+ case WM_TRANSLATEACCEL:
+ {
+ // Da uns OS/2 zu viele Tasten abfaegnt, unternehmen wir etwas,
+ // damit wir Shift+F1, Shift+F10 und Shift+Enter bekommen
+ PQMSG pMsg = (PQMSG)nMP1;
+ USHORT nKeyFlags = SHORT1FROMMP( pMsg->mp1 );
+ USHORT nKeyCode = (UCHAR)SHORT2FROMMP( pMsg->mp2 );
+
+ if ( !(nKeyFlags & KC_KEYUP) && (nKeyFlags & KC_VIRTUALKEY) &&
+ (nKeyFlags & KC_SHIFT) && (nKeyCode != VK_ESC) )
+ return (MRESULT)FALSE;
+
+ if ( nKeyCode == VK_F1 )
+ return (MRESULT)FALSE;
+ }
+ break;
+
+ case WM_CREATE:
+ {
+ SalData* pSalData = GetSalData();
+ // Window-Instanz am Windowhandle speichern
+ pFrame = pSalData->mpCreateFrame;
+ pSalData->mpCreateFrame = NULL;
+ SetWindowPtr( hWnd, pFrame );
+ }
+ break;
+
+ case WM_CLOSE:
+ ImplSalYieldMutexAcquire();
+ ImplHandleCloseMsg( pFrame );
+ ImplSalYieldMutexRelease();
+ bDef = FALSE;
+ break;
+
+ case WM_SYSVALUECHANGED:
+ if ( pFrame->maFrameData.mbFullScreen )
+ ImplSalFrameFullScreenPos( pFrame );
+ // kein break, da der Rest auch noch verarbeitet werden soll
+ case PL_ALTERED:
+ case WM_SYSCOLORCHANGE:
+ ImplSalYieldMutexAcquire();
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_SETTINGSCHANGED, 0 );
+ ImplSalYieldMutexRelease();
+ break;
+
+ case SAL_MSG_USEREVENT:
+ ImplHandleUserEvent( pFrame, nMP2 );
+ bDef = FALSE;
+ break;
+
+ case WM_COMMAND:
+ case SAL_MSG_SYSPROCESSMENU:
+ if ( SalImplHandleProcessMenu( hWnd, nMsg, nMP1, nMP2 ) )
+ {
+ bDef = FALSE;
+ nRet = (MRESULT)1;
+ }
+ break;
+
+#ifdef ENABLE_IME
+ case WM_IMEREQUEST:
+ if ( (PM_ULONG)nMP1 == IMR_CONVRESULT )
+ {
+ if ( pFrame->maFrameData.mbHandleIME )
+ {
+ // Nur im Conversionmodus akzeptieren wir den IME-Input
+ if ( pFrame->maFrameData.mbConversionMode )
+ {
+ ImplSalYieldMutexAcquire();
+ if ( ImplHandleIMEConversion( pFrame, nMP2 ) )
+ {
+ bDef = FALSE;
+ nRet = (MRESULT)TRUE;
+ }
+ ImplSalYieldMutexRelease();
+ }
+ }
+ }
+ else if ( (PM_ULONG)nMP1 == IMR_CANDIDATE )
+ {
+ if ( pFrame->maFrameData.mbHandleIME )
+ {
+ ImplSalYieldMutexAcquire();
+ if ( (PM_ULONG)nMP2 & IMR_CANDIDATE_SHOW )
+ ImplHandleIMEOpenCandidate( pFrame );
+ else if ( (PM_ULONG)nMP2 & IMR_CANDIDATE_HIDE )
+ ImplHandleIMECloseCandidate( pFrame );
+ ImplSalYieldMutexRelease();
+ }
+ }
+ break;
+
+ case WM_IMENOTIFY:
+ if ( (PM_ULONG)nMP1 == IMN_STARTCONVERSION )
+ {
+ ImplSalYieldMutexAcquire();
+ if ( ImplHandleIMEStartConversion( pFrame ) )
+ {
+ bDef = FALSE;
+ nRet = (MRESULT)TRUE;
+ }
+ ImplSalYieldMutexRelease();
+ }
+ else if ( (PM_ULONG)nMP1 == IMN_ENDCONVERSION )
+ {
+ if ( pFrame->maFrameData.mbHandleIME )
+ {
+ ImplSalYieldMutexAcquire();
+ if ( ImplHandleIMEEndConversion( pFrame ) )
+ {
+ bDef = FALSE;
+ nRet = (MRESULT)TRUE;
+ }
+ ImplSalYieldMutexRelease();
+ }
+ }
+ break;
+#endif
+ }
+
+ if ( bDef )
+ nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+MRESULT EXPENTRY SalFrameFrameProc( HWND hWnd, PM_ULONG nMsg,
+ MPARAM nMP1, MPARAM nMP2 )
+{
+ if ( nMsg == WM_SYSCOMMAND )
+ {
+ HWND hWndClient = WinWindowFromID( hWnd, FID_CLIENT );
+ if( hWndClient )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWndClient );
+ if ( pFrame )
+ {
+ USHORT nCmd = SHORT1FROMMP( nMP1 );
+ if ( pFrame->maFrameData.mbFullScreen )
+ {
+ if ( (nCmd == SC_SIZE) || (nCmd == SC_MOVE) ||
+ (nCmd == SC_RESTORE) ||
+ (nCmd == SC_MINIMIZE) || (nCmd == SC_MAXIMIZE) )
+ {
+ WinAlarm( HWND_DESKTOP, WA_NOTE );
+ return 0;
+ }
+ }
+
+ if ( nCmd == SC_APPMENU )
+ {
+ // KeyInput mit MENU-Key rufen
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = WinQueryMsgTime( pFrame->maFrameData.mhAB );
+ aKeyEvt.mnCode = KEY_MENU;
+ aKeyEvt.mnCharCode = 0;
+ aKeyEvt.mnRepeat = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ if ( nRet )
+ return (MRESULT)0;
+ }
+ }
+ }
+ }
+ else if ( nMsg == WM_SHOW )
+ {
+ HWND hWndClient = WinWindowFromID( hWnd, FID_CLIENT );
+ if( hWndClient )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWndClient );
+ if ( pFrame )
+ ImplHandleShowMsg( pFrame, nMP1 );
+ }
+ }
+
+ return aSalShlData.mpOldFrameProc( hWnd, nMsg, nMP1, nMP2 );
+}
diff --git a/vcl/os2/source/window/salobj.cxx b/vcl/os2/source/window/salobj.cxx
new file mode 100644
index 000000000000..a5023e3e4301
--- /dev/null
+++ b/vcl/os2/source/window/salobj.cxx
@@ -0,0 +1,605 @@
+/*************************************************************************
+ *
+ * $RCSfile: salobj.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <tools/svpm.h>
+
+#define _SV_SALOBJ_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+
+// =======================================================================
+
+static BOOL ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild )
+{
+ if ( hWndParent == hWndChild )
+ return TRUE;
+
+ HWND hTempWnd = WinQueryWindow( hWndChild, QW_PARENT );
+ while ( hTempWnd )
+ {
+ if ( hTempWnd == hWndParent )
+ return TRUE;
+ hTempWnd = WinQueryWindow( hTempWnd, QW_PARENT );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static SalObject* ImplFindSalObject( HWND hWndChild )
+{
+ SalData* pSalData = GetSalData();
+ SalObject* pObject = pSalData->mpFirstObject;
+ while ( pObject )
+ {
+ if ( ImplIsSysWindowOrChild( pObject->maObjectData.mhWndChild, hWndChild ) )
+ return pObject;
+
+ pObject = pObject->maObjectData.mpNextObject;
+ }
+
+ return NULL;
+}
+
+// =======================================================================
+
+PM_BOOL EXPENTRY SalSysMsgProc( HAB /* hAB */, QMSG* pMsg, PM_ULONG /* fs */ )
+{
+ if ( (pMsg->msg == WM_BUTTON1DOWN) ||
+ (pMsg->msg == WM_BUTTON2DOWN) ||
+ (pMsg->msg == WM_BUTTON3DOWN) )
+ {
+ SalData* pSalData = GetSalData();
+ SalObject* pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ WinPostMsg( pObject->maObjectData.mhWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ }
+
+ // Focus fangen wir hier nicht ab, da wir erstmal davon ausgehen,
+ // das unser SalObject-Fenster immer eine WM_FOCUSCHANGE-Message
+ // bekommt.
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+MRESULT EXPENTRY SalSysObjWndProc( HWND hWnd, PM_ULONG nMsg,
+ MPARAM nMP1, MPARAM nMP2 )
+{
+ SalObject* pSysObj;
+ MRESULT nRet = 0;
+ int bDef = TRUE;
+
+ switch( nMsg )
+ {
+ case WM_ERASEBACKGROUND:
+ nRet = (MRESULT)FALSE;
+ bDef = FALSE;
+ break;
+ case WM_PAINT:
+ {
+ HPS hPS;
+ RECTL aRect;
+ hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect );
+ WinEndPaint( hPS );
+ bDef = FALSE;
+ }
+ bDef = FALSE;
+ break;
+
+ case WM_BUTTON1DOWN:
+ case WM_BUTTON2DOWN:
+ case WM_BUTTON3DOWN:
+ case SALOBJ_MSG_TOTOP:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj,
+ SALOBJ_EVENT_TOTOP, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ WinPostMsg( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ break;
+
+ case WM_FOCUSCHANGE:
+ case SALOBJ_MSG_POSTFOCUS:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ if ( SHORT1FROMMP( nMP2 ) )
+ {
+ pSysObj->maObjectData.mhLastFocusWnd = WinQueryFocus( HWND_DESKTOP );
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj,
+ SALOBJ_EVENT_GETFOCUS, 0 );
+ }
+ else
+ {
+ HWND hWndFocus = HWNDFROMMP( nMP1 );
+ if ( !hWndFocus || !ImplIsSysWindowOrChild( hWnd, hWndFocus ) )
+ {
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj,
+ SALOBJ_EVENT_LOSEFOCUS, 0 );
+ }
+ }
+ ImplSalYieldMutexRelease();
+ }
+ else
+ WinPostMsg( hWnd, SALOBJ_MSG_POSTFOCUS, nMP1, nMP2 );
+ break;
+
+ case WM_SIZE:
+ {
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ pSysObj->maObjectData.mnHeight = (short)SHORT2FROMMP( nMP2 );
+ WinSetWindowPos( pSysObj->maObjectData.mhWndChild, 0,
+ 0, 0,
+ (short)SHORT1FROMMP( nMP2 ), (short)SHORT2FROMMP( nMP2 ),
+ SWP_SIZE | SWP_MOVE );
+ bDef = FALSE;
+ }
+ break;
+
+ case WM_CREATE:
+ {
+ // Window-Instanz am Windowhandle speichern
+ CREATESTRUCT* pStruct = (CREATESTRUCT*)nMP2;
+ pSysObj = (SalObject*)pStruct->pPresParams;
+ SetSalObjWindowPtr( hWnd, pSysObj );
+ bDef = FALSE;
+ }
+ break;
+ }
+
+ if ( bDef )
+ nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+MRESULT EXPENTRY SalSysObjChildWndProc( HWND hWnd, PM_ULONG nMsg,
+ MPARAM nMP1, MPARAM nMP2 )
+{
+ MRESULT nRet = 0;
+ int bDef = TRUE;
+
+ switch( nMsg )
+ {
+ case WM_ERASEBACKGROUND:
+ // Wegen PlugIn's loeschen wir erstmal den Hintergrund
+/*
+ nRet = (MRESULT)FALSE;
+ bDef = FALSE;
+*/
+ break;
+ case WM_PAINT:
+ {
+ HPS hPS;
+ RECTL aRect;
+ hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect );
+ WinEndPaint( hPS );
+ bDef = FALSE;
+ }
+ break;
+ }
+
+ if ( bDef )
+ nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+MRESULT EXPENTRY SalSysObjClipWndProc( HWND hWnd, PM_ULONG nMsg,
+ MPARAM nMP1, MPARAM nMP2 )
+{
+ MRESULT nRet = 0;
+ int bDef = TRUE;
+
+ switch( nMsg )
+ {
+ case WM_MOUSEMOVE:
+ case WM_BUTTON1DOWN:
+ case WM_BUTTON2DOWN:
+ case WM_BUTTON3DOWN:
+ case WM_BUTTON1DBLCLK:
+ case WM_BUTTON2DBLCLK:
+ case WM_BUTTON3DBLCLK:
+ case WM_BUTTON1UP:
+ case WM_BUTTON2UP:
+ case WM_BUTTON3UP:
+ {
+ // Alle Events an den Frame weiterreichen, da diese Bereiche
+ // dem Frame gehoeren. Dazu muessen die Mouse-Koordinaaten
+ // entsprechend umgerechnet werden
+ HWND hWndParent = WinQueryWindow( hWnd, QW_PARENT ); // ergibt SysChild-Fenster
+ hWndParent = WinQueryWindow( hWndParent, QW_PARENT );
+ short nX = (short)SHORT1FROMMP( nMP1 );
+ short nY = (short)SHORT2FROMMP( nMP1 );
+ POINTL aPos;
+ aPos.x = nX;
+ aPos.y = nY;
+ WinMapWindowPoints( hWnd, hWndParent, &aPos, 1 );
+ nMP1 = MPFROM2SHORT( (short)aPos.x, (short)aPos.y );
+ bDef = FALSE;
+ nRet = WinSendMsg( hWndParent, nMsg, nMP1, nMP2 );
+ }
+ break;
+
+ case WM_HITTEST:
+ // Damit im disablten Zustand die MouseKlicks immer noch
+ // an den Frame geschickt werden
+ // Dieser Code reicht leider nicht aus, deshalb wir unter
+ // OS2 immer das Child-Fenster disablen, im Gegensatz
+ // zu Windows, wo immer der Parent disablte wird, da
+ // sich das Fenster evtl. anders Darstellen koennte,
+ // wenn es disablte wird. Da dieser Fall uns bisher
+ // nicht bekannt ist, ignorieren wir das.
+ nRet = HT_NORMAL;
+ bDef = FALSE;
+ break;
+
+ case WM_ERASEBACKGROUND:
+ nRet = (MRESULT)FALSE;
+ bDef = FALSE;
+ break;
+ case WM_PAINT:
+ {
+ HPS hPS;
+ RECTL aRect;
+ hPS = WinBeginPaint( hWnd, NULLHANDLE, &aRect );
+ WinEndPaint( hPS );
+ bDef = FALSE;
+ }
+ break;
+ }
+
+ if ( bDef )
+ nRet = WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
+ return nRet;
+}
+
+// =======================================================================
+
+void ImplDestroyAllClipWindows( HWND hWndLast )
+{
+ if ( hWndLast == HWND_TOP )
+ return;
+
+ HWND hWndPrev;
+ while ( hWndLast )
+ {
+ hWndPrev = WinQueryWindow( hWndLast, QW_PREV );
+ WinDestroyWindow( hWndLast );
+ hWndLast = hWndPrev;
+ }
+}
+
+// =======================================================================
+
+SalObject* ImplSalCreateObject( SalInstance* pInst, SalFrame* pParent )
+{
+ SalData* pSalData = GetSalData();
+
+ if ( !pSalData->mbObjClassInit )
+ {
+ if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CLASSNAME,
+ (PFNWP)SalSysObjWndProc, CS_MOVENOTIFY,
+ SAL_OBJECT_WNDEXTRA ) )
+ {
+ if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CLIPCLASSNAME,
+ (PFNWP)SalSysObjClipWndProc, CS_HITTEST | CS_MOVENOTIFY, 0 ) )
+ {
+ if ( WinRegisterClass( pSalData->mhAB, (PSZ)SAL_OBJECT_CHILDCLASSNAME,
+ (PFNWP)SalSysObjChildWndProc, CS_HITTEST | CS_MOVENOTIFY, 32 ) )
+ pSalData->mbObjClassInit = TRUE;
+ }
+ }
+ }
+
+ if ( pSalData->mbObjClassInit )
+ {
+ SalObject* pObject = new SalObject;
+ HWND hWnd = WinCreateWindow( pParent->maFrameData.mhWndClient, SAL_OBJECT_CLASSNAME, "",
+ 0,
+ 0, 0, 0, 0,
+ pParent->maFrameData.mhWndClient, HWND_TOP,
+ 0, NULL, (void*)pObject );
+ HWND hWndChild = WinCreateWindow( hWnd, SAL_OBJECT_CHILDCLASSNAME, "",
+ WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
+ 0, 0, 0, 0,
+ hWnd, HWND_TOP,
+ 0, NULL, NULL );
+
+ if ( !hWndChild )
+ {
+ if ( hWnd )
+ WinDestroyWindow( hWnd );
+ delete pObject;
+ return NULL;
+ }
+
+ if ( hWnd )
+ {
+ pObject->maObjectData.mhWnd = hWnd;
+ pObject->maObjectData.mhWndChild = hWndChild;
+ pObject->maObjectData.maSysData.hWnd = hWndChild;
+ return pObject;
+ }
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyObject( SalObject* pObject )
+{
+ delete pObject;
+}
+
+// =======================================================================
+
+long ImplSalObjCallbackDummy( void*, SalObject*, USHORT, const void* )
+{
+ return 0;
+}
+
+// =======================================================================
+
+SalObject::SalObject()
+{
+ SalData* pSalData = GetSalData();
+
+ maObjectData.mhLastClipWnd = HWND_TOP;
+
+ maObjectData.mhWnd = 0;
+ maObjectData.mhWndChild = 0;
+ maObjectData.mhLastFocusWnd = 0;
+ maObjectData.maSysData.nSize = sizeof( SystemEnvData );
+ maObjectData.mnHeight = 0;
+ maObjectData.mpInst = NULL;
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+
+ // Hook installieren, wenn es das erste SalObject ist
+ if ( !pSalData->mpFirstObject )
+ {
+ WinSetHook( pSalData->mhAB, pSalData->mhMQ,
+ HK_INPUT, (PFN)SalSysMsgProc, (HMODULE)0 );
+ }
+
+ // Insert object in objectlist
+ maObjectData.mpNextObject = pSalData->mpFirstObject;
+ pSalData->mpFirstObject = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalObject::~SalObject()
+{
+ SalData* pSalData = GetSalData();
+
+ // remove frame from framelist
+ if ( this == pSalData->mpFirstObject )
+ {
+ pSalData->mpFirstObject = maObjectData.mpNextObject;
+
+ // Wenn letztes SalObject, dann Hook wieder entfernen
+ if ( !pSalData->mpFirstObject )
+ {
+ WinReleaseHook( pSalData->mhAB, pSalData->mhMQ,
+ HK_INPUT, (PFN)SalSysMsgProc, (HMODULE)0 );
+ }
+ }
+ else
+ {
+ SalObject* pTempObject = pSalData->mpFirstObject;
+ while ( pTempObject->maObjectData.mpNextObject != this )
+ pTempObject = pTempObject->maObjectData.mpNextObject;
+
+ pTempObject->maObjectData.mpNextObject = maObjectData.mpNextObject;
+ }
+
+ // Cache-Daten zerstoeren
+ ImplDestroyAllClipWindows( maObjectData.mhLastClipWnd );
+
+ if ( maObjectData.mhWndChild )
+ WinDestroyWindow( maObjectData.mhWndChild );
+ if ( maObjectData.mhWnd )
+ WinDestroyWindow( maObjectData.mhWnd );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::ResetClipRegion()
+{
+ ImplDestroyAllClipWindows( maObjectData.mhLastClipWnd );
+ maObjectData.mhLastClipWnd = HWND_TOP;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalObject::GetClipRegionType()
+{
+ return SAL_OBJECT_CLIP_EXCLUDERECTS;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::BeginSetClipRegion( ULONG nRectCount )
+{
+ maObjectData.mhOldLastClipWnd = maObjectData.mhLastClipWnd;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ HWND hClipWnd = WinCreateWindow( maObjectData.mhWnd, SAL_OBJECT_CLIPCLASSNAME, "",
+ WS_VISIBLE,
+ nX, maObjectData.mnHeight-(nY+nHeight), nWidth, nHeight,
+ maObjectData.mhWnd, maObjectData.mhLastClipWnd,
+ 0, NULL, NULL );
+ maObjectData.mhLastClipWnd = hClipWnd;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::EndSetClipRegion()
+{
+ ImplDestroyAllClipWindows( maObjectData.mhOldLastClipWnd );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
+{
+ PM_ULONG nStyle = 0;
+ PM_BOOL bVisible = WinIsWindowVisible( maObjectData.mhWnd );
+ if ( bVisible )
+ {
+ WinShowWindow( maObjectData.mhWnd, FALSE );
+ nStyle |= SWP_SHOW;
+ }
+ SWP aParentSWP;
+ WinQueryWindowPos( WinQueryWindow( maObjectData.mhWnd, QW_PARENT ), &aParentSWP );
+ WinSetWindowPos( maObjectData.mhWnd, 0, nX, aParentSWP.cy-(nY+nHeight), nWidth, nHeight,
+ SWP_MOVE | SWP_SIZE | nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::Show( BOOL bVisible )
+{
+ WinShowWindow( maObjectData.mhWnd, bVisible );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::Enable( BOOL bEnable )
+{
+ // Im Gegensatz zu Windows disablen wir das Childfenster,
+ // da ansonsten unser Clippen nicht mehr funktioniert, da
+ // wir keine Events mehr bekommen. Dadurch kann sich evtl.
+ // das Fenster anders darstellen, was wir eigentlich nicht
+ // wollen. Aber da uns bisher kein Fall bekannt ist,
+ // ignorieren wir dies. Ansonsten muss ein Fenster dazwischen
+ // gezogen werden oder getestet werden, wie wir die
+ // Maustransparenz erreichen, wenn maObjectData.mhWnd
+ // disablte wird.
+ WinEnableWindow( maObjectData.mhWndChild, bEnable );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::GrabFocus()
+{
+ if ( maObjectData.mhLastFocusWnd &&
+ WinIsWindow( GetSalData()->mhAB, maObjectData.mhLastFocusWnd ) &&
+ ImplIsSysWindowOrChild( maObjectData.mhWndChild, maObjectData.mhLastFocusWnd ) )
+ WinSetFocus( HWND_DESKTOP, maObjectData.mhLastFocusWnd );
+ else
+ WinSetFocus( HWND_DESKTOP, maObjectData.mhWndChild );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground( SalColor nSalColor )
+{
+}
+
+// -----------------------------------------------------------------------
+
+const SystemChildData* SalObject::GetSystemData() const
+{
+ return &maObjectData.maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc )
+{
+ maObjectData.mpInst = pInst;
+ if ( pProc )
+ maObjectData.mpProc = pProc;
+ else
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+}
diff --git a/vcl/prj/d.lst b/vcl/prj/d.lst
new file mode 100644
index 000000000000..d66650014ace
--- /dev/null
+++ b/vcl/prj/d.lst
@@ -0,0 +1,186 @@
+mkdir: %_DEST%\bin%_EXT%\remote
+mkdir: %_DEST%\idl%_EXT%\stardiv\remote
+mkdir: %_DEST%\idl%_EXT%\stardiv\system
+mkdir: %_DEST%\inc%_EXT%\sv
+mkdir: %_DEST%\inc%_EXT%\tools
+mkdir: %_DEST%\inc%_EXT%\uno
+mkdir: %_DEST%\inc%_EXT%\uno\awt
+mkdir: %_DEST%\inc%_EXT%\vcl
+mkdir: %_DEST%\inc%_EXT%\vcl\unx
+mkdir: %_DEST%\ucr%_EXT%
+mkdir: %_DEST%\ucr%_EXT%\vcl
+
+..\%__SRC%\bin\remote\vcl%upd%??.dll %_DEST%\bin%_EXT%\remote\vcl?????.dll
+..\%__SRC%\bin\vcl%UPD%??.res %_DEST%\bin%_EXT%\vcl%upd%??.res
+..\%__SRC%\bin\vcl%upd%??.dll %_DEST%\bin%_EXT%\vcl?????.dll
+..\%__SRC%\bin\vcl%upd%??.sym %_DEST%\bin%_EXT%\vcl?????.sym
+..\%__SRC%\lib\*.a %_DEST%\lib%_EXT%\*.a
+..\%__SRC%\lib\*.sl %_DEST%\lib%_EXT%\*.sl
+..\%__SRC%\lib\*.so %_DEST%\lib%_EXT%\*.so
+..\%__SRC%\lib\*.so.* %_DEST%\lib%_EXT%\*.so.*
+..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+..\%__SRC%\lib\app16.lib %_DEST%\lib%_EXT%\app16.lib
+..\%__SRC%\lib\gdi16.lib %_DEST%\lib%_EXT%\gdi16.lib
+..\%__SRC%\lib\isv.lib %_DEST%\lib%_EXT%\isv.lib
+..\%__SRC%\lib\ivcl.lib %_DEST%\lib%_EXT%\ivcl.lib
+..\%__SRC%\lib\remote\*.so %_DEST%\bin%_EXT%\remote\*.so
+..\%__SRC%\lib\remote\*.so %_DEST%\lib%_EXT%\remote\*.so
+..\%__SRC%\lib\vcl.lib %_DEST%\lib%_EXT%\vcl.lib
+..\%__SRC%\misc\vcl%upd%??.map %_DEST%\bin%_EXT%\vcl?????.map
+..\%__SRC%\obj\main.obj %_DEST%\lib%_EXT%\xsvmain.obj
+..\%__SRC%\obj\salmain.obj %_DEST%\lib%_EXT%\salmain.obj
+..\%__SRC%\obj\svapp.obj %_DEST%\lib%_EXT%\xsvapp.obj
+..\%__SRC%\res\svsrc.res %_DEST%\res%_EXT%\svsrc.res
+..\%__SRC%\slb\sv.lib %_DEST%\lib%_EXT%\xsv.lib
+..\%__SRC%\slo\salmain.o %_DEST%\lib%_EXT%\salmain.o
+..\%__SRC%\slo\svdll.obj %_DEST%\lib%_EXT%\xsvdll.obj
+..\%__SRC%\ucr\*.ucr %_DEST%\ucr%_EXT%\vcl\*.ucr
+
+hedabu: ..\%__SRC%\inc\*.h %_DEST%\inc%_EXT%\vcl\*.h
+hedabu: ..\%__SRC%\inc\*.hxx %_DEST%\inc%_EXT%\vcl\*.hxx
+hedabu: ..\%__SRC%\inc\convert.hxx %_DEST%\inc%_EXT%\vcl\convert.hxx
+hedabu: ..\inc\accel.hxx %_DEST%\inc%_EXT%\vcl\accel.hxx
+hedabu: ..\inc\access.hxx %_DEST%\inc%_EXT%\vcl\access.hxx
+hedabu: ..\inc\accmgr.hxx %_DEST%\inc%_EXT%\vcl\accmgr.hxx
+hedabu: ..\inc\alpha.hxx %_DEST%\inc%_EXT%\vcl\alpha.hxx
+hedabu: ..\inc\animate.hxx %_DEST%\inc%_EXT%\vcl\animate.hxx
+hedabu: ..\inc\apptypes.hxx %_DEST%\inc%_EXT%\vcl\apptypes.hxx
+hedabu: ..\inc\bitmap.hxx %_DEST%\inc%_EXT%\vcl\bitmap.hxx
+hedabu: ..\inc\bitmap.inl %_DEST%\inc%_EXT%\vcl\bitmap.inl
+hedabu: ..\inc\bitmapex.hxx %_DEST%\inc%_EXT%\vcl\bitmapex.hxx
+hedabu: ..\inc\bmpacc.hxx %_DEST%\inc%_EXT%\vcl\bmpacc.hxx
+hedabu: ..\inc\btndlg.hxx %_DEST%\inc%_EXT%\vcl\btndlg.hxx
+hedabu: ..\inc\button.hxx %_DEST%\inc%_EXT%\vcl\button.hxx
+hedabu: ..\inc\button.hxx %_DEST%\inc%_EXT%\vcl\imagebtn.hxx
+hedabu: ..\inc\clip.hxx %_DEST%\inc%_EXT%\vcl\clip.hxx
+hedabu: ..\inc\cmdevt.h %_DEST%\inc%_EXT%\vcl\cmdevt.h
+hedabu: ..\inc\cmdevt.hxx %_DEST%\inc%_EXT%\vcl\cmdevt.hxx
+hedabu: ..\inc\color.hxx %_DEST%\inc%_EXT%\vcl\color.hxx
+hedabu: ..\inc\combobox.h %_DEST%\inc%_EXT%\vcl\combobox.h
+hedabu: ..\inc\combobox.hxx %_DEST%\inc%_EXT%\vcl\combobox.hxx
+hedabu: ..\inc\config.hxx %_DEST%\inc%_EXT%\vcl\config.hxx
+hedabu: ..\inc\ctrl.hxx %_DEST%\inc%_EXT%\vcl\ctrl.hxx
+hedabu: ..\inc\cursor.hxx %_DEST%\inc%_EXT%\vcl\cursor.hxx
+hedabu: ..\inc\cvtgrf.hxx %_DEST%\inc%_EXT%\vcl\cvtgrf.hxx
+hedabu: ..\inc\cvtsvm.hxx %_DEST%\inc%_EXT%\vcl\cvtsvm.hxx
+hedabu: ..\inc\decoview.hxx %_DEST%\inc%_EXT%\vcl\decoview.hxx
+hedabu: ..\inc\dialog.hxx %_DEST%\inc%_EXT%\vcl\dialog.hxx
+hedabu: ..\inc\dockwin.hxx %_DEST%\inc%_EXT%\vcl\dockwin.hxx
+hedabu: ..\inc\drag.hxx %_DEST%\inc%_EXT%\vcl\drag.hxx
+hedabu: ..\inc\edit.hxx %_DEST%\inc%_EXT%\vcl\edit.hxx
+hedabu: ..\inc\event.hxx %_DEST%\inc%_EXT%\vcl\event.hxx
+hedabu: ..\inc\exchange.hxx %_DEST%\inc%_EXT%\vcl\exchange.hxx
+hedabu: ..\inc\field.hxx %_DEST%\inc%_EXT%\vcl\field.hxx
+hedabu: ..\inc\fildlg.hxx %_DEST%\inc%_EXT%\vcl\fildlg.hxx
+hedabu: ..\inc\filedlg.hxx %_DEST%\inc%_EXT%\vcl\filedlg.hxx
+hedabu: ..\inc\fixbrd.hxx %_DEST%\inc%_EXT%\vcl\fixbrd.hxx
+hedabu: ..\inc\fixed.hxx %_DEST%\inc%_EXT%\vcl\fixed.hxx
+hedabu: ..\inc\fldunit.hxx %_DEST%\inc%_EXT%\vcl\fldunit.hxx
+hedabu: ..\inc\floatwin.hxx %_DEST%\inc%_EXT%\vcl\floatwin.hxx
+hedabu: ..\inc\font.hxx %_DEST%\inc%_EXT%\vcl\font.hxx
+hedabu: ..\inc\fonttype.hxx %_DEST%\inc%_EXT%\vcl\fonttype.hxx
+hedabu: ..\inc\gdimtf.hxx %_DEST%\inc%_EXT%\vcl\gdimtf.hxx
+hedabu: ..\inc\gdiobj.hxx %_DEST%\inc%_EXT%\vcl\gdiobj.hxx
+hedabu: ..\inc\gen.hxx %_DEST%\inc%_EXT%\vcl\gen.hxx
+hedabu: ..\inc\gfxlink.hxx %_DEST%\inc%_EXT%\vcl\gfxlink.hxx
+hedabu: ..\inc\gradient.hxx %_DEST%\inc%_EXT%\vcl\gradient.hxx
+hedabu: ..\inc\graph.h %_DEST%\inc%_EXT%\vcl\graph.h
+hedabu: ..\inc\graph.hxx %_DEST%\inc%_EXT%\vcl\graph.hxx
+hedabu: ..\inc\group.hxx %_DEST%\inc%_EXT%\vcl\group.hxx
+hedabu: ..\inc\hatch.hxx %_DEST%\inc%_EXT%\vcl\hatch.hxx
+hedabu: ..\inc\hdltab.hxx %_DEST%\inc%_EXT%\vcl\hdltab.hxx
+hedabu: ..\inc\help.hxx %_DEST%\inc%_EXT%\vcl\help.hxx
+hedabu: ..\inc\image.hxx %_DEST%\inc%_EXT%\vcl\image.hxx
+hedabu: ..\inc\imagebtn.hxx %_DEST%\inc%_EXT%\vcl\imagebtn.hxx
+hedabu: ..\inc\imgcons.hxx %_DEST%\inc%_EXT%\vcl\imgcons.hxx
+hedabu: ..\inc\imgctrl.hxx %_DEST%\inc%_EXT%\vcl\imgctrl.hxx
+hedabu: ..\inc\inputctx.hxx %_DEST%\inc%_EXT%\vcl\inputctx.hxx
+hedabu: ..\inc\jobset.hxx %_DEST%\inc%_EXT%\vcl\jobset.hxx
+hedabu: ..\inc\keycod.hxx %_DEST%\inc%_EXT%\vcl\keycod.hxx
+hedabu: ..\inc\keycodes.hxx %_DEST%\inc%_EXT%\vcl\keycodes.hxx
+hedabu: ..\inc\line.hxx %_DEST%\inc%_EXT%\vcl\line.hxx
+hedabu: ..\inc\lineinfo.hxx %_DEST%\inc%_EXT%\vcl\lineinfo.hxx
+hedabu: ..\inc\longcurr.hxx %_DEST%\inc%_EXT%\vcl\longcurr.hxx
+hedabu: ..\inc\lstbox.h %_DEST%\inc%_EXT%\vcl\lstbox.h
+hedabu: ..\inc\lstbox.hxx %_DEST%\inc%_EXT%\vcl\lstbox.hxx
+hedabu: ..\inc\mapmod.hxx %_DEST%\inc%_EXT%\vcl\mapmod.hxx
+hedabu: ..\inc\mapunit.hxx %_DEST%\inc%_EXT%\vcl\mapunit.hxx
+hedabu: ..\inc\menu.hxx %_DEST%\inc%_EXT%\vcl\menu.hxx
+hedabu: ..\inc\menubtn.hxx %_DEST%\inc%_EXT%\vcl\menubtn.hxx
+hedabu: ..\inc\metaact.hxx %_DEST%\inc%_EXT%\vcl\metaact.hxx
+hedabu: ..\inc\metric.hxx %_DEST%\inc%_EXT%\vcl\metric.hxx
+hedabu: ..\inc\morebtn.hxx %_DEST%\inc%_EXT%\vcl\morebtn.hxx
+hedabu: ..\inc\msgbox.hxx %_DEST%\inc%_EXT%\vcl\msgbox.hxx
+hedabu: ..\inc\octree.hxx %_DEST%\inc%_EXT%\vcl\octree.hxx
+hedabu: ..\inc\opengl.hxx %_DEST%\inc%_EXT%\vcl\opengl.hxx
+hedabu: ..\inc\outdev.hxx %_DEST%\inc%_EXT%\vcl\outdev.hxx
+hedabu: ..\inc\outdev3d.hxx %_DEST%\inc%_EXT%\vcl\outdev3d.hxx
+hedabu: ..\inc\pal.hxx %_DEST%\inc%_EXT%\vcl\pal.hxx
+hedabu: ..\inc\pointr.hxx %_DEST%\inc%_EXT%\vcl\pointr.hxx
+hedabu: ..\inc\poly.hxx %_DEST%\inc%_EXT%\vcl\poly.hxx
+hedabu: ..\inc\ppdparser.hxx %_DEST%\inc%_EXT%\vcl\ppdparser.hxx
+hedabu: ..\inc\print.hxx %_DEST%\inc%_EXT%\vcl\print.hxx
+hedabu: ..\inc\prndlg.hxx %_DEST%\inc%_EXT%\vcl\prndlg.hxx
+hedabu: ..\inc\prntypes.hxx %_DEST%\inc%_EXT%\vcl\prntypes.hxx
+hedabu: ..\inc\ptrstyle.hxx %_DEST%\inc%_EXT%\vcl\ptrstyle.hxx
+hedabu: ..\inc\rc.h %_DEST%\inc%_EXT%\vcl\rc.h
+hedabu: ..\inc\rc.hxx %_DEST%\inc%_EXT%\vcl\rc.hxx
+hedabu: ..\inc\rcid.h %_DEST%\inc%_EXT%\vcl\rcid.h
+hedabu: ..\inc\rcown.hxx %_DEST%\inc%_EXT%\vcl\rcown.hxx
+hedabu: ..\inc\regband.hxx %_DEST%\inc%_EXT%\vcl\regband.hxx
+hedabu: ..\inc\region.hxx %_DEST%\inc%_EXT%\vcl\region.hxx
+hedabu: ..\inc\resary.hxx %_DEST%\inc%_EXT%\vcl\resary.hxx
+hedabu: ..\inc\resid.hxx %_DEST%\inc%_EXT%\vcl\resid.hxx
+hedabu: ..\inc\resmgr.hxx %_DEST%\inc%_EXT%\vcl\resmgr.hxx
+hedabu: ..\inc\rversion.h %_DEST%\inc%_EXT%\vcl\rversion.h
+hedabu: ..\inc\salbtype.hxx %_DEST%\inc%_EXT%\vcl\salbtype.hxx
+hedabu: ..\inc\salctype.hxx %_DEST%\inc%_EXT%\vcl\salctype.hxx
+hedabu: ..\inc\salgtype.hxx %_DEST%\inc%_EXT%\vcl\salgtype.hxx
+hedabu: ..\inc\salotype.hxx %_DEST%\inc%_EXT%\vcl\salotype.hxx
+hedabu: ..\inc\salstype.hxx %_DEST%\inc%_EXT%\vcl\salstype.hxx
+hedabu: ..\inc\scrbar.hxx %_DEST%\inc%_EXT%\vcl\scrbar.hxx
+hedabu: ..\inc\seleng.hxx %_DEST%\inc%_EXT%\vcl\seleng.hxx
+hedabu: ..\inc\settings.hxx %_DEST%\inc%_EXT%\vcl\settings.hxx
+hedabu: ..\inc\slider.hxx %_DEST%\inc%_EXT%\vcl\slider.hxx
+hedabu: ..\inc\sndstyle.hxx %_DEST%\inc%_EXT%\vcl\sndstyle.hxx
+hedabu: ..\inc\sound.hxx %_DEST%\inc%_EXT%\vcl\sound.hxx
+hedabu: ..\inc\spin.h %_DEST%\inc%_EXT%\vcl\spin.h
+hedabu: ..\inc\spin.hxx %_DEST%\inc%_EXT%\vcl\spin.hxx
+hedabu: ..\inc\spinfld.hxx %_DEST%\inc%_EXT%\vcl\spinfld.hxx
+hedabu: ..\inc\split.hxx %_DEST%\inc%_EXT%\vcl\split.hxx
+hedabu: ..\inc\splitwin.hxx %_DEST%\inc%_EXT%\vcl\splitwin.hxx
+hedabu: ..\inc\status.hxx %_DEST%\inc%_EXT%\vcl\status.hxx
+hedabu: ..\inc\stdtext.hxx %_DEST%\inc%_EXT%\vcl\stdtext.hxx
+hedabu: ..\inc\strhelper.hxx %_DEST%\inc%_EXT%\vcl\strhelper.hxx
+hedabu: ..\inc\sv.h %_DEST%\inc%_EXT%\vcl\sv.h
+hedabu: ..\inc\svapp.hxx %_DEST%\inc%_EXT%\vcl\svapp.hxx
+hedabu: ..\inc\svsys.h %_DEST%\inc%_EXT%\vcl\svsys.h
+hedabu: ..\inc\symbol.hxx %_DEST%\inc%_EXT%\vcl\symbol.hxx
+hedabu: ..\inc\syschild.hxx %_DEST%\inc%_EXT%\vcl\syschild.hxx
+hedabu: ..\inc\sysdata.hxx %_DEST%\inc%_EXT%\vcl\sysdata.hxx
+hedabu: ..\inc\sysdlg.hxx %_DEST%\inc%_EXT%\vcl\sysdlg.hxx
+hedabu: ..\inc\system.hxx %_DEST%\inc%_EXT%\vcl\system.hxx
+hedabu: ..\inc\syswin.hxx %_DEST%\inc%_EXT%\vcl\syswin.hxx
+hedabu: ..\inc\tab.hxx %_DEST%\inc%_EXT%\vcl\tab.hxx
+hedabu: ..\inc\tabctrl.hxx %_DEST%\inc%_EXT%\vcl\tabctrl.hxx
+hedabu: ..\inc\tabdlg.hxx %_DEST%\inc%_EXT%\vcl\tabdlg.hxx
+hedabu: ..\inc\tabpage.hxx %_DEST%\inc%_EXT%\vcl\tabpage.hxx
+hedabu: ..\inc\timer.hxx %_DEST%\inc%_EXT%\vcl\timer.hxx
+hedabu: ..\inc\toolbox.hxx %_DEST%\inc%_EXT%\vcl\toolbox.hxx
+hedabu: ..\inc\uniqid.hxx %_DEST%\inc%_EXT%\vcl\uniqid.hxx
+hedabu: ..\inc\unowrap.hxx %_DEST%\inc%_EXT%\vcl\unowrap.hxx
+hedabu: ..\inc\vclenum.hxx %_DEST%\inc%_EXT%\vcl\vclenum.hxx
+hedabu: ..\inc\vector2d.hxx %_DEST%\inc%_EXT%\vcl\vector2d.hxx
+hedabu: ..\inc\virdev.hxx %_DEST%\inc%_EXT%\vcl\virdev.hxx
+hedabu: ..\inc\waitobj.hxx %_DEST%\inc%_EXT%\vcl\waitobj.hxx
+hedabu: ..\inc\wall.hxx %_DEST%\inc%_EXT%\vcl\wall.hxx
+hedabu: ..\inc\winbit.hxx %_DEST%\inc%_EXT%\vcl\winbit.hxx
+hedabu: ..\inc\window.hxx %_DEST%\inc%_EXT%\vcl\window.hxx
+hedabu: ..\inc\wintypes.hxx %_DEST%\inc%_EXT%\vcl\wintypes.hxx
+hedabu: ..\inc\wrkwin.hxx %_DEST%\inc%_EXT%\vcl\wrkwin.hxx
+hedabu: ..\inc\atom.hxx %_DEST%\inc%_EXT%\vcl\atom.hxx
+hedabu: ..\inc\threadex.hxx %_DEST%\inc%_EXT%\vcl\threadex.hxx
+hedabu: ..\inc\evntpost.hxx %_DEST%\inc%_EXT%\vcl\evntpost.hxx
+hedabu: ..\inc\unohelp.hxx %_DEST%\inc%_EXT%\vcl\unohelp.hxx
+hedabu: ..\unx\inc\salconfig.hxx %_DEST%\inc%_EXT%\vcl\unx\salconfig.hxx
+
diff --git a/vcl/source/app/dbggui.cxx b/vcl/source/app/dbggui.cxx
new file mode 100644
index 000000000000..024f3cdd5191
--- /dev/null
+++ b/vcl/source/app/dbggui.cxx
@@ -0,0 +1,1884 @@
+/*************************************************************************
+ *
+ * $RCSfile: dbggui.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#pragma hdrstop
+
+#ifdef DBG_UTIL
+
+#define _SV_DBGGUI_CXX
+
+#include "svdata.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <svsys.h>
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_LSTBOX_HXX
+#include <lstbox.hxx>
+#endif
+#ifndef _SV_BUTTON_HXX
+#include <button.hxx>
+#endif
+#ifndef _SV_EDIT_HXX
+#include <edit.hxx>
+#endif
+#ifndef _SV_FIXED_HXX
+#include <fixed.hxx>
+#endif
+#ifndef _SV_GROUP_HXX
+#include <group.hxx>
+#endif
+#ifndef _SV_FIELD_HXX
+#include <field.hxx>
+#endif
+#ifndef _SV_MSGBOX_HXX
+#include <msgbox.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_SYSTEM_HXX
+#include <system.hxx>
+#endif
+
+#ifndef _SV_DBGGUI_HXX
+#include <dbggui.hxx>
+#endif
+
+// =======================================================================
+
+static sal_Char* pDbgHelpText[] =
+{
+"Object Test\n",
+"------------------------------------------\n",
+"\n",
+"--- Macros ---\n",
+"DBG_NAME( aName )\n",
+"Definiert die Verwaltungsdaten fuer eine Klasse. Dieses Makro darf nur in "
+"einem Source-File mit dem gleichen Namen benutzt werden.\n",
+"\n",
+"DBG_NAMEEX( aName )\n",
+"Wie DBG_NAME, nur fuer weitere Source-Files.\n",
+"\n",
+"DBG_CTOR( aName, fTest )\n",
+"Muss in allen Konstruktoren einer Klasse benutzt werden (auch beim "
+"CopyCtor). Als erster Paramter muss der registrierte Name (am besten der "
+"Klassenname) uebergeben werden und als zweiter Parameter die Testfunktion "
+"oder 0.\n",
+"\n",
+"DBG_DTOR( aName, fTest )\n",
+"Muss im Destruktor der Klasse benutzt werden. Als erster Paramter muss "
+"der registrierte Name uebergeben werden und als zweiter Parameter die "
+"Testfunktion oder 0.\n",
+"\n",
+"DBG_CHKTHIS( aName, fTest )\n",
+"Kann in Methoden einer Klasse benutzt werden, wo die Konstruktoren und "
+"der Destruktor der Klasse mit den entsprechenden Makros ausgestattet sind. "
+"Als erster Paramter muss der registrierte Name uebergeben werden und als "
+"zweiter Parameter die Testfunktion oder 0.\n",
+"\n",
+"DBG_CHKOBJ( pObj, aName, fTest )\n",
+"Kann auf Instanzen einer Klasse angewendet werden, wo die Konstruktoren und "
+"der Destruktor der Klasse mit den entsprechenden Makros ausgestattet sind. "
+"Als erster Paramter muss die Adresse des zu testenden Objects uebergeben "
+"werden, als zweiter Parameter der registrierte Name und als dritter "
+"Parameter die Testfunktion oder 0.\n",
+"\n",
+"Damit die Makros Wirkung haben, muss DBG_UTIL defniert sein.\n",
+"\n",
+#ifndef CFRONT
+"--- Optionen ---\n",
+"This\n",
+"Es wird auf gueltigen This-Pointer getestet. Dadurch kann man erreichen, "
+"das bei allen Objekten die damit ausgestattet sind, geprueft wird, ob "
+"mit einem existierenden Objekt gearbeitet wird. Dadurch findet man zum "
+"Beispiel schneller Fehler durch falsche Mehrfachvererbung, Alignment oder "
+"Compilerfehler. Da fast alle Standard-Klassen von SV (String, List, Pen, "
+"Brush, Polygon, ...) mit DBG_CHKTHIS() ausgestattet sind, werden viele "
+"Fehler gefunden, jedoch kostet dadurch dieser Test auch entsprechend viel "
+"Performence.\n",
+"\n",
+"Function\n",
+"Wenn eine Funktion bei den Macros uebergeben wird, wird sie gerufen.\n",
+"\n",
+"Exit\n",
+"This- und Func-Test wird auch beim Funktionsaustritt durchgefuehrt.\n",
+"\n",
+"Report\n",
+"Am Programmende wird die Anzahl der angelegten Objekte ausgegeben. "
+"Da alle wichtigen SV-Klassen zumindest mit DBG_CTOR()/DBG_DTOR() "
+"ausgestattet sind, kann man damit feststellen, ob man die sogenannten "
+"Resource-Leaks hat (Systemobjekte, die nicht freigegeben werden). Dazu "
+"gehoehren OutputDevice, Window, VirtualDevice, Printer und Menu. Achtung: "
+"Dtor-Aufrufe von statischen Objekten werden nicht beruecksichtigt. Deshalb "
+"bleiben bei jedem SV-Programm auch 2 Strings und eine Bitmap nach.\n",
+"\n",
+"Trace\n",
+"Erzeugung, Zerstoerung und Benutzung der mit DBG_XTOR ausgestatteten "
+"Objekte wird protokoliert.\n",
+"\n",
+"\n",
+"Memory Test\n",
+"------------------------------------------\n",
+"\n",
+"--- Macros ---\n",
+"DBG_MEMTEST()\n",
+"Fuehrt die eingestellten Memory Tests durch.\n",
+"\n",
+"DBG_MEMTEST_PTR( p )\n",
+"Fuehrt die eingestellten Memory Tests durch und zusaetzlich wird der "
+"uebergebene Pointer auf Gueltigkeit geprueft, wenn Pointer Test an ist.\n",
+"\n",
+"--- Optionen ---\n",
+"Initilize\n",
+"Allokierter Speicher wird mit 0x77 und freier oder freigegebener Speicher "
+"wird mit 0x33 initialisiert. Diese Option kostet (fast) keine Performence "
+"und sollte deshalb waehrend der Entwicklung fast immer an sein. Denn "
+"dadurch erreicht man auch, das Abstuerze oefters reproduzierbarer "
+"auftreten.\n",
+"\n",
+"Overwrite\n",
+"Es wird getestet, ob vor/hinter die Bloecke geschrieben wird. Vor und "
+"hinter dem Block wird der Speicher mit 0x55 initialisiert. Diese Option "
+"kostet Performence, sollte jedoch auch mal eingesetzt werden um die "
+"haeufigsten Speicherueberschreiber (+-1-Fehler) zu testen. Diese Option "
+"sollte auch eingeschaltet werden, wenn das Programm im new oder "
+"delete-Operator abstuerzt.\n",
+"\n",
+"Free\n",
+"Es wird getestet, ob freier Speicher ueberschrieben wird. Diese Option "
+"kostet eine ganze Menge Performence und sollte deshalb nur gelegentlich "
+"eingesetzt werden um Speicherueberschreiber zu testen. Diese Option "
+"sollte evt. auch eingeschaltet werden, wenn das Programm im new oder "
+"delete-Operator abstuerzt.\n",
+"\n",
+"Pointer\n",
+"Bei delete und DBG_MEMTEST_PTR() wird der Zeiger getestet, ob er auch mit "
+"new oder SvMemAlloc() angelegt wurde. Wenn diese Option eingeschaltet ist, "
+"werden Fehler wie doppeltes delete und delete auf Stack-Objekte oder "
+"ungueltige Zeiger gefunden. Diese Option kostet Performence und sollte "
+"deshalb nicht immer eingeschaltet sein. Jedoch sollte auch ab und zu mit "
+"dieser Option getestet werden, da der Memory-Manager nicht immer bei delete "
+"und ungueltigem Zeiger abstuerzt. Diese Option sollte auch eingeschaltet "
+"werden, wenn das Programm im new oder delete-Operator abstuerzt.\n",
+"\n",
+"Report\n",
+"Am Programmende wird eine kleine Statistik und der nicht freigegebene "
+"Speicher ausgegeben. Achtung: Speicher der von globalen Objekten noch "
+"freigegeben wird, taucht auch in der Leak-Liste auf.\n",
+"\n",
+"Trace\n",
+"Allokation und Freigeben von Speicher wird protokoliert.\n",
+"\n",
+"Leak-Report\n",
+"Gibt unter WNT beim Programmende eine Liste der Memory-Leaks mit "
+"Stack-Trace aus. Dabei werden nur Bloecke beruecksichtigt, die innerhalb "
+"von Application::Execute() angelegt und freigegeben werden. Wenn diese "
+"Option und Overwrite gesetzt ist, wird bei einem Speicherueberschreiber "
+"auch noch versucht den Stack auszugeben, wo der Block angelegt wurde. "
+"Diese Ausgabe erfolgt erst nach Ausgabe der Fehlermeldung in die "
+"Log-Datei.\n"
+"\n",
+"New/Delete\n",
+"Memory-Tests werden auf den gesammten Speicher bei jedem new/delete "
+"durchgefuhert. Achtung: Diese Option macht die Programme sehr langsam "
+"und sollte nur eingeschaltet werden, wenn ein Speicherueberschreiber "
+"eingegrenzt werden soll. Ansonsten reicht es, die einzelnen Optionen "
+"einzuschalten, da (kein Leak vorrausgesetzt) jeder zu erkennende "
+"Speicherueberschreiber waehrend der Laufzeit eines Programms gefunden "
+"werden sollte.\n",
+"\n",
+"Object Test\n",
+"Memory-Tests werden auf den gesammten Speicher bei jedem Object-Test "
+"durchgefuhert. Achtung: Diese Option macht die Programme sehr langsam "
+"und sollte nur eingeschaltet werden, wenn ein Speicherueberschreiber "
+"eingegrenzt werden soll. Ansonsten reicht es, die einzelnen Optionen "
+"einzuschalten, da (kein Leak vorrausgesetzt) jeder zu erkennende "
+"Speicherueberschreiber waehrend der Laufzeit eines Programms gefunden "
+"werden sollte.\n",
+"\n",
+"SysAlloc\n",
+"Wenn dieses Flag gesetzt ist, wird Speicher mit direkten Systemfunktionen"
+"angefordert und der Memory-Manager von SV umgangen. Dadurch ist es moeglich"
+"leistungsfaehigere Memory-Test-Tools einzusetzen. Es ist jedoch darauf zu"
+"achten, das nicht auf jedem System die Memory-Funktionen vom Compiler"
+"gerufen werden, sondern die Systemfunktionen. Dadurch ist man unter"
+"Windows 16-Bit auf ca. 4000 news begrenzt und unter OS2 werden immer"
+"4096 KB Bloecke angefordert.\n",
+"\n",
+"Windows 16-Bit und Debug-Tests\n",
+"Achtung: Wenn Memory-Tests an sind (ausser Initilize) wird niemals "
+"(auch nicht bei >= 64 KB) Speicher mit Offset 0 zurueckgeben. Falls man "
+"darauf angewiesen ist, muessen die Tests mit 32-Bit-Versionen der "
+"Programme durchgefuehrt werden. Teilweise reicht es aber auch schon aus, "
+"wenn man statt 64 KB nur 64 KB - 64-Bytes anlegt, da es dann nicht zu "
+"einem Segmentueberlauf kommt.\n",
+"Ausserdem sollten die Memory- genauso wie die Object-Tests nur dann "
+"eingesetzt werden, wenn nur eine SV-Applikation gleichzeitig laeuft. "
+"Ansonsten kann es zu unkontrolierten Fehlern kommen. Hier hilft dann auch "
+"nur ein ausweichen auf 32-Bit-Programme."
+"\n",
+"\n",
+"\nWeitere Test's und Makros\n",
+"------------------------------------------\n",
+"\n",
+"Profiling\n",
+"DBG_PROFSTART() / DBG_PROFSTOP() / DBG_PROFCONTINUE() / DBG_PROFPAUSE() "
+"werden ausgewertet und beim Programmende wird die Anzahl der Durchlaeufe "
+"und die dazu benoetigte Zeit (inklusive der Childaufrufe) in "
+"Millisekunden ausgegeben. Diese Macros koennen dann eingesetzt werden, wenn "
+"die gleichen Funktionsablaeufe ueber die gesammte Entwicklungszeit "
+"beobachtet werden sollen, wie zum Beispiel die Startup-Zeiten. Bei den "
+"Makros muss der registrierte Name uebergeben werden, der mit DBG_NAME() "
+"registriert wurde.\n",
+"\n",
+"Resourcen\n",
+"Bei Resource-Fehlern gibt es einen Fehler-Dialog, bevor der "
+"Exception-Handler gerufen wird.\n",
+"\n",
+"Dialog\n",
+"Es werden FixedTexte, CheckBoxen, TriStateBoxen und RadioButtons mit "
+"einer anderen Hintergrundfarbe versehen, damit man feststellen kann, wie "
+"Gross die Controls sind. Ausserdem wird getestet, ob sich Controls "
+"ueberschneiden, die Tabreihenfolge in Ordnung ist und die Mnemonischen "
+"Zeichen ordentlich vergeben wurden. Bei Dialogen wird auch angemahnt, "
+"wenn kein DefPushButton oder kein OK-/CancelButton vorhanden ist. "
+"Diese Tests sind nicht 100% (es wird evt. zuviel angemahnt) und "
+"erfuellen auch keine Garantie, das alle Problemfaelle festgestellt "
+"werden, da zum Beispiel nur initial und dann nur die sichtbaren Controls "
+"getestet werden. Es werden somit keine Fehler gefunden, die waehrend der "
+"Benutzung des Dialoges auftreten.\n",
+"\n",
+"Bold AppFont\n",
+"Es wird der Applikationsfont auf Fett gesetzt, damit man feststellen kann, "
+"ob der Platz fuer die Texte auf anderen Systemen oder bei anderer "
+"Systemeinstellung ausreicht. Denn bei schmalen Fonts werden die Dialoge "
+"kuenstlich breiter gemacht, da diese ansonsten zu schmal aussehen.\n",
+"\n",
+"Trace-Ausgaben\n",
+"DBG_TRACE() kann verwendet werden, wenn man TRACE-Ausgaben haben moechte. "
+"DBG_TRACEFILE() gibt zu der Meldung auch noch die Datei und die Zeilennummer "
+"aus, an der das Makro steht. DBG_TRACE1() bis DBG_TRACE5() koennen "
+"verwendet werden, wenn man eine formatierte Ausgabe (printf-Formatstring) "
+"haben moechte. Die Trace-Ausgaben werden aktiviert, in dem man in der "
+"DropDown-ListBox eine entsprechende Ausgabe waehlt.\n"
+"\n",
+"Warnings\n",
+"DBG_WARNING() kann verwendet werden, wenn man Warnungen ausgeben moechte. "
+"DBG_WARNINGFILE() gibt zu der Warnung auch noch die Datei und die "
+"Zeilennummer aus, an der das Makro steht. DBG_WARNING1() bis DBG_WARNING5() "
+"koennen verwendet werden, wenn man eine formatierte Ausgabe "
+"(printf-Formatstring) haben moechte. Wenn man die Warnung von einer "
+"Bedingung abhaengig machen moechte, kann man DBG_ASSERTWARNING() "
+"benutzen. Die Warning wird ausgegeben, wenn die Bedingung nicht erfuellt "
+"wurde. Als erster Parameter muss die zu testende Bedingung und als zweiter "
+"Parameter die auszugebene Meldung uebergeben werden. Die Warnungen werden "
+"aktiviert, in dem man in der DropDown-ListBox eine entsprechende Ausgabe "
+"waehlt. Wenn None gewaehlt ist, wird auch die Bedingung bei "
+"DBG_ASSERTWARNING() nicht ausgewertet.\n",
+"\n",
+"Errors\n",
+"DBG_ERROR() kann verwendet werden, wenn man Fehlermeldungen ausgeben "
+"moechte. DBG_ERRORFILE() gibt zu dem Fehler auch noch die Datei und die "
+"Zeilennummer aus, an der das Makro steht. DBG_ERROR1() bis DBG_ERROR5() "
+"koennen verwendet werden, wenn man eine formatierte Ausgabe "
+"(printf-Formatstring) haben moechte. Wenn man die Fehlerausgabe von einer "
+"Bedingung abhaengig machen moechte, kann man DBG_ASSERT() benutzen. Der "
+"Fehler wird ausgegeben, wenn die Bedingung nicht erfuellt wurde. Als erster "
+"Parameter muss die zu testende Bedingung und als zweiter Parameter die "
+"auszugebene Meldung uebergeben werden. Die Fehlermeldungen werden "
+"aktiviert, in dem man in der DropDown-ListBox eine entsprechende Ausgabe "
+"waehlt. Wenn None gewaehlt ist, wird auch die Bedingung bei "
+"DBG_ASSERT() nicht ausgewertet.\n",
+"\n",
+"\n",
+"Output\n",
+"------------------------------------------\n",
+"\n",
+"Overwrite - CheckBox\n",
+"Bei jedem neuen Programmstart wird das Log-File ueberschrieben, wenn "
+"eine Ausgabe stattgefunden hat.\n",
+"\n",
+"Include-ObjectTest-Filter\n",
+"Es werden nur die Klassen bei Object-Test ausgewertet, die einen der "
+"angegebenen Filter enthalten. Die Filter werden mit ';' getrennt und "
+"sind casesensitiv. Wildcards werden nicht unterstuetzt. Wenn kein Text "
+"angegeben wird, ist der Filter nicht aktiv.\n",
+"\n",
+"Exclude-ObjectTest-Filter\n",
+"Es werden die Klassen bei Object-Test ausgewertet, die einen der "
+"angegebenen Filter nicht enthalten. Die Filter werden mit ';' getrennt "
+"und sind casesensitiv. Wildcards werden nicht unterstuetzt. Wenn kein "
+"Text angegeben wird, ist der Filter nicht aktiv.\n",
+"\n",
+"Include-Filter\n",
+"Es werden nur die Texte ausgegeben, die einen der angegebenen Filter "
+"enthalten. Die Filter werden mit ';' getrennt und sind casesensitiv. "
+"Wildcards werden nicht unterstuetzt. Der Filter gilt fuer alle Ausgaben "
+"(jedoch nicht fuer Errors). Wenn kein Text angegeben wird, ist der Filter "
+"nicht aktiv.\n",
+"\n",
+"Exclude-Filter\n",
+"Es werden nur die Texte ausgegeben, die einen der angegebenen Filter "
+"nicht enthalten. Die Filter werden mit ';' getrennt und sind casesensitiv. "
+"Wildcards werden nicht unterstuetzt. Der Filter gilt fuer alle Ausgaben "
+"(jedoch nicht fuer Errors). Wenn kein Text angegeben wird, ist der Filter "
+"nicht aktiv.\n",
+"\n",
+"Ausserdem kann eingestellt werden, wohin die Daten ausgegeben werden "
+"sollen:\n",
+"\n",
+"None\n",
+"Ausgabe wird unterdrueckt.\n",
+"\n",
+"File\n",
+"Ausgabe ins Debug-File. Dateiname kann im Editfeld eingegeben werden.\n",
+"\n",
+"Window\n",
+"Ausgabe in ein kleines Debug-Window. Die Fenstergroesse wird gespeichert, "
+"wenn man den Debug-Dialog mit OK beendet und das Fenster sichtbar ist.\n",
+"\n",
+"Shell\n",
+"Ausgabe in ein Debug-System (Windows Debug-Window) wenn vorhanden oder "
+"unter Unix ins Shell-Fenster. Ansonsten das gleiche wie Window.\n",
+"\n",
+"MessageBox\n",
+"Ausgabe in MessageBox. In dieser hat man dann die Auswahl, ob das Programm "
+"fortgesetzt, beendet (Application::Abort) oder mit CoreDump abgebrochen "
+"werden soll. Da eine MessageBox weitere Event-Verarbeitung zulaest koennen "
+"jeweils weitere Fehler zum Beispiel durch Paints, Activate/Deactivate, "
+"GetFocus/LoseFocus die Ausgabe der Meldung oder weitere und falsche "
+"Fehler und Meldungen ausloesen. Deshalb sollte bei Problemen die Meldungen "
+"evt. auch in ein File/Debugger geleitet werden um die (richtigen) Fehlermeldungen "
+"zu erhalten.\n",
+"\n",
+"TestTool\n",
+"Wenn das TestTool laeuft, werden die Meldungen in das TestTool umgeleitet.\n",
+"\n",
+"Debugger\n",
+"Versucht den Debugger zu aktivieren und dort die Meldung auszugeben, "
+"so das man im Debugger dann immer auch den dazugehoerenden Stacktrace "
+"erhaellt.\n",
+"\n",
+"CoreDump\n",
+"Erzeugt einen Absturz\n",
+"\n",
+"\n",
+"Einstellungen\n",
+"------------------------------------------\n",
+"\n",
+"Wo standardmaessig das INI-File und LOG-File gelesen und geschrieben "
+"wird, kann folgendermassen eingestellt werden:\n",
+"\n",
+"WIN/WNT (WIN.INI, Gruppe SV, Default: dbgsv.ini und dbgsv.log):\n",
+"INI: dbgsv\n",
+"LOG: dbgsvlog\n",
+"\n",
+"OS2 (OS2.INI, Application SV, Default: dbgsv.ini und dbgsv.log):\n",
+"INI: DBGSV\n",
+"LOG: DBGSVLOG\n",
+"\n",
+"UNIX (Environment-Variable, Default: .dbgsv.init und dbgsv.log):\n",
+"INI: DBGSV_INIT\n",
+"LOG: DBGSV_LOG\n",
+"\n",
+"MAC (Default: dbgsv.ini und dbgsv.log):\n",
+"INI: keine Moeglichkeit\n",
+"LOG: nur Debug-Dialogeinstellung\n",
+"\n",
+"Es muss jeweils Pfad und Dateiname angegeben werden. Der Name der "
+"Log-Datei, der im Debug-Dialog eintragen wurde, hat immer vorrang.\n",
+"\n",
+"\n",
+"Beispiel\n",
+"------------------------------------------\n",
+"\n",
+"DBG_NAME( String );\n",
+"\n",
+"#ifdef DBG_UTIL\n",
+"const sal_Char* DbgCheckString( const void* pString )\n",
+"{\n",
+" String* p = (String*)pString;\n",
+"\n",
+" if ( p->mpData->maStr[p->mpData->mnLen] != 0 )\n",
+" return \"String damaged: aStr[nLen] != 0\";\n",
+"\n",
+" return NULL;\n",
+"}\n",
+"#endif\n",
+"\n",
+"String::String()\n",
+"{\n",
+" DBG_CTOR( String, DbgCheckString );\n",
+" // ...\n",
+"}\n",
+"\n",
+"String::~String()\n",
+"{\n",
+" DBG_DTOR( String, DbgCheckString );\n",
+" //...\n",
+"}\n",
+"\n",
+"char& String::operator [] ( USHORT nIndex )\n",
+"{\n",
+" DBG_CHKTHIS( String, DbgCheckString );\n",
+" DBG_ASSERT( nIndex <= pData->nLen, \"String::[] : nIndex > Len\" );\n",
+"\n",
+" //...\n",
+"}\n",
+"\n",
+"USHORT String::Search( const String& rStr, USHORT nIndex ) const\n",
+"{\n",
+" DBG_CHKTHIS( String, DbgCheckString );\n",
+" DBG_CHKOBJ( &rStr, String, DbgCheckString );\n",
+"\n",
+" //...\n",
+"}",
+"\n",
+#endif
+NULL
+};
+
+// =======================================================================
+
+// -------------
+// - DbgWindow -
+// -------------
+
+#define DBGWIN_MAXLINES 100
+
+class DbgWindow : public WorkWindow
+{
+private:
+ ListBox maLstBox;
+
+public:
+ DbgWindow();
+
+ virtual BOOL Close();
+ virtual void Resize();
+ void InsertLine( const XubString& rLine );
+ void Update() { WorkWindow::Update(); maLstBox.Update(); }
+};
+
+// -----------------
+// - DbgInfoDialog -
+// -----------------
+
+class DbgInfoDialog : public ModalDialog
+{
+private:
+ ListBox maListBox;
+ OKButton maOKButton;
+ BOOL mbHelpText;
+
+public:
+ DbgInfoDialog( Window* pParent, BOOL bHelpText = FALSE );
+
+ void SetInfoText( const XubString& rStr );
+};
+
+// -------------
+// - DbgDialog -
+// -------------
+
+class DbgDialog : public ModalDialog
+{
+private:
+ CheckBox maXtorThis;
+ CheckBox maXtorFunc;
+ CheckBox maXtorExit;
+ CheckBox maXtorReport;
+ CheckBox maXtorTrace;
+ GroupBox maBox1;
+
+ CheckBox maMemInit;
+ CheckBox maMemOverwrite;
+ CheckBox maMemOverwriteFree;
+ CheckBox maMemPtr;
+ CheckBox maMemReport;
+ CheckBox maMemTrace;
+ CheckBox maMemLeakReport;
+ CheckBox maMemNewDel;
+ CheckBox maMemXtor;
+ CheckBox maMemSysAlloc;
+ GroupBox maBox2;
+
+ CheckBox maProf;
+ CheckBox maRes;
+ CheckBox maDialog;
+ CheckBox maBoldAppFont;
+ GroupBox maBox3;
+
+ Edit maDebugName;
+ CheckBox maOverwrite;
+ FixedText maInclClassText;
+ Edit maInclClassFilter;
+ FixedText maExclClassText;
+ Edit maExclClassFilter;
+ FixedText maInclText;
+ Edit maInclFilter;
+ FixedText maExclText;
+ Edit maExclFilter;
+ FixedText maTraceText;
+ ListBox maTraceBox;
+ FixedText maWarningText;
+ ListBox maWarningBox;
+ FixedText maErrorText;
+ ListBox maErrorBox;
+ GroupBox maBox4;
+
+ OKButton maOKButton;
+ CancelButton maCancelButton;
+ PushButton maInfoButton;
+ HelpButton maHelpButton;
+ USHORT mnErrorOff;
+
+public:
+ DbgDialog();
+
+ DECL_LINK( ClickHdl, Button* );
+ void RequestHelp( const HelpEvent& rHEvt );
+};
+
+// =======================================================================
+
+static sal_Char aDbgInfoBuf[12288];
+static sal_Char aDbgOutBuf[DBG_BUF_MAXLEN];
+
+// =======================================================================
+
+DbgWindow::DbgWindow() :
+ WorkWindow( NULL, WB_STDWORK ),
+ maLstBox( this, WB_AUTOHSCROLL )
+{
+ DbgData* pData = DbgGetData();
+
+ maLstBox.Show();
+ maLstBox.SetPosPixel( Point( 0, 0 ) );
+
+ SetOutputSizePixel( Size( 250, 400 ) );
+ if ( pData->aDbgWinState )
+ {
+ ByteString aState( pData->aDbgWinState );
+ SetWindowState( aState );
+ }
+
+ SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "StarView Debug Window" ) ) );
+ Show();
+ Update();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL DbgWindow::Close()
+{
+ delete this;
+ ImplGetSVData()->maWinData.mpDbgWin = NULL;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void DbgWindow::Resize()
+{
+ maLstBox.SetSizePixel( GetOutputSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+void DbgWindow::InsertLine( const XubString& rLine )
+{
+ XubString aStr = rLine;
+ aStr.ConvertLineEnd( LINEEND_LF );
+ xub_StrLen nPos = aStr.Search( _LF );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ if ( maLstBox.GetEntryCount() >= DBGWIN_MAXLINES )
+ maLstBox.RemoveEntry( 0 );
+ maLstBox.InsertEntry( aStr.Copy( 0, nPos ) );
+ aStr.Erase( 0, nPos+1 );
+ nPos = aStr.Search( _LF );
+ }
+ if ( maLstBox.GetEntryCount() >= DBGWIN_MAXLINES )
+ maLstBox.RemoveEntry( 0 );
+ maLstBox.InsertEntry( aStr );
+ maLstBox.SetTopEntry( DBGWIN_MAXLINES-1 );
+ maLstBox.Update();
+}
+
+// =======================================================================
+
+DbgDialog::DbgDialog() :
+ ModalDialog( Application::GetAppWindow(), WB_STDMODAL | WB_SYSTEMWINDOW ),
+ maXtorThis( this ),
+ maXtorFunc( this ),
+ maXtorExit( this ),
+ maXtorReport( this ),
+ maXtorTrace( this ),
+ maBox1( this ),
+ maMemInit( this ),
+ maMemOverwrite( this ),
+ maMemOverwriteFree( this ),
+ maMemPtr( this ),
+ maMemReport( this ),
+ maMemTrace( this ),
+ maMemLeakReport( this ),
+ maMemNewDel( this ),
+ maMemXtor( this ),
+ maMemSysAlloc( this ),
+ maBox2( this ),
+ maProf( this ),
+ maRes( this ),
+ maDialog( this ),
+ maBoldAppFont( this ),
+ maBox3( this ),
+ maDebugName( this ),
+ maOverwrite( this ),
+ maInclClassText( this ),
+ maInclClassFilter( this ),
+ maExclClassText( this ),
+ maExclClassFilter( this ),
+ maInclText( this ),
+ maInclFilter( this ),
+ maExclText( this ),
+ maExclFilter( this ),
+ maTraceText( this ),
+ maTraceBox( this, WB_DROPDOWN ),
+ maWarningText( this ),
+ maWarningBox( this, WB_DROPDOWN ),
+ maErrorText( this ),
+ maErrorBox( this, WB_DROPDOWN ),
+ maBox4( this ),
+ maOKButton( this, WB_DEFBUTTON ),
+ maCancelButton( this ),
+ maInfoButton( this ),
+ maHelpButton( this )
+{
+ DbgData* pData = DbgGetData();
+ MapMode aAppMap( MAP_APPFONT );
+ Size aButtonSize = LogicToPixel( Size( 60, 12 ), aAppMap );
+
+ {
+ maXtorThis.Show();
+ maXtorThis.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "T~his" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_XTOR_THIS )
+ maXtorThis.Check( TRUE );
+ maXtorThis.SetPosSizePixel( LogicToPixel( Point( 10, 15 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maXtorFunc.Show();
+ maXtorFunc.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Function" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_XTOR_FUNC )
+ maXtorFunc.Check( TRUE );
+ maXtorFunc.SetPosSizePixel( LogicToPixel( Point( 75, 15 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maXtorExit.Show();
+ maXtorExit.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "E~xit" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_XTOR_EXIT )
+ maXtorExit.Check( TRUE );
+ maXtorExit.SetPosSizePixel( LogicToPixel( Point( 140, 15 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maXtorReport.Show();
+ maXtorReport.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Report" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_XTOR_REPORT )
+ maXtorReport.Check( TRUE );
+ maXtorReport.SetPosSizePixel( LogicToPixel( Point( 205, 15 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maXtorTrace.Show();
+ maXtorTrace.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Trace" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_XTOR_TRACE )
+ maXtorTrace.Check( TRUE );
+ maXtorTrace.SetPosSizePixel( LogicToPixel( Point( 270, 15 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maBox1.Show();
+ maBox1.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Object Tests" ) ) );
+ maBox1.SetPosSizePixel( LogicToPixel( Point( 5, 5 ), aAppMap ),
+ LogicToPixel( Size( 330, 30 ), aAppMap ) );
+ }
+
+ {
+ maMemInit.Show();
+ maMemInit.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Initilize" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_INIT )
+ maMemInit.Check( TRUE );
+ maMemInit.SetPosSizePixel( LogicToPixel( Point( 10, 50 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maMemOverwrite.Show();
+ maMemOverwrite.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Overwrite" )) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_OVERWRITE )
+ maMemOverwrite.Check( TRUE );
+ maMemOverwrite.SetPosSizePixel( LogicToPixel( Point( 75, 50 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maMemOverwriteFree.Show();
+ maMemOverwriteFree.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Free" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_OVERWRITEFREE )
+ maMemOverwriteFree.Check( TRUE );
+ maMemOverwriteFree.SetPosSizePixel( LogicToPixel( Point( 140, 50 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maMemPtr.Show();
+ maMemPtr.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Pointer" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_POINTER )
+ maMemPtr.Check( TRUE );
+ maMemPtr.SetPosSizePixel( LogicToPixel( Point( 205, 50 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maMemReport.Show();
+ maMemReport.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Report" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_REPORT )
+ maMemReport.Check( TRUE );
+ maMemReport.SetPosSizePixel( LogicToPixel( Point( 270, 50 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maMemTrace.Show();
+ maMemTrace.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Trace" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_TRACE )
+ maMemTrace.Check( TRUE );
+ maMemTrace.SetPosSizePixel( LogicToPixel( Point( 10, 65 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maMemLeakReport.Show();
+ maMemLeakReport.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Leak-Report" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_LEAKREPORT )
+ maMemLeakReport.Check( TRUE );
+ maMemLeakReport.SetPosSizePixel( LogicToPixel( Point( 75, 65 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maMemNewDel.Show();
+ maMemNewDel.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~New/Delete" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_NEWDEL )
+ maMemNewDel.Check( TRUE );
+ maMemNewDel.SetPosSizePixel( LogicToPixel( Point( 140, 65 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maMemXtor.Show();
+ maMemXtor.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Ob~ject Test" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_XTOR )
+ maMemXtor.Check( TRUE );
+ maMemXtor.SetPosSizePixel( LogicToPixel( Point( 205, 65 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maMemSysAlloc.Show();
+ maMemSysAlloc.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "System ~Alloc" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_MEM_SYSALLOC )
+ {
+ maMemSysAlloc.Check( TRUE );
+ ClickHdl( &maMemSysAlloc );
+ }
+ maMemSysAlloc.SetClickHdl( LINK( this, DbgDialog, ClickHdl ) );
+ maMemSysAlloc.SetPosSizePixel( LogicToPixel( Point( 270, 65 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maBox2.Show();
+ maBox2.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Memory Tests" ) ) );
+ maBox2.SetPosSizePixel( LogicToPixel( Point( 5, 40 ), aAppMap ),
+ LogicToPixel( Size( 330, 40 ), aAppMap ) );
+ }
+
+ {
+ maProf.Show();
+ maProf.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Profiling" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_PROFILING )
+ maProf.Check( TRUE );
+ maProf.SetPosSizePixel( LogicToPixel( Point( 10, 95 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maRes.Show();
+ maRes.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Resourcen" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_RESOURCE )
+ maRes.Check( TRUE );
+ maRes.SetPosSizePixel( LogicToPixel( Point( 75, 95 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maDialog.Show();
+ maDialog.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Dialog" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_DIALOG )
+ maDialog.Check( TRUE );
+ maDialog.SetPosSizePixel( LogicToPixel( Point( 140, 95 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maBoldAppFont.Show();
+ maBoldAppFont.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Bold AppFont" ) ) );
+ if ( pData->nTestFlags & DBG_TEST_BOLDAPPFONT )
+ maBoldAppFont.Check( TRUE );
+ maBoldAppFont.SetPosSizePixel( LogicToPixel( Point( 205, 95 ), aAppMap ),
+ aButtonSize );
+ maBoldAppFont.SaveValue();
+ }
+
+ {
+ maBox3.Show();
+ maBox3.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Test Options" ) ) );
+ maBox3.SetPosSizePixel( LogicToPixel( Point( 5, 85 ), aAppMap ),
+ LogicToPixel( Size( 330, 30 ), aAppMap ) );
+ }
+
+ {
+ maDebugName.Show();
+ maDebugName.SetText( XubString( pData->aDebugName, RTL_TEXTENCODING_UTF8 ) );
+ maDebugName.SetMaxTextLen( sizeof( pData->aDebugName ) );
+ maDebugName.SetPosSizePixel( LogicToPixel( Point( 10, 130 ), aAppMap ),
+ LogicToPixel( Size( 185, 14 ), aAppMap ) );
+ }
+
+ {
+ maOverwrite.Show();
+ maOverwrite.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Overwrite ~File" ) ) );
+ if ( pData->bOverwrite )
+ maOverwrite.Check( TRUE );
+ maOverwrite.SetPosSizePixel( LogicToPixel( Point( 205, 130 ), aAppMap ),
+ aButtonSize );
+ }
+
+ {
+ maInclClassText.Show();
+ maInclClassText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Include-ObjectTest-Filter" ) ) );
+ maInclClassText.SetPosSizePixel( LogicToPixel( Point( 10, 150 ), aAppMap ),
+ LogicToPixel( Size( 95, 9 ), aAppMap ) );
+ }
+
+ {
+ maInclClassFilter.Show();
+ maInclClassFilter.SetText( XubString( pData->aInclClassFilter, RTL_TEXTENCODING_UTF8 ) );
+ maInclClassFilter.SetMaxTextLen( sizeof( pData->aInclClassFilter ) );
+ maInclClassFilter.SetPosSizePixel( LogicToPixel( Point( 10, 160 ), aAppMap ),
+ LogicToPixel( Size( 95, 14 ), aAppMap ) );
+ }
+
+ {
+ maExclClassText.Show();
+ maExclClassText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Exclude-ObjectTest-Filter" ) ) );
+ maExclClassText.SetPosSizePixel( LogicToPixel( Point( 115, 150 ), aAppMap ),
+ LogicToPixel( Size( 95, 9 ), aAppMap ) );
+ }
+
+ {
+ maExclClassFilter.Show();
+ maExclClassFilter.SetText( XubString( pData->aExclClassFilter, RTL_TEXTENCODING_UTF8 ) );
+ maExclClassFilter.SetMaxTextLen( sizeof( pData->aExclClassFilter ) );
+ maExclClassFilter.SetPosSizePixel( LogicToPixel( Point( 115, 160 ), aAppMap ),
+ LogicToPixel( Size( 95, 14 ), aAppMap ) );
+ }
+
+ {
+ maInclText.Show();
+ maInclText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Include-Filter" ) ) );
+ maInclText.SetPosSizePixel( LogicToPixel( Point( 10, 180 ), aAppMap ),
+ LogicToPixel( Size( 95, 9 ), aAppMap ) );
+ }
+
+ {
+ maInclFilter.Show();
+ maInclFilter.SetText( XubString( pData->aInclFilter, RTL_TEXTENCODING_UTF8 ) );
+ maInclFilter.SetMaxTextLen( sizeof( pData->aInclFilter ) );
+ maInclFilter.SetPosSizePixel( LogicToPixel( Point( 10, 190 ), aAppMap ),
+ LogicToPixel( Size( 95, 14 ), aAppMap ) );
+ }
+
+ {
+ maExclText.Show();
+ maExclText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Exclude-Filter" ) ) );
+ maExclText.SetPosSizePixel( LogicToPixel( Point( 115, 180 ), aAppMap ),
+ LogicToPixel( Size( 95, 9 ), aAppMap ) );
+ }
+
+ {
+ maExclFilter.Show();
+ maExclFilter.SetText( XubString( pData->aExclFilter, RTL_TEXTENCODING_UTF8 ) );
+ maExclFilter.SetMaxTextLen( sizeof( pData->aExclFilter ) );
+ maExclFilter.SetPosSizePixel( LogicToPixel( Point( 115, 190 ), aAppMap ),
+ LogicToPixel( Size( 95, 14 ), aAppMap ) );
+ }
+
+ {
+ maTraceText.Show();
+ maTraceText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Trace" ) ) );
+ maTraceText.SetPosSizePixel( LogicToPixel( Point( 10, 210 ), aAppMap ),
+ LogicToPixel( Size( 95, 9 ), aAppMap ) );
+ }
+
+ {
+ maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) );
+ maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) );
+ maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Window" ) ) );
+ maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Shell" ) ) );
+ maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "MessageBox" ) ) );
+ maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "TestTool" ) ) );
+ maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debugger" ) ) );
+ maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "CoreDump" ) ) );
+ maTraceBox.SelectEntryPos( (USHORT)pData->nTraceOut );
+ maTraceBox.Show();
+ maTraceBox.SetPosSizePixel( LogicToPixel( Point( 10, 220 ), aAppMap ),
+ LogicToPixel( Size( 95, 80 ), aAppMap ) );
+ }
+
+ {
+ maWarningText.Show();
+ maWarningText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Warning" ) ) );
+ maWarningText.SetPosSizePixel( LogicToPixel( Point( 115, 210 ), aAppMap ),
+ LogicToPixel( Size( 95, 9 ), aAppMap ) );
+ }
+
+ {
+ maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) );
+ maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) );
+ maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Window" ) ) );
+ maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Shell" ) ) );
+ maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "MessageBox" ) ) );
+ maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "TestTool" ) ) );
+ maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debugger" ) ) );
+ maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "CoreDump" ) ) );
+ maWarningBox.SelectEntryPos( (USHORT)pData->nWarningOut );
+ maWarningBox.Show();
+ maWarningBox.SetPosSizePixel( LogicToPixel( Point( 115, 220 ), aAppMap ),
+ LogicToPixel( Size( 95, 80 ), aAppMap ) );
+ }
+
+ {
+ maErrorText.Show();
+ maErrorText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Error" ) ) );
+ maErrorText.SetPosSizePixel( LogicToPixel( Point( 220, 210 ), aAppMap ),
+ LogicToPixel( Size( 95, 9 ), aAppMap ) );
+ }
+
+ {
+ if ( DbgIsAllErrorOut() )
+ {
+ maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) );
+ maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) );
+ maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Window" ) ) );
+ maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Shell" ) ) );
+ mnErrorOff = 0;
+ }
+ else
+ mnErrorOff = 4;
+ maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "MessageBox" ) ) );
+ maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "TestTool" ) ) );
+ maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debugger" ) ) );
+ maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "CoreDump" ) ) );
+ maErrorBox.SelectEntryPos( (USHORT)pData->nErrorOut-mnErrorOff );
+ maErrorBox.Show();
+ maErrorBox.SetPosSizePixel( LogicToPixel( Point( 220, 220 ), aAppMap ),
+ LogicToPixel( Size( 95, 80 ), aAppMap ) );
+ }
+
+ {
+ maBox4.Show();
+ maBox4.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Output" ) ) );
+ maBox4.SetPosSizePixel( LogicToPixel( Point( 5, 120 ), aAppMap ),
+ LogicToPixel( Size( 330, 120 ), aAppMap ) );
+ }
+
+ {
+ maOKButton.Show();
+ maOKButton.SetClickHdl( LINK( this, DbgDialog, ClickHdl ) );
+ maOKButton.SetPosSizePixel( LogicToPixel( Point( 10, 245 ), aAppMap ),
+ LogicToPixel( Size( 50, 15 ), aAppMap ) );
+ }
+ {
+ maCancelButton.Show();
+ maCancelButton.SetPosSizePixel( LogicToPixel( Point( 70, 245 ), aAppMap ),
+ LogicToPixel( Size( 50, 15 ), aAppMap ) );
+ }
+ {
+ maInfoButton.Show();
+ maInfoButton.SetClickHdl( LINK( this, DbgDialog, ClickHdl ) );
+ maInfoButton.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Info..." ) ) );
+ maInfoButton.SetPosSizePixel( LogicToPixel( Point( 130, 245 ), aAppMap ),
+ LogicToPixel( Size( 50, 15 ), aAppMap ) );
+ }
+ {
+ maHelpButton.Show();
+ maHelpButton.SetPosSizePixel( LogicToPixel( Point( 190, 245 ), aAppMap ),
+ LogicToPixel( Size( 50, 15 ), aAppMap ) );
+ }
+
+ {
+#ifdef REMOTE_APPSERVER
+ SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "VCL Debug Options (Server)" ) ) );
+#else
+ SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "VCL Debug Options" ) ) );
+#endif
+ SetOutputSizePixel( LogicToPixel( Size( 340, 265 ), aAppMap ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( DbgDialog, ClickHdl, Button*, pButton )
+{
+ if ( pButton == &maOKButton )
+ {
+ DbgData aData;
+
+ memcpy( &aData, DbgGetData(), sizeof( DbgData ) );
+ aData.nTestFlags = 0;
+
+ aData.nTraceOut = maTraceBox.GetSelectEntryPos();
+ aData.nWarningOut = maWarningBox.GetSelectEntryPos();
+ aData.nErrorOut = maErrorBox.GetSelectEntryPos()+mnErrorOff;
+
+ strncpy( aData.aDebugName, ByteString( maDebugName.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aDebugName ) );
+ strncpy( aData.aInclClassFilter, ByteString( maInclClassFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aInclClassFilter ) );
+ strncpy( aData.aExclClassFilter, ByteString( maExclClassFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aExclClassFilter ) );
+ strncpy( aData.aInclFilter, ByteString( maInclFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aInclFilter ) );
+ strncpy( aData.aExclFilter, ByteString( maExclFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aExclFilter ) );
+ aData.aDebugName[sizeof( aData.aDebugName )-1] = '\0';
+ aData.aInclClassFilter[sizeof( aData.aInclClassFilter )-1] = '\0';
+ aData.aExclClassFilter[sizeof( aData.aExclClassFilter )-1] = '\0';
+ aData.aInclFilter[sizeof( aData.aInclFilter )-1] = '\0';
+ aData.aExclFilter[sizeof( aData.aExclFilter )-1] = '\0';
+
+ if ( maOverwrite.IsChecked() )
+ aData.bOverwrite = TRUE;
+ else
+ aData.bOverwrite = FALSE;
+
+ if ( maXtorThis.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_XTOR_THIS;
+
+ if ( maXtorFunc.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_XTOR_FUNC;
+
+ if ( maXtorExit.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_XTOR_EXIT;
+
+ if ( maXtorReport.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_XTOR_REPORT;
+
+ if ( maXtorTrace.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_XTOR_TRACE;
+
+ if ( maMemInit.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_INIT;
+
+ if ( maMemOverwrite.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_OVERWRITE;
+
+ if ( maMemOverwriteFree.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_OVERWRITEFREE;
+
+ if ( maMemPtr.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_POINTER;
+
+ if ( maMemReport.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_REPORT;
+
+ if ( maMemTrace.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_TRACE;
+
+ if ( maMemLeakReport.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_LEAKREPORT;
+
+ if ( maMemNewDel.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_NEWDEL;
+
+ if ( maMemXtor.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_XTOR;
+
+ if ( maMemSysAlloc.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_MEM_SYSALLOC;
+
+ if ( maProf.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_PROFILING;
+
+ if ( maRes.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_RESOURCE;
+
+ if ( maDialog.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_DIALOG;
+
+ if ( maBoldAppFont.IsChecked() )
+ aData.nTestFlags |= DBG_TEST_BOLDAPPFONT;
+
+ // Fensterposition mit abspeichern
+ DbgWindow* pDbgWindow = ImplGetSVData()->maWinData.mpDbgWin;
+ if ( pDbgWindow )
+ {
+ ByteString aState = pDbgWindow->GetWindowState();
+ if ( aState.Len() < sizeof( aData.aDbgWinState ) )
+ memcpy( aData.aDbgWinState, aState.GetBuffer(), aState.Len() );
+ }
+
+ // Daten speichern
+ DbgSaveData( aData );
+
+ // Umschalten der Laufzeitwerte
+ DBG_INSTOUTTRACE( aData.nTraceOut );
+ DBG_INSTOUTWARNING( aData.nWarningOut );
+ DBG_INSTOUTERROR( aData.nErrorOut );
+
+ DbgData* pData = DbgGetData();
+ pData->nTestFlags &= ~(DBG_TEST_XTOR_TRACE | DBG_TEST_MEM_INIT | DBG_TEST_RESOURCE | DBG_TEST_DIALOG | DBG_TEST_BOLDAPPFONT);
+ pData->nTestFlags |= aData.nTestFlags & (DBG_TEST_XTOR_TRACE | DBG_TEST_MEM_INIT | DBG_TEST_RESOURCE | DBG_TEST_DIALOG | DBG_TEST_BOLDAPPFONT);
+ strcpy( pData->aInclClassFilter, aData.aInclClassFilter );
+ strcpy( pData->aExclClassFilter, aData.aExclClassFilter );
+ strcpy( pData->aInclFilter, aData.aInclFilter );
+ strcpy( pData->aExclFilter, aData.aExclFilter );
+ if ( maBoldAppFont.GetSavedValue() != maBoldAppFont.IsChecked() )
+ {
+ AllSettings aSettings = Application::GetSettings();
+ StyleSettings aStyleSettings = aSettings.GetStyleSettings();
+ Font aFont = aStyleSettings.GetAppFont();
+ if ( maBoldAppFont.IsChecked() )
+ aFont.SetWeight( WEIGHT_BOLD );
+ else
+ aFont.SetWeight( WEIGHT_NORMAL );
+ aStyleSettings.SetAppFont( aFont );
+ aSettings.SetStyleSettings( aStyleSettings );
+ Application::SetSettings( aSettings );
+ }
+ EndDialog( TRUE );
+ }
+ else if ( pButton == &maInfoButton )
+ {
+ DbgInfoDialog aInfoDialog( this );
+ aDbgInfoBuf[0] = '\0';
+ DbgMemInfo( aDbgInfoBuf );
+ DbgXtorInfo( aDbgInfoBuf );
+ XubString aInfoText( aDbgInfoBuf, RTL_TEXTENCODING_UTF8 );
+ aInfoDialog.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debug InfoReport" ) ) );
+ aInfoDialog.SetInfoText( aInfoText );
+ aInfoDialog.Execute();
+ }
+ else if ( pButton == &maMemSysAlloc )
+ {
+ BOOL bEnable = maMemSysAlloc.IsChecked() == 0;
+ maMemInit.Enable( bEnable );
+ maMemOverwrite.Enable( bEnable );
+ maMemOverwriteFree.Enable( bEnable );
+ maMemPtr.Enable( bEnable );
+ maMemReport.Enable( bEnable );
+ maMemTrace.Enable( bEnable );
+ maMemLeakReport.Enable( bEnable );
+ maMemNewDel.Enable( bEnable );
+ maMemXtor.Enable( bEnable );
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void DbgDialog::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( rHEvt.GetMode() & HELPMODE_CONTEXT )
+ {
+ DbgInfoDialog aInfoDialog( this, TRUE );
+ XubString aHelpText;
+ sal_Char** pHelpStrs = pDbgHelpText;
+ while ( *pHelpStrs )
+ {
+ aHelpText.AppendAscii( *pHelpStrs );
+ pHelpStrs++;
+ }
+ aInfoDialog.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debug Hilfe" ) ) );
+ aInfoDialog.SetInfoText( aHelpText );
+ aInfoDialog.Execute();
+ }
+}
+
+// =======================================================================
+
+DbgInfoDialog::DbgInfoDialog( Window* pParent, BOOL bHelpText ) :
+ ModalDialog( pParent, WB_STDMODAL ),
+ maListBox( this, WB_BORDER | WB_AUTOHSCROLL ),
+ maOKButton( this, WB_DEFBUTTON )
+{
+ mbHelpText = bHelpText;
+
+ if ( !bHelpText )
+ {
+ Font aFont = System::GetStandardFont( STDFONT_FIXED );
+ aFont.SetHeight( 8 );
+ aFont.SetPitch( PITCH_FIXED );
+ maListBox.SetControlFont( aFont );
+ }
+ maListBox.SetPosSizePixel( Point( 5, 5 ), Size( 630, 380 ) );
+ maListBox.Show();
+
+ maOKButton.SetPosSizePixel( Point( 290, 390 ), Size( 60, 25 ) );
+ maOKButton.Show();
+
+ SetOutputSizePixel( Size( 640, 420 ) );
+}
+
+// -----------------------------------------------------------------------
+
+void DbgInfoDialog::SetInfoText( const XubString& rStr )
+{
+ maListBox.SetUpdateMode( FALSE );
+ maListBox.Clear();
+ XubString aStr = rStr;
+ aStr.ConvertLineEnd( LINEEND_LF );
+ USHORT nIndex = 0;
+ USHORT nFoundIndex;
+ do
+ {
+ nFoundIndex = aStr.Search( _LF, nIndex );
+ XubString aTextParagraph = aStr.Copy( nIndex, nFoundIndex-nIndex );
+ if ( mbHelpText )
+ {
+ long nMaxWidth = maListBox.GetOutputSizePixel().Width()-30;
+ USHORT nLastIndex = 0;
+ USHORT nIndex = aTextParagraph.Search( ' ' );
+ while ( nIndex != STRING_NOTFOUND )
+ {
+ if ( maListBox.GetTextWidth( aTextParagraph, 0, nIndex ) > nMaxWidth )
+ {
+ if ( !nLastIndex )
+ nLastIndex = nIndex+1;
+ XubString aTempStr = aTextParagraph.Copy( 0, nLastIndex );
+ aTextParagraph.Erase( 0, nLastIndex );
+ maListBox.InsertEntry( aTempStr );
+ nLastIndex = 0;
+ }
+ else
+ nLastIndex = nIndex+1;
+ nIndex = aTextParagraph.Search( ' ', nLastIndex );
+ }
+
+ if ( maListBox.GetTextWidth( aTextParagraph, 0, nIndex ) > nMaxWidth )
+ {
+ if ( !nLastIndex )
+ nLastIndex = nIndex+1;
+ XubString aTempStr = aTextParagraph.Copy( 0, nLastIndex );
+ aTextParagraph.Erase( 0, nLastIndex );
+ maListBox.InsertEntry( aTempStr );
+ }
+ }
+ maListBox.InsertEntry( aTextParagraph );
+ nIndex = nFoundIndex+1;
+ }
+ while ( nFoundIndex != STRING_NOTFOUND );
+ maListBox.SetUpdateMode( TRUE );
+}
+
+// =======================================================================
+
+void DbgDialogTest( Window* pWindow )
+{
+ BOOL aAccelBuf[65536];
+ USHORT nChildCount = pWindow->GetChildCount();
+ Window* pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
+ Window* pChild;
+ Point aTabPos;
+
+ if ( !pGetChild )
+ return;
+
+ Rectangle* pRectAry = (Rectangle*)new long[(sizeof(Rectangle)*nChildCount)/sizeof(long)];
+ memset( aAccelBuf, 0, sizeof( aAccelBuf ) );
+ memset( pRectAry, 0, sizeof(Rectangle)*nChildCount );
+
+ if ( pWindow->IsDialog() )
+ {
+ BOOL bOKCancelButton = FALSE;
+ BOOL bDefPushButton = FALSE;
+ BOOL bButton = FALSE;
+ pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
+ while ( pGetChild )
+ {
+ pChild = pGetChild->ImplGetWindow();
+
+ if ( pChild->ImplIsPushButton() )
+ {
+ bButton = TRUE;
+ if ( (pChild->GetType() == WINDOW_OKBUTTON) || (pChild->GetType() == WINDOW_CANCELBUTTON) )
+ bOKCancelButton = TRUE;
+ if ( pChild->GetStyle() & WB_DEFBUTTON )
+ bDefPushButton = TRUE;
+ }
+
+ pGetChild = pGetChild->GetWindow( WINDOW_NEXT );
+ }
+
+ if ( bButton )
+ {
+ if ( !bOKCancelButton )
+ DbgError( "Dialogs should have a OK- or CancelButton" );
+ if ( !bDefPushButton )
+ DbgError( "Dialogs should have a Button with WB_DEFBUTTON" );
+ }
+ }
+
+ USHORT i = 0;
+ pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
+ while ( pGetChild )
+ {
+ pChild = pGetChild->ImplGetWindow();
+
+ if ( (pChild->GetType() != WINDOW_TABCONTROL) &&
+ (pChild->GetType() != WINDOW_TABPAGE) &&
+ (pChild->GetType() != WINDOW_GROUPBOX) )
+ {
+ XubString aText = pChild->GetText();
+ USHORT nAccelPos;
+ xub_Unicode cAccel = 0;
+ if ( aText.Len() )
+ {
+ nAccelPos = aText.Search( '~' );
+ if ( nAccelPos != STRING_NOTFOUND )
+ {
+ const International& rIntn = Application::GetSettings().GetInternational();
+ XubString aUpperText = rIntn.Upper( aText );
+ cAccel = aUpperText.GetChar( nAccelPos+1 );
+ if ( pChild->IsVisible() )
+ {
+ if ( aAccelBuf[cAccel] )
+ DbgOutTypef( DBG_OUT_ERROR, "Double mnemonic char: %c", cAccel );
+ else
+ aAccelBuf[cAccel] = TRUE;
+ }
+ }
+ }
+
+ if ( (pChild->GetType() == WINDOW_RADIOBUTTON) ||
+ (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) ||
+ (pChild->GetType() == WINDOW_CHECKBOX) ||
+ (pChild->GetType() == WINDOW_TRISTATEBOX) ||
+ (pChild->GetType() == WINDOW_PUSHBUTTON) )
+ {
+ if ( !cAccel && aText.Len() && !aText.EqualsAscii( "..." ) )
+ {
+ const char* pClass;
+ if ( pChild->GetType() == WINDOW_RADIOBUTTON )
+ pClass = "RadioButton";
+ else if ( pChild->GetType() == WINDOW_IMAGERADIOBUTTON )
+ pClass = "ImageRadioButton";
+ else if ( pChild->GetType() == WINDOW_CHECKBOX )
+ pClass = "CheckBox";
+ else if ( pChild->GetType() == WINDOW_TRISTATEBOX )
+ pClass = "TriStateBox";
+ else if ( pChild->GetType() == WINDOW_PUSHBUTTON )
+ pClass = "PushButton";
+ else
+ pClass = "Dontknow";
+ DbgOutTypef( DBG_OUT_ERROR,
+ "%s should have a mnemonic char (~): %s",
+ pClass,
+ ByteString( aText, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+ }
+
+ if ( pChild->GetType() == WINDOW_FIXEDTEXT )
+ {
+ if ( (pChild->GetSizePixel().Height() >= pChild->GetTextHeight()*2) &&
+ !(pChild->GetStyle() & WB_WORDBREAK) )
+ {
+ DbgOutTypef( DBG_OUT_ERROR,
+ "FixedText greater than one line, but WordBreak is not set: %s",
+ ByteString( aText, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+
+ if ( (i+1 < nChildCount) && aText.Len() )
+ {
+ Window* pTempChild = pGetChild->GetWindow( WINDOW_NEXT )->ImplGetWindow();
+ if ( (pTempChild->GetType() == WINDOW_EDIT) ||
+ (pTempChild->GetType() == WINDOW_MULTILINEEDIT) ||
+ (pTempChild->GetType() == WINDOW_SPINFIELD) ||
+ (pTempChild->GetType() == WINDOW_PATTERNFIELD) ||
+ (pTempChild->GetType() == WINDOW_NUMERICFIELD) ||
+ (pTempChild->GetType() == WINDOW_METRICFIELD) ||
+ (pTempChild->GetType() == WINDOW_CURRENCYFIELD) ||
+ (pTempChild->GetType() == WINDOW_DATEFIELD) ||
+ (pTempChild->GetType() == WINDOW_TIMEFIELD) ||
+ (pTempChild->GetType() == WINDOW_LISTBOX) ||
+ (pTempChild->GetType() == WINDOW_MULTILISTBOX) ||
+ (pTempChild->GetType() == WINDOW_COMBOBOX) ||
+ (pTempChild->GetType() == WINDOW_PATTERNBOX) ||
+ (pTempChild->GetType() == WINDOW_NUMERICBOX) ||
+ (pTempChild->GetType() == WINDOW_METRICBOX) ||
+ (pTempChild->GetType() == WINDOW_CURRENCYBOX) ||
+ (pTempChild->GetType() == WINDOW_DATEBOX) ||
+ (pTempChild->GetType() == WINDOW_TIMEBOX) )
+ {
+ if ( !cAccel )
+ {
+ DbgOutTypef( DBG_OUT_ERROR,
+ "Labels befor Fields (Edit,ListBox,...) should have a mnemonic char (~): %s",
+ ByteString( aText, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+ if ( !pTempChild->IsEnabled() && pChild->IsEnabled() )
+ {
+ DbgOutTypef( DBG_OUT_ERROR,
+ "Labels befor Fields (Edit,ListBox,...) should be disabled, when the field is disabled: %s",
+ ByteString( aText, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+ }
+ }
+ }
+
+ if ( pChild->GetType() == WINDOW_MULTILINEEDIT )
+ {
+ if ( !(pChild->GetStyle() & WB_IGNORETAB) )
+ {
+ DbgOutTypef( DBG_OUT_ERROR,
+ "MultiLineEdits in Dialogs should have the Style WB_IGNORETAB: %s",
+ ByteString( aText, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+ }
+
+ if ( (pChild->GetType() == WINDOW_RADIOBUTTON) ||
+ (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) ||
+ (pChild->GetType() == WINDOW_CHECKBOX) ||
+ (pChild->GetType() == WINDOW_TRISTATEBOX) ||
+ (pChild->GetType() == WINDOW_FIXEDTEXT) )
+ {
+ pChild->SetBackground( Wallpaper( Color( COL_LIGHTGREEN ) ) );
+ }
+
+ if ( pChild->IsVisible() )
+ {
+ BOOL bMaxWarning = FALSE;
+ if ( pChild->GetType() == WINDOW_NUMERICFIELD )
+ {
+ NumericField* pField = (NumericField*)pChild;
+ if ( pField->GetMax() == LONG_MAX )
+ bMaxWarning = TRUE;
+ }
+ else if ( pChild->GetType() == WINDOW_METRICFIELD )
+ {
+ MetricField* pField = (MetricField*)pChild;
+ if ( pField->GetMax() == LONG_MAX )
+ bMaxWarning = TRUE;
+ }
+ else if ( pChild->GetType() == WINDOW_CURRENCYFIELD )
+ {
+ CurrencyField* pField = (CurrencyField*)pChild;
+ if ( pField->GetMax() == LONG_MAX )
+ bMaxWarning = TRUE;
+ }
+ else if ( pChild->GetType() == WINDOW_TIMEFIELD )
+ {
+ TimeField* pField = (TimeField*)pChild;
+ if ( pField->GetMax() == Time( 23, 59, 59, 99 ) )
+ bMaxWarning = TRUE;
+ }
+ else if ( pChild->GetType() == WINDOW_DATEFIELD )
+ {
+ DateField* pField = (DateField*)pChild;
+ if ( pField->GetMax() == Date( 31, 12, 9999 ) )
+ bMaxWarning = TRUE;
+ }
+ else if ( pChild->GetType() == WINDOW_NUMERICBOX )
+ {
+ NumericBox* pBox = (NumericBox*)pChild;
+ if ( pBox->GetMax() == LONG_MAX )
+ bMaxWarning = TRUE;
+ }
+ else if ( pChild->GetType() == WINDOW_METRICBOX )
+ {
+ MetricBox* pBox = (MetricBox*)pChild;
+ if ( pBox->GetMax() == LONG_MAX )
+ bMaxWarning = TRUE;
+ }
+ else if ( pChild->GetType() == WINDOW_CURRENCYBOX )
+ {
+ CurrencyBox* pBox = (CurrencyBox*)pChild;
+ if ( pBox->GetMax() == LONG_MAX )
+ bMaxWarning = TRUE;
+ }
+ else if ( pChild->GetType() == WINDOW_TIMEBOX )
+ {
+ TimeBox* pBox = (TimeBox*)pChild;
+ if ( pBox->GetMax() == Time( 23, 59, 59, 99 ) )
+ bMaxWarning = TRUE;
+ }
+ else if ( pChild->GetType() == WINDOW_DATEBOX )
+ {
+ DateBox* pBox = (DateBox*)pChild;
+ if ( pBox->GetMax() == Date( 31, 12, 9999 ) )
+ bMaxWarning = TRUE;
+ }
+ if ( bMaxWarning )
+ {
+ DbgOutTypef( DBG_OUT_ERROR,
+ "No Max-Value is set: %s",
+ ByteString( aText, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+
+ if ( (pChild->GetType() == WINDOW_RADIOBUTTON) ||
+ (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) ||
+ (pChild->GetType() == WINDOW_CHECKBOX) ||
+ (pChild->GetType() == WINDOW_TRISTATEBOX) ||
+ (pChild->GetType() == WINDOW_PUSHBUTTON) ||
+ (pChild->GetType() == WINDOW_OKBUTTON) ||
+ (pChild->GetType() == WINDOW_CANCELBUTTON) ||
+ (pChild->GetType() == WINDOW_HELPBUTTON) ||
+ (pChild->GetType() == WINDOW_IMAGEBUTTON) ||
+ (pChild->GetType() == WINDOW_FIXEDTEXT) ||
+ (pChild->GetType() == WINDOW_EDIT) ||
+ (pChild->GetType() == WINDOW_MULTILINEEDIT) ||
+ (pChild->GetType() == WINDOW_SPINFIELD) ||
+ (pChild->GetType() == WINDOW_PATTERNFIELD) ||
+ (pChild->GetType() == WINDOW_NUMERICFIELD) ||
+ (pChild->GetType() == WINDOW_METRICFIELD) ||
+ (pChild->GetType() == WINDOW_CURRENCYFIELD) ||
+ (pChild->GetType() == WINDOW_DATEFIELD) ||
+ (pChild->GetType() == WINDOW_TIMEFIELD) ||
+ (pChild->GetType() == WINDOW_LISTBOX) ||
+ (pChild->GetType() == WINDOW_MULTILISTBOX) ||
+ (pChild->GetType() == WINDOW_COMBOBOX) ||
+ (pChild->GetType() == WINDOW_PATTERNBOX) ||
+ (pChild->GetType() == WINDOW_NUMERICBOX) ||
+ (pChild->GetType() == WINDOW_METRICBOX) ||
+ (pChild->GetType() == WINDOW_CURRENCYBOX) ||
+ (pChild->GetType() == WINDOW_DATEBOX) ||
+ (pChild->GetType() == WINDOW_TIMEBOX) )
+ {
+ Point aNewPos = pChild->GetPosPixel();
+ Rectangle aChildRect( aNewPos, pChild->GetSizePixel() );
+
+ if ( cAccel || (pChild->GetStyle() & WB_TABSTOP) ||
+ (pChild->GetType() == WINDOW_RADIOBUTTON) ||
+ (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) )
+ {
+ if ( (aNewPos.X() <= aTabPos.X()) && (aNewPos.Y() <= aTabPos.Y()) )
+ {
+ DbgOutTypef( DBG_OUT_ERROR,
+ "Possible wrong childorder for dialogcontrol: %s",
+ ByteString( aText, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+ aTabPos = aNewPos;
+ }
+
+ for ( USHORT j = 0; j < i; j++ )
+ {
+ if ( ((pRectAry[j].Right() != 0) || (pRectAry[j].Bottom() != 0)) &&
+ aChildRect.IsOver( pRectAry[j] ) )
+ {
+ DbgOutTypef( DBG_OUT_ERROR,
+ "Window overlaps with sibling window: %s",
+ ByteString( aText, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
+ }
+ }
+ pRectAry[i] = aChildRect;
+ }
+ }
+ }
+
+ pGetChild = pGetChild->GetWindow( WINDOW_NEXT );
+ i++;
+ }
+
+ delete pRectAry;
+}
+
+// =======================================================================
+
+void DbgPrintMsgBox( const char* pLine )
+{
+ if ( Application::IsDialogCancelEnabled() )
+ {
+#if defined( WNT )
+ if ( GetSystemMetrics( SM_DEBUG ) )
+ {
+ strcpy( aDbgOutBuf, pLine );
+ strcat( aDbgOutBuf, "\r\n" );
+ OutputDebugString( aDbgOutBuf );
+ return;
+ }
+#endif
+#ifdef UNX
+ fprintf( stderr, "%s\n", pLine );
+ return;
+#else
+ DbgPrintFile( pLine );
+ return;
+#endif
+ }
+
+ strcpy( aDbgOutBuf, pLine );
+ strcat( aDbgOutBuf, "\nAbort ? (Yes=abort / No=ignore / Cancel=core dump)" );
+
+ // Tracking beenden und Mouse freigeben, damit die Boxen nicht haengen
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maWinData.mpTrackWin )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
+ if ( pSVData->maWinData.mpCaptureWin )
+ pSVData->maWinData.mpCaptureWin->ReleaseMouse();
+
+#ifndef REMOTE_APPSERVER
+#if defined( WNT )
+ BOOL bOldCallTimer = pSVData->mbNoCallTimer;
+ pSVData->mbNoCallTimer = TRUE;
+ short nRet = (short)MessageBox( 0, (LPSTR)aDbgOutBuf, "Debug Output",
+ MB_TASKMODAL | MB_YESNOCANCEL |
+ MB_DEFBUTTON2 | MB_ICONSTOP );
+ MessageBeep( MB_ICONHAND );
+ pSVData->mbNoCallTimer = bOldCallTimer;
+ switch ( nRet )
+ {
+ case IDYES:
+ nRet = RET_YES;
+ break;
+ case IDNO:
+ nRet = RET_NO;
+ break;
+ case IDCANCEL:
+ nRet = RET_CANCEL;
+ break;
+ }
+#elif defined( OS2 )
+ BOOL bOldCallTimer = pSVData->mbNoCallTimer;
+ pSVData->mbNoCallTimer = TRUE;
+ PM_ULONG nRet = WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
+ (PSZ)aDbgOutBuf, (PSZ)"Debug Output", 0,
+ MB_APPLMODAL | MB_MOVEABLE |
+ MB_YESNOCANCEL | MB_DEFBUTTON2 |
+ MB_ERROR );
+ pSVData->mbNoCallTimer = bOldCallTimer;
+ switch ( nRet )
+ {
+ case MBID_YES:
+ nRet = RET_YES;
+ break;
+ case MBID_NO:
+ nRet = RET_NO;
+ break;
+ case MBID_CANCEL:
+ nRet = RET_CANCEL;
+ break;
+ }
+#else
+ USHORT nOldMode = Application::GetSystemWindowMode();
+ Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
+ ErrorBox aBox( Application::GetAppWindow(), WB_YES_NO_CANCEL | WB_DEF_NO,
+ UniString( aDbgOutBuf, RTL_TEXTENCODING_UTF8 ) );
+ aBox.SetText( String( RTL_CONSTASCII_USTRINGPARAM("Debug Output") ) );
+ Application::SetSystemWindowMode( nOldMode );
+ short nRet = aBox.Execute();
+#endif
+#else
+ USHORT nOldMode = Application::GetSystemWindowMode();
+ Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
+ ErrorBox aBox( Application::GetAppWindow(), WB_YES_NO_CANCEL | WB_DEF_NO,
+ UniString( aDbgOutBuf, RTL_TEXTENCODING_UTF8 ) );
+ aBox.SetText( String( RTL_CONSTASCII_USTRINGPARAM("Debug Output (Server)") ) );
+ Application::SetSystemWindowMode( nOldMode );
+ short nRet = aBox.Execute();
+#endif
+
+ if ( nRet == RET_YES )
+ GetpApp()->Abort( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debug-Utilities-Error" ) ) );
+ else if ( nRet == RET_CANCEL )
+ DbgCoreDump();
+}
+
+// -----------------------------------------------------------------------
+
+void DbgPrintWindow( const char* pLine )
+{
+ static BOOL bIn = FALSE;
+
+ // keine rekursiven Traces
+ if ( bIn )
+ return;
+ bIn = TRUE;
+
+ DbgWindow* pDbgWindow = ImplGetSVData()->maWinData.mpDbgWin;
+ if ( !pDbgWindow )
+ {
+ pDbgWindow = new DbgWindow;
+ ImplGetSVData()->maWinData.mpDbgWin = pDbgWindow;
+ }
+
+ pDbgWindow->InsertLine( XubString( pLine, RTL_TEXTENCODING_UTF8 ) );
+
+ bIn = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void DbgPrintShell( const char* pLine )
+{
+#if defined( WNT )
+ if ( GetSystemMetrics( SM_DEBUG ) )
+ {
+ strcpy( aDbgOutBuf, pLine );
+ strcat( aDbgOutBuf, "\r\n" );
+ OutputDebugString( aDbgOutBuf );
+ return;
+ }
+#endif
+#ifdef UNX
+ fprintf( stderr, "%s\n", pLine );
+ return;
+#endif
+
+ DbgPrintWindow( pLine );
+}
+
+// =======================================================================
+
+#if defined( REMOTE_APPSERVER ) || defined( WNT ) || defined( OS2 )
+void ImplDbgTestSolarMutex();
+#endif
+
+// =======================================================================
+
+void DbgGUIInit()
+{
+ DbgSetPrintMsgBox( DbgPrintMsgBox );
+ DbgSetPrintWindow( DbgPrintWindow );
+ DbgSetPrintShell( DbgPrintShell );
+#if defined( REMOTE_APPSERVER ) || defined( WNT ) || defined( OS2 )
+ DbgSetTestSolarMutex( ImplDbgTestSolarMutex );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void DbgGUIDeInit()
+{
+ DbgSetPrintMsgBox( NULL );
+ DbgSetPrintWindow( NULL );
+ DbgSetPrintShell( NULL );
+#if defined( REMOTE_APPSERVER ) || defined( WNT ) || defined( OS2 )
+ DbgSetTestSolarMutex( NULL );
+#endif
+
+ DbgWindow* pDbgWindow = ImplGetSVData()->maWinData.mpDbgWin;
+ if ( pDbgWindow )
+ delete pDbgWindow;
+}
+
+// -----------------------------------------------------------------------
+
+void DbgGUIStart()
+{
+ DbgData* pData = DbgGetData();
+
+ if ( pData )
+ {
+ DbgDialog* pDialog = new DbgDialog;
+ // Fuer den Debug-Dialog schalten wir Dialogtests aus
+ ULONG nOldFlags = pData->nTestFlags;
+ pData->nTestFlags &= ~DBG_TEST_DIALOG;
+ if ( !pDialog->Execute() )
+ pData->nTestFlags |= (nOldFlags & DBG_TEST_DIALOG);
+ delete pDialog;
+ }
+ else
+ {
+ ErrorBox( 0, WB_OK,
+ XubString( RTL_CONSTASCII_USTRINGPARAM( "TOOLS Library has no Debug-Routines" ) ) ).Execute();
+ }
+}
+
+#endif // DBG_UTIL
diff --git a/vcl/source/app/help.cxx b/vcl/source/app/help.cxx
new file mode 100644
index 000000000000..91343819c168
--- /dev/null
+++ b/vcl/source/app/help.cxx
@@ -0,0 +1,686 @@
+/*************************************************************************
+ *
+ * $RCSfile: help.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_HELP_CXX
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_HELPWIN_HXX
+#include <helpwin.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define HELPWINSTYLE_QUICK 0
+#define HELPWINSTYLE_BALLOON 1
+
+#define HELPTEXTMARGIN_QUICK 3
+#define HELPTEXTMARGIN_BALLOON 6
+
+#define HELPDELAY_NORMAL 1
+#define HELPDELAY_SHORT 2
+#define HELPDELAY_NONE 3
+
+// =======================================================================
+
+Help::Help()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::Start( ULONG )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::Start( const XubString& )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString Help::GetHelpText( ULONG nHelpId )
+{
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void Help::EnableContextHelp()
+{
+ ImplGetSVData()->maHelpData.mbContextHelp = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Help::DisableContextHelp()
+{
+ ImplGetSVData()->maHelpData.mbContextHelp = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::IsContextHelpEnabled()
+{
+ return ImplGetSVData()->maHelpData.mbContextHelp;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::StartContextHelp()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maHelpData.mbContextHelp )
+ {
+ Window* pWindow = pSVData->maWinData.mpFocusWin;
+ if ( pWindow )
+ {
+ Point aMousePos = pWindow->OutputToScreenPixel( pWindow->GetPointerPosPixel() );
+ HelpEvent aHelpEvent( aMousePos, HELPMODE_CONTEXT );
+ pWindow->RequestHelp( aHelpEvent );
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Help::EnableExtHelp()
+{
+ ImplGetSVData()->maHelpData.mbExtHelp = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Help::DisableExtHelp()
+{
+ ImplGetSVData()->maHelpData.mbExtHelp = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::IsExtHelpEnabled()
+{
+ return ImplGetSVData()->maHelpData.mbExtHelp;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::StartExtHelp()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maHelpData.mbExtHelp && !pSVData->maHelpData.mbExtHelpMode )
+ {
+ pSVData->maHelpData.mbExtHelpMode = TRUE;
+ pSVData->maHelpData.mbOldBalloonMode = pSVData->maHelpData.mbBalloonHelp;
+ pSVData->maHelpData.mbBalloonHelp = TRUE;
+ if ( pSVData->maWinData.mpAppWin )
+ pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::EndExtHelp()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maHelpData.mbExtHelp && pSVData->maHelpData.mbExtHelpMode )
+ {
+ pSVData->maHelpData.mbExtHelpMode = FALSE;
+ pSVData->maHelpData.mbBalloonHelp = pSVData->maHelpData.mbOldBalloonMode;
+ if ( pSVData->maWinData.mpAppWin )
+ pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::IsExtHelpActive()
+{
+ return ImplGetSVData()->maHelpData.mbExtHelpMode;
+}
+
+// -----------------------------------------------------------------------
+
+void Help::EnableBalloonHelp()
+{
+ ImplGetSVData()->maHelpData.mbBalloonHelp = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Help::DisableBalloonHelp()
+{
+ ImplGetSVData()->maHelpData.mbBalloonHelp = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::IsBalloonHelpEnabled()
+{
+ return ImplGetSVData()->maHelpData.mbBalloonHelp;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::ShowBalloon( Window* pParent,
+ const Point& rScreenPos,
+ const XubString& rHelpText )
+{
+ ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, 0,
+ rHelpText, ImplGetSVEmptyStr(), rScreenPos );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::ShowBalloon( Window* pParent,
+ const Point& rScreenPos, const Rectangle& rRect,
+ const XubString& rHelpText )
+{
+ ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, 0,
+ rHelpText, ImplGetSVEmptyStr(), rScreenPos, &rRect );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Help::EnableQuickHelp()
+{
+ ImplGetSVData()->maHelpData.mbQuickHelp = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Help::DisableQuickHelp()
+{
+ ImplGetSVData()->maHelpData.mbQuickHelp = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::IsQuickHelpEnabled()
+{
+ return ImplGetSVData()->maHelpData.mbQuickHelp;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Help::ShowQuickHelp( Window* pParent,
+ const Rectangle& rScreenRect,
+ const XubString& rHelpText,
+ const XubString& rLongHelpText,
+ USHORT nStyle )
+{
+ ImplShowHelpWindow( pParent, HELPWINSTYLE_QUICK, nStyle,
+ rHelpText, rLongHelpText,
+ pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rScreenRect );
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Help::ShowTip( Window* pParent, const Rectangle& rRect,
+ const XubString& rText, USHORT nStyle )
+{
+ USHORT nHelpWinStyle = HELPWINSTYLE_QUICK;
+ HelpTextWindow* pHelpWin = new HelpTextWindow( pParent, rText, nHelpWinStyle, nStyle );
+
+ Size aSz = pHelpWin->CalcOutSize();
+ pHelpWin->SetOutputSizePixel( aSz );
+ ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle,
+ pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rRect );
+ pHelpWin->ShowHelp( HELPDELAY_NONE );
+ return (ULONG)pHelpWin;
+}
+
+// -----------------------------------------------------------------------
+
+void Help::HideTip( ULONG nId )
+{
+ HelpTextWindow* pHelpWin = (HelpTextWindow*)nId;
+ Window* pFrameWindow = pHelpWin->ImplGetFrameWindow();
+ pHelpWin->Hide();
+ // Update ausloesen, damit ein Paint sofort ausgeloest wird, da
+ // wir den Hintergrund nicht sichern
+ pFrameWindow->ImplUpdateAll();
+ delete pHelpWin;
+}
+
+// =======================================================================
+
+HelpTextWindow::HelpTextWindow( Window* pParent, const XubString& rText, USHORT nHelpWinStyle, USHORT nStyle ) :
+ FloatingWindow( pParent->ImplGetFrameWindow(), 0 ),
+ maHelpText( rText )
+{
+ ImplSetMouseTransparent( TRUE );
+ mnHelpWinStyle = nHelpWinStyle;
+ mnStyle = nStyle;
+
+ EnableAlwaysOnTop();
+ EnableSaveBackground();
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetPointFont( rStyleSettings.GetHelpFont() );
+ SetTextColor( rStyleSettings.GetHelpTextColor() );
+ SetTextAlign( ALIGN_TOP );
+ SetBackground( Wallpaper( rStyleSettings.GetHelpColor() ) );
+ SetLineColor( COL_BLACK );
+ SetFillColor();
+
+ if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
+ {
+ Size aSize;
+ aSize.Height() = GetTextHeight();
+ if ( mnStyle & QUICKHELP_CTRLTEXT )
+ aSize.Width() = GetCtrlTextWidth( maHelpText );
+ else
+ aSize.Width() = GetTextWidth( maHelpText );
+ maTextRect = Rectangle( Point( HELPTEXTMARGIN_QUICK, HELPTEXTMARGIN_QUICK ), aSize );
+ }
+ else // HELPWINSTYLE_BALLOON
+ {
+ Point aTmpPoint;
+ USHORT nCharsInLine = 35 + ((maHelpText.Len()/100)*5);
+ XubString aXXX;
+ aXXX.Fill( nCharsInLine, 'x' ); // Durchschnittliche Breite, damit nicht jedes Fenster anders.
+ long nWidth = GetTextWidth( aXXX );
+ Size aTmpSize( nWidth, 0x7FFFFFFF );
+ Rectangle aTry1( aTmpPoint, aTmpSize );
+ USHORT nDrawFlags = TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK |
+ TEXT_DRAW_LEFT | TEXT_DRAW_TOP;
+ if ( mnStyle & QUICKHELP_CTRLTEXT )
+ nDrawFlags |= TEXT_DRAW_MNEMONIC;
+ Rectangle aTextRect = GetTextRect( aTry1, maHelpText, nDrawFlags );
+
+ // Spaeter mal eine geeignete Breite ermitteln...
+ maTextRect = aTextRect;
+
+ // Sicherheitsabstand...
+ maTextRect.SetPos( Point( HELPTEXTMARGIN_BALLOON, HELPTEXTMARGIN_BALLOON ) );
+ }
+
+ const HelpSettings& rHelpSettings = GetSettings().GetHelpSettings();
+ maShowTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) );
+ maHideTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) );
+ maHideTimer.SetTimeout( rHelpSettings.GetTipTimeout() );
+}
+
+// -----------------------------------------------------------------------
+
+HelpTextWindow::~HelpTextWindow()
+{
+ maShowTimer.Stop();
+ maHideTimer.Stop();
+
+ if ( maStatusText.Len() )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->mpApp->HideHelpStatusText();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HelpTextWindow::ImplShow()
+{
+ if ( maStatusText.Len() )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->mpApp->ShowHelpStatusText( maStatusText );
+ }
+ Show();
+ Update();
+}
+
+// -----------------------------------------------------------------------
+
+void HelpTextWindow::Paint( const Rectangle& )
+{
+ // Border zeichen
+ // .....
+
+ if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
+ {
+ if ( mnStyle & QUICKHELP_CTRLTEXT )
+ DrawCtrlText( maTextRect.TopLeft(), maHelpText );
+ else
+ DrawText( maTextRect.TopLeft(), maHelpText );
+ }
+ else // HELPWINSTYLE_BALLOON
+ {
+ USHORT nDrawFlags = TEXT_DRAW_MULTILINE|TEXT_DRAW_WORDBREAK|
+ TEXT_DRAW_LEFT|TEXT_DRAW_TOP;
+ if ( mnStyle & QUICKHELP_CTRLTEXT )
+ nDrawFlags |= TEXT_DRAW_MNEMONIC;
+ DrawText( maTextRect, maHelpText, nDrawFlags );
+ }
+
+ // Umrandung
+ Size aSz = GetOutputSizePixel();
+ DrawRect( Rectangle( Point(), aSz ) );
+ if ( mnHelpWinStyle == HELPWINSTYLE_BALLOON )
+ {
+ aSz.Width() -= 2;
+ aSz.Height() -= 2;
+ Color aColor( GetLineColor() );
+ SetLineColor( ( COL_GRAY ) );
+ DrawRect( Rectangle( Point( 1, 1 ), aSz ) );
+ SetLineColor( aColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HelpTextWindow::ShowHelp( USHORT nDelayMode )
+{
+ ULONG nTimeout = 0;
+ if ( nDelayMode != HELPDELAY_NONE )
+ {
+ // Im ExtendedHelp-Fall die Hilfe schneller anzeigen
+ if ( ImplGetSVData()->maHelpData.mbExtHelpMode )
+ nTimeout = 15;
+ else
+ {
+ const HelpSettings& rHelpSettings = GetSettings().GetHelpSettings();
+ if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
+ nTimeout = rHelpSettings.GetTipDelay();
+ else
+ nTimeout = rHelpSettings.GetBalloonDelay();
+ }
+
+ if ( nDelayMode == HELPDELAY_SHORT )
+ nTimeout /= 3;
+ }
+
+ maShowTimer.SetTimeout( nTimeout );
+ maShowTimer.Start();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( HelpTextWindow, TimerHdl, Timer*, pTimer)
+{
+ if ( pTimer == &maShowTimer )
+ {
+ ImplShow();
+ if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
+ {
+ // Auto-Hide nicht bei einem Tip-Fenster (ShowTip)
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( this == pSVData->maHelpData.mpHelpWin )
+ maHideTimer.Start();
+ }
+ }
+ else
+ {
+ Hide();
+ ImplDestroyHelpWindow();
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+Size HelpTextWindow::CalcOutSize() const
+{
+ Size aSz = maTextRect.GetSize();
+ aSz.Width() += 2*maTextRect.Left();
+ aSz.Height() += 2*maTextRect.Top();
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+void HelpTextWindow::RequestHelp( const HelpEvent& rHEvt )
+{
+ // Nur damit nicht von Window::RequestHelp() ein
+ // ShowQuickHelp/ShowBalloonHelp am HelpTextWindow aufgerufen wird.
+}
+
+// =======================================================================
+
+
+void ImplShowHelpWindow( Window* pParent, USHORT nHelpWinStyle, USHORT nStyle,
+ const XubString& rHelpText, const XubString& rStatusText,
+ const Point& rScreenPos, const Rectangle* pHelpArea )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ HelpTextWindow* pHelpWin = pSVData->maHelpData.mpHelpWin;
+ USHORT nDelayMode = HELPDELAY_NORMAL;
+ if ( pHelpWin )
+ {
+ DBG_ASSERT( pHelpWin != pParent, "HelpInHelp ?!" );
+
+ if ( ( pHelpWin->GetHelpText() != rHelpText ) ||
+ ( pHelpWin->GetWinStyle() != nHelpWinStyle ) ||
+ ( pHelpArea && ( pHelpWin->GetHelpArea() != *pHelpArea ) ) )
+ {
+ // Fenster wegnehmen wenn kein HelpText oder anderer HelpText oder
+ // anderer Modus.
+ if ( pHelpWin->IsVisible() )
+ nDelayMode = HELPDELAY_SHORT; // Wenn schon vorher Quick-Hilfe, dann jetzt auch schnell
+ pHelpWin = NULL;
+ ImplDestroyHelpWindow();
+ }
+ else if ( !pHelpWin->IsVisible() )
+ {
+ // Dann die Position der Maus annaehren...
+ ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea );
+ }
+ }
+
+ if ( !pHelpWin && rHelpText.Len() )
+ {
+ DBG_ASSERT( !pHelpWin, "Noch ein HelpWin ?!" );
+ pHelpWin = new HelpTextWindow( pParent, rHelpText, nHelpWinStyle, nStyle );
+ pSVData->maHelpData.mpHelpWin = pHelpWin;
+ pHelpWin->SetStatusText( rStatusText );
+ if ( pHelpArea )
+ pHelpWin->SetHelpArea( *pHelpArea );
+
+// Positionieren...
+ Size aSz = pHelpWin->CalcOutSize();
+ pHelpWin->SetOutputSizePixel( aSz );
+ ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea );
+ // Wenn nicht aus Window::RequestHelp, dann ohne Delay...
+ if ( !pSVData->maHelpData.mbRequestingHelp )
+ nDelayMode = HELPDELAY_NONE;
+ pHelpWin->ShowHelp( nDelayMode );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDestroyHelpWindow( BOOL bUpdate )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ HelpTextWindow* pHelpWin = pSVData->maHelpData.mpHelpWin;
+ if ( pHelpWin )
+ {
+ pSVData->maHelpData.mpHelpWin = NULL;
+ pHelpWin->Hide();
+ if ( bUpdate )
+ {
+ // Update ausloesen, damit ein Paint sofort ausgeloest wird, da
+ // wir den Hintergrund nicht sichern
+ Window* pFrameWindow = pHelpWin->ImplGetFrameWindow();
+ pFrameWindow->ImplUpdateAll();
+ }
+ delete pHelpWin;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSetHelpWindowPos( Window* pHelpWin, USHORT nHelpWinStyle, USHORT nStyle,
+ const Point& rPos, const Rectangle* pHelpArea )
+{
+ Point aPos = rPos;
+ Size aSz = pHelpWin->GetSizePixel();
+ Rectangle aScreenRect = pHelpWin->ImplGetFrameWindow()->GetDesktopRectPixel();
+ if ( nHelpWinStyle == HELPWINSTYLE_QUICK )
+ {
+ if ( !(nStyle & QUICKHELP_NOAUTOPOS) )
+ {
+ long nScreenHeight = aScreenRect.GetHeight();
+ aPos.X() -= 4;
+ if ( aPos.Y() > aScreenRect.Top()+nScreenHeight-(nScreenHeight/4) )
+ aPos.Y() -= aSz.Height()+4;
+ else
+ aPos.Y() += 21;
+ }
+ }
+ else
+ {
+ // Wenn es die Maus-Position ist, dann Fenster leicht versetzt
+ // anzeigen, damit MousePointer nicht das Hilfe-Fenster verdeckt
+ if ( aPos == pHelpWin->OutputToScreenPixel( pHelpWin->GetPointerPosPixel() ) )
+ {
+ aPos.X() += 12;
+ aPos.Y() += 16;
+ }
+ }
+
+ if ( nStyle & QUICKHELP_NOAUTOPOS )
+ {
+ if ( pHelpArea )
+ {
+ // Welche Position vom Rechteck?
+ aPos = pHelpArea->Center();
+
+ if ( nStyle & QUICKHELP_LEFT )
+ aPos.X() = pHelpArea->Left();
+ else if ( nStyle & QUICKHELP_RIGHT )
+ aPos.X() = pHelpArea->Right();
+
+ if ( nStyle & QUICKHELP_TOP )
+ aPos.Y() = pHelpArea->Top();
+ else if ( nStyle & QUICKHELP_BOTTOM )
+ aPos.Y() = pHelpArea->Bottom();
+ }
+
+ // Welche Richtung?
+ if ( nStyle & QUICKHELP_LEFT )
+ ;
+ else if ( nStyle & QUICKHELP_RIGHT )
+ aPos.X() -= aSz.Width();
+ else
+ aPos.X() -= aSz.Width()/2;
+
+ if ( nStyle & QUICKHELP_TOP )
+ ;
+ else if ( nStyle & QUICKHELP_BOTTOM )
+ aPos.Y() -= aSz.Height();
+ else
+ aPos.Y() -= aSz.Height()/2;
+ }
+
+ if ( aPos.X() < aScreenRect.Left() )
+ aPos.X() = aScreenRect.Left();
+ else if ( ( aPos.X() + aSz.Width() ) > aScreenRect.Right() )
+ aPos.X() = aScreenRect.Right() - aSz.Width();
+ if ( aPos.Y() < aScreenRect.Top() )
+ aPos.Y() = aScreenRect.Top();
+ else if ( ( aPos.Y() + aSz.Height() ) > aScreenRect.Bottom() )
+ aPos.Y() = aScreenRect.Bottom() - aSz.Height();
+
+ pHelpWin->SetPosPixel( aPos );
+}
diff --git a/vcl/source/app/idlemgr.cxx b/vcl/source/app/idlemgr.cxx
new file mode 100644
index 000000000000..e597d2680c1a
--- /dev/null
+++ b/vcl/source/app/idlemgr.cxx
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * $RCSfile: idlemgr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_IDLEMGR_CXX
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+
+#ifndef _SV_IDLEMGR_HXX
+#include <idlemgr.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+
+// =======================================================================
+
+struct ImplIdleData
+{
+ Link maIdleHdl;
+ USHORT mnPriority;
+ BOOL mbTimeout;
+};
+
+DECLARE_LIST( ImplIdleList, ImplIdleData* );
+
+#define IMPL_IDLETIMEOUT 350
+
+// =======================================================================
+
+ImplIdleMgr::ImplIdleMgr()
+{
+ mpIdleList = new ImplIdleList( 8, 8, 8 );
+
+ maTimer.SetTimeout( IMPL_IDLETIMEOUT );
+ maTimer.SetTimeoutHdl( LINK( this, ImplIdleMgr, TimeoutHdl ) );
+}
+
+// -----------------------------------------------------------------------
+
+ImplIdleMgr::~ImplIdleMgr()
+{
+ // Liste loeschen
+ ImplIdleData* pIdleData = mpIdleList->First();
+ while ( pIdleData )
+ {
+ delete pIdleData;
+ pIdleData = mpIdleList->Next();
+ }
+
+ delete mpIdleList;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplIdleMgr::InsertIdleHdl( const Link& rLink, USHORT nPriority )
+{
+ ULONG nPos = LIST_APPEND;
+ ImplIdleData* pIdleData = mpIdleList->First();
+ while ( pIdleData )
+ {
+ // Wenn Link schon existiert, dann gebe FALSE zurueck
+ if ( pIdleData->maIdleHdl == rLink )
+ return FALSE;
+
+ // Nach Prioritaet sortieren
+ if ( nPriority <= pIdleData->mnPriority )
+ nPos = mpIdleList->GetCurPos();
+
+ // Schleife nicht beenden, da noch
+ // geprueft werden muss, ob sich der Link
+ // schon in der Liste befindet
+
+ pIdleData = mpIdleList->Next();
+ }
+
+ pIdleData = new ImplIdleData;
+ pIdleData->maIdleHdl = rLink;
+ pIdleData->mnPriority = nPriority;
+ pIdleData->mbTimeout = FALSE;
+ mpIdleList->Insert( pIdleData, nPos );
+
+ // Wenn Timer noch nicht gestartet ist, dann starten
+ if ( !maTimer.IsActive() )
+ maTimer.Start();
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplIdleMgr::RemoveIdleHdl( const Link& rLink )
+{
+ ImplIdleData* pIdleData = mpIdleList->First();
+ while ( pIdleData )
+ {
+ if ( pIdleData->maIdleHdl == rLink )
+ {
+ mpIdleList->Remove();
+ delete pIdleData;
+ break;
+ }
+
+ pIdleData = mpIdleList->Next();
+ }
+
+ // keine Handdler mehr da
+ if ( !mpIdleList->Count() )
+ maTimer.Stop();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ImplIdleMgr, TimeoutHdl, Timer*, EMPTYARG )
+{
+ ImplIdleData* pIdleData = mpIdleList->First();
+ while ( pIdleData )
+ {
+ if ( !pIdleData->mbTimeout )
+ {
+ pIdleData->mbTimeout = TRUE;
+ pIdleData->maIdleHdl.Call( GetpApp() );
+ // Kann im Handler entfernt worden sein
+ if ( mpIdleList->GetPos( pIdleData ) != LIST_ENTRY_NOTFOUND )
+ pIdleData->mbTimeout = FALSE;
+ }
+
+ pIdleData = mpIdleList->Next();
+ }
+
+ return 0;
+}
diff --git a/vcl/source/app/makefile.mk b/vcl/source/app/makefile.mk
new file mode 100644
index 000000000000..ef981b4c4c1c
--- /dev/null
+++ b/vcl/source/app/makefile.mk
@@ -0,0 +1,123 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=vcl
+TARGET=app
+
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+CDEFS+=-DDLLSUFFIX=$(DLLSUFFIX)
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/access.obj \
+ $(SLO)$/config.obj \
+ $(SLO)$/dbggui.obj \
+ $(SLO)$/help.obj \
+ $(SLO)$/idlemgr.obj \
+ $(SLO)$/oldsv.obj \
+ $(SLO)$/resary.obj \
+ $(SLO)$/resmgr.obj \
+ $(SLO)$/settings.obj \
+ $(SLO)$/sound.obj \
+ $(SLO)$/stdtext.obj \
+ $(SLO)$/svapp.obj \
+ $(SLO)$/svdata.obj \
+ $(SLO)$/svmain.obj \
+ $(SLO)$/system.obj \
+ $(SLO)$/timer.obj \
+ $(SLO)$/unohelp.obj
+
+.IF "$(remote)"!=""
+EXCEPTIONSFILES= \
+ $(SLO)$/svapp.obj \
+ $(SLO)$/access.obj \
+ $(SLO)$/config.obj \
+ $(SLO)$/oldsv.obj \
+ $(SLO)$/help.obj \
+ $(SLO)$/resmgr.obj \
+ $(SLO)$/sound.obj \
+ $(SLO)$/svapp.obj \
+ $(SLO)$/svmain.obj \
+ $(SLO)$/system.obj \
+ $(SLO)$/idlemgr.obj \
+ $(SLO)$/timer.obj \
+ $(SLO)$/unohelp.obj
+.ELSE
+EXCEPTIONSFILES= $(SLO)$/svapp.obj \
+EXCEPTIONSFILES= $(SLO)$/unohelp.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
+
diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx
new file mode 100644
index 000000000000..663a2fe387f5
--- /dev/null
+++ b/vcl/source/app/settings.cxx
@@ -0,0 +1,1857 @@
+/*************************************************************************
+ *
+ * $RCSfile: settings.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SETTINGS_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+
+#ifndef _ISOLANG_HXX
+#include <tools/isolang.hxx>
+#endif
+
+#pragma hdrstop
+
+BOOL ImplCompareLocales( const ::com::sun::star::lang::Locale& L1, const ::com::sun::star::lang::Locale& L2 )
+{
+ return ( ( L1.Language == L2.Language ) &&
+ ( L1.Country == L2.Country ) &&
+ ( L1.Variant == L2.Variant ) );
+}
+
+// =======================================================================
+
+DBG_NAME( AllSettings );
+
+// =======================================================================
+
+#define STDSYS_STYLE (STYLE_OPTION_SCROLLARROW | \
+ STYLE_OPTION_SPINARROW | \
+ STYLE_OPTION_SPINUPDOWN | \
+ STYLE_OPTION_NOMNEMONICS)
+
+// =======================================================================
+
+ImplMachineData::ImplMachineData()
+{
+ mnRefCount = 1;
+ mnOptions = 0;
+ mnScreenOptions = 0;
+ mnPrintOptions = 0;
+ mnScreenRasterFontDeviation = 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImplMachineData::ImplMachineData( const ImplMachineData& rData )
+{
+ mnRefCount = 1;
+ mnOptions = rData.mnOptions;
+ mnScreenOptions = rData.mnScreenOptions;
+ mnPrintOptions = rData.mnPrintOptions;
+ mnScreenRasterFontDeviation = rData.mnScreenRasterFontDeviation;
+}
+
+// -----------------------------------------------------------------------
+
+MachineSettings::MachineSettings()
+{
+ mpData = new ImplMachineData();
+}
+
+// -----------------------------------------------------------------------
+
+MachineSettings::MachineSettings( const MachineSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "MachineSettings: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpData = rSet.mpData;
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+MachineSettings::~MachineSettings()
+{
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+const MachineSettings& MachineSettings::operator =( const MachineSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "MachineSettings: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rSet.mpData->mnRefCount++;
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+
+ mpData = rSet.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void MachineSettings::CopyData()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplMachineData( *mpData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MachineSettings::operator ==( const MachineSettings& rSet ) const
+{
+ if ( mpData == rSet.mpData )
+ return TRUE;
+
+ if ( (mpData->mnOptions == rSet.mpData->mnOptions) &&
+ (mpData->mnScreenOptions == rSet.mpData->mnScreenOptions) &&
+ (mpData->mnPrintOptions == rSet.mpData->mnPrintOptions) &&
+ (mpData->mnScreenRasterFontDeviation == rSet.mpData->mnScreenRasterFontDeviation) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, MachineSettings& rSet )
+{
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const MachineSettings& rSet )
+{
+ return rOStream;
+}
+
+// =======================================================================
+
+ImplMouseData::ImplMouseData()
+{
+ mnRefCount = 1;
+ mnOptions = 0;
+ mnDoubleClkTime = 500;
+ mnDoubleClkWidth = 2;
+ mnDoubleClkHeight = 2;
+ mnStartDragWidth = 2;
+ mnStartDragHeight = 2;
+ mnStartDragCode = MOUSE_LEFT;
+ mnDragMoveCode = 0;
+ mnDragCopyCode = KEY_MOD1;
+ mnDragLinkCode = KEY_SHIFT | KEY_MOD1;
+ mnContextMenuCode = MOUSE_RIGHT;
+ mnContextMenuClicks = 1;
+ mbContextMenuDown = FALSE;
+ mnScrollRepeat = 100;
+ mnButtonStartRepeat = 370;
+ mnButtonRepeat = 90;
+ mnActionDelay = 250;
+ mnMenuDelay = 150;
+ mnFollow = MOUSE_FOLLOW_MENU | MOUSE_FOLLOW_DDLIST;
+}
+
+// -----------------------------------------------------------------------
+
+ImplMouseData::ImplMouseData( const ImplMouseData& rData )
+{
+ mnRefCount = 1;
+ mnOptions = rData.mnOptions;
+ mnDoubleClkTime = rData.mnDoubleClkTime;
+ mnDoubleClkWidth = rData.mnDoubleClkWidth;
+ mnDoubleClkHeight = rData.mnDoubleClkHeight;
+ mnStartDragWidth = rData.mnStartDragWidth;
+ mnStartDragHeight = rData.mnStartDragHeight;
+ mnStartDragCode = rData.mnStartDragCode;
+ mnDragMoveCode = rData.mnDragMoveCode;
+ mnDragCopyCode = rData.mnDragCopyCode;
+ mnDragLinkCode = rData.mnDragLinkCode;
+ mnContextMenuCode = rData.mnContextMenuCode;
+ mnContextMenuClicks = rData.mnContextMenuClicks;
+ mbContextMenuDown = rData.mbContextMenuDown;
+ mnScrollRepeat = rData.mnScrollRepeat;
+ mnButtonStartRepeat = rData.mnButtonStartRepeat;
+ mnButtonRepeat = rData.mnButtonRepeat;
+ mnActionDelay = rData.mnActionDelay;
+ mnMenuDelay = rData.mnMenuDelay;
+ mnFollow = rData.mnFollow;
+}
+
+// -----------------------------------------------------------------------
+
+MouseSettings::MouseSettings()
+{
+ mpData = new ImplMouseData();
+}
+
+// -----------------------------------------------------------------------
+
+MouseSettings::MouseSettings( const MouseSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "MouseSettings: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpData = rSet.mpData;
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+MouseSettings::~MouseSettings()
+{
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+const MouseSettings& MouseSettings::operator =( const MouseSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "MouseSettings: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rSet.mpData->mnRefCount++;
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+
+ mpData = rSet.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void MouseSettings::CopyData()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplMouseData( *mpData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MouseSettings::operator ==( const MouseSettings& rSet ) const
+{
+ if ( mpData == rSet.mpData )
+ return TRUE;
+
+ if ( (mpData->mnOptions == rSet.mpData->mnOptions) &&
+ (mpData->mnDoubleClkTime == rSet.mpData->mnDoubleClkTime) &&
+ (mpData->mnDoubleClkWidth == rSet.mpData->mnDoubleClkWidth) &&
+ (mpData->mnDoubleClkHeight == rSet.mpData->mnDoubleClkHeight) &&
+ (mpData->mnStartDragWidth == rSet.mpData->mnStartDragWidth) &&
+ (mpData->mnStartDragHeight == rSet.mpData->mnStartDragHeight) &&
+ (mpData->mnStartDragCode == rSet.mpData->mnStartDragCode) &&
+ (mpData->mnDragMoveCode == rSet.mpData->mnDragMoveCode) &&
+ (mpData->mnDragCopyCode == rSet.mpData->mnDragCopyCode) &&
+ (mpData->mnDragLinkCode == rSet.mpData->mnDragLinkCode) &&
+ (mpData->mnContextMenuCode == rSet.mpData->mnContextMenuCode) &&
+ (mpData->mnContextMenuClicks == rSet.mpData->mnContextMenuClicks) &&
+ (mpData->mbContextMenuDown == rSet.mpData->mbContextMenuDown) &&
+ (mpData->mnScrollRepeat == rSet.mpData->mnScrollRepeat) &&
+ (mpData->mnButtonStartRepeat == rSet.mpData->mnButtonStartRepeat) &&
+ (mpData->mnButtonRepeat == rSet.mpData->mnButtonRepeat) &&
+ (mpData->mnActionDelay == rSet.mpData->mnActionDelay) &&
+ (mpData->mnMenuDelay == rSet.mpData->mnMenuDelay) &&
+ (mpData->mnFollow == rSet.mpData->mnFollow) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, MouseSettings& rSet )
+{
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const MouseSettings& rSet )
+{
+ return rOStream;
+}
+
+// =======================================================================
+
+ImplKeyboardData::ImplKeyboardData()
+{
+ mnRefCount = 1;
+ mnOptions = 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImplKeyboardData::ImplKeyboardData( const ImplKeyboardData& rData )
+{
+ mnRefCount = 1;
+ mnOptions = rData.mnOptions;
+}
+
+// -----------------------------------------------------------------------
+
+KeyboardSettings::KeyboardSettings()
+{
+ mpData = new ImplKeyboardData();
+}
+
+// -----------------------------------------------------------------------
+
+KeyboardSettings::KeyboardSettings( const KeyboardSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "KeyboardSettings: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpData = rSet.mpData;
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+KeyboardSettings::~KeyboardSettings()
+{
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+const KeyboardSettings& KeyboardSettings::operator =( const KeyboardSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "KeyboardSettings: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rSet.mpData->mnRefCount++;
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+
+ mpData = rSet.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void KeyboardSettings::CopyData()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplKeyboardData( *mpData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL KeyboardSettings::operator ==( const KeyboardSettings& rSet ) const
+{
+ if ( mpData == rSet.mpData )
+ return TRUE;
+
+ if ( (mpData->mnOptions == rSet.mpData->mnOptions) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, KeyboardSettings& rSet )
+{
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const KeyboardSettings& rSet )
+{
+ return rOStream;
+}
+
+// =======================================================================
+
+ImplStyleData::ImplStyleData()
+{
+ mnRefCount = 1;
+ mnScrollBarSize = 16;
+ mnSplitSize = 3;
+ mnSpinSize = 16;
+ mnIconHorzSpace = 50;
+ mnIconVertSpace = 40;
+ mnCursorSize = 2;
+#ifdef REMOTE_APPSERVER
+ mnCursorBlinkTime = STYLE_CURSOR_NOBLINKTIME;
+#else
+ mnCursorBlinkTime = 500;
+#endif
+ mnScreenZoom = 100;
+ mnScreenFontZoom = 100;
+ mnRadioButtonStyle = 0;
+ mnCheckBoxStyle = 0;
+ mnPushButtonStyle = 0;
+ mnTabControlStyle = 0;
+ mnLogoDisplayTime = LOGO_DISPLAYTIME_STARTTIME;
+ mnDragFullOptions = 0;
+ mnAnimationOptions = 0;
+ mnSelectionOptions = 0;
+ mnOptions = 0;
+
+ SetStandardStyles();
+}
+
+// -----------------------------------------------------------------------
+
+ImplStyleData::ImplStyleData( const ImplStyleData& rData ) :
+ maFaceColor( rData.maFaceColor ),
+ maCheckedColor( rData.maCheckedColor ),
+ maLightColor( rData.maLightColor ),
+ maLightBorderColor( rData.maLightBorderColor ),
+ maShadowColor( rData.maShadowColor ),
+ maDarkShadowColor( rData.maDarkShadowColor ),
+ maButtonTextColor( rData.maButtonTextColor ),
+ maRadioCheckTextColor( rData.maRadioCheckTextColor ),
+ maGroupTextColor( rData.maGroupTextColor ),
+ maLabelTextColor( rData.maLabelTextColor ),
+ maInfoTextColor( rData.maInfoTextColor ),
+ maWindowColor( rData.maWindowColor ),
+ maWindowTextColor( rData.maWindowTextColor ),
+ maDialogColor( rData.maDialogColor ),
+ maDialogTextColor( rData.maDialogTextColor ),
+ maWorkspaceColor( rData.maWorkspaceColor ),
+ maFieldColor( rData.maFieldColor ),
+ maFieldTextColor( rData.maFieldTextColor ),
+ maActiveColor( rData.maActiveColor ),
+ maActiveColor2( rData.maActiveColor2 ),
+ maActiveTextColor( rData.maActiveTextColor ),
+ maActiveBorderColor( rData.maActiveBorderColor ),
+ maDeactiveColor( rData.maDeactiveColor ),
+ maDeactiveColor2( rData.maDeactiveColor2 ),
+ maDeactiveTextColor( rData.maDeactiveTextColor ),
+ maDeactiveBorderColor( rData.maDeactiveBorderColor ),
+ maMenuColor( rData.maMenuColor ),
+ maMenuTextColor( rData.maMenuTextColor ),
+ maMenuHighlightColor( rData.maMenuHighlightColor ),
+ maMenuHighlightTextColor( rData.maMenuHighlightTextColor ),
+ maHighlightColor( rData.maHighlightColor ),
+ maHighlightTextColor( rData.maHighlightTextColor ),
+ maDisableColor( rData.maDisableColor ),
+ maHelpColor( rData.maHelpColor ),
+ maHelpTextColor( rData.maHelpTextColor ),
+ maLinkColor( rData.maLinkColor ),
+ maVisitedLinkColor( rData.maLinkColor ),
+ maHighlightLinkColor( rData.maLinkColor ),
+ maAppFont( rData.maAppFont ),
+ maHelpFont( rData.maAppFont ),
+ maTitleFont( rData.maTitleFont ),
+ maFloatTitleFont( rData.maFloatTitleFont ),
+ maMenuFont( rData.maMenuFont ),
+ maToolFont( rData.maToolFont ),
+ maGroupFont( rData.maGroupFont ),
+ maLabelFont( rData.maLabelFont ),
+ maInfoFont( rData.maInfoFont ),
+ maRadioCheckFont( rData.maRadioCheckFont ),
+ maPushButtonFont( rData.maPushButtonFont ),
+ maFieldFont( rData.maFieldFont ),
+ maIconFont( rData.maIconFont )
+{
+ mnRefCount = 1;
+ mnBorderSize = rData.mnBorderSize;
+ mnTitleHeight = rData.mnTitleHeight;
+ mnFloatTitleHeight = rData.mnFloatTitleHeight;
+ mnTearOffTitleHeight = rData.mnTearOffTitleHeight;
+ mnMenuBarHeight = rData.mnMenuBarHeight;
+ mnScrollBarSize = rData.mnScrollBarSize;
+ mnSplitSize = rData.mnSplitSize;
+ mnSpinSize = rData.mnSpinSize;
+ mnIconHorzSpace = rData.mnIconHorzSpace;
+ mnIconVertSpace = rData.mnIconVertSpace;
+ mnCursorSize = rData.mnCursorSize;
+ mnCursorBlinkTime = rData.mnCursorBlinkTime;
+ mnScreenZoom = rData.mnScreenZoom;
+ mnScreenFontZoom = rData.mnScreenFontZoom;
+ mnRadioButtonStyle = rData.mnRadioButtonStyle;
+ mnCheckBoxStyle = rData.mnCheckBoxStyle;
+ mnPushButtonStyle = rData.mnPushButtonStyle;
+ mnTabControlStyle = rData.mnTabControlStyle;
+ mnLogoDisplayTime = rData.mnLogoDisplayTime;
+ mnDragFullOptions = rData.mnDragFullOptions;
+ mnAnimationOptions = rData.mnAnimationOptions;
+ mnSelectionOptions = rData.mnSelectionOptions;
+ mnOptions = rData.mnOptions;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplStyleData::SetStandardStyles()
+{
+ Font aStdFont( FAMILY_SWISS, Size( 0, 8 ) );
+ aStdFont.SetCharSet( gsl_getSystemTextEncoding() );
+ aStdFont.SetWeight( WEIGHT_NORMAL );
+ aStdFont.SetName( XubString( RTL_CONSTASCII_USTRINGPARAM( "MS Sans Serif;Geneva;Helv;WarpSans;Tahoma;Arial Unicode MS;Dialog;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Arial;Times;Times New Roman;Interface System" ) ) );
+ maAppFont = aStdFont;
+ maHelpFont = aStdFont;
+ maMenuFont = aStdFont;
+ maToolFont = aStdFont;
+ maGroupFont = aStdFont;
+ maLabelFont = aStdFont;
+ maInfoFont = aStdFont;
+ maRadioCheckFont = aStdFont;
+ maPushButtonFont = aStdFont;
+ maFieldFont = aStdFont;
+ maIconFont = aStdFont;
+ maFloatTitleFont = aStdFont;
+ aStdFont.SetWeight( WEIGHT_BOLD );
+ aStdFont.SetName( XubString( RTL_CONSTASCII_USTRINGPARAM( "MS Sans Serif;Charcoal;Chicago;Geneva;Helv;WarpSans;Tahoma;Arial Unicode MS;Dialog;Lucida;Helvetica;MS Sans Serif;Arial;Times;Times New Roman;Interface System" ) ) );
+ maTitleFont = aStdFont;
+
+ maFaceColor = Color( COL_LIGHTGRAY );
+ maCheckedColor = Color( 0xCC, 0xCC, 0xCC );
+ maLightColor = Color( COL_WHITE );
+ maLightBorderColor = Color( COL_LIGHTGRAY );
+ maShadowColor = Color( COL_GRAY );
+ maDarkShadowColor = Color( COL_BLACK );
+ maButtonTextColor = Color( COL_BLACK );
+ maRadioCheckTextColor = Color( COL_BLACK );
+ maGroupTextColor = Color( COL_BLACK );
+ maLabelTextColor = Color( COL_BLACK );
+ maInfoTextColor = Color( COL_BLACK );
+ maWindowColor = Color( COL_WHITE );
+ maWindowTextColor = Color( COL_BLACK );
+ maDialogColor = Color( COL_LIGHTGRAY );
+ maDialogTextColor = Color( COL_BLACK );
+ maWorkspaceColor = Color( COL_GRAY );
+ maFieldColor = Color( COL_WHITE );
+ maFieldTextColor = Color( COL_BLACK );
+ maActiveColor = Color( COL_BLUE );
+ maActiveColor2 = Color( COL_BLACK );
+ maActiveTextColor = Color( COL_WHITE );
+ maActiveBorderColor = Color( COL_LIGHTGRAY );
+ maDeactiveColor = Color( COL_GRAY );
+ maDeactiveColor2 = Color( COL_BLACK );
+ maDeactiveTextColor = Color( COL_LIGHTGRAY );
+ maDeactiveBorderColor = Color( COL_LIGHTGRAY );
+ maMenuColor = Color( COL_LIGHTGRAY );
+ maMenuTextColor = Color( COL_BLACK );
+ maMenuHighlightColor = Color( COL_BLUE );
+ maMenuHighlightTextColor = Color( COL_WHITE );
+ maHighlightColor = Color( COL_BLUE );
+ maHighlightTextColor = Color( COL_WHITE );
+ maDisableColor = Color( COL_GRAY );
+ maHelpColor = Color( 0xFF, 0xFF, 0xE0 );
+ maHelpTextColor = Color( COL_BLACK );
+ maLinkColor = Color( COL_BLUE );
+ maVisitedLinkColor = Color( COL_RED );
+ maHighlightLinkColor = Color( COL_LIGHTBLUE );
+
+ mnRadioButtonStyle &= ~STYLE_RADIOBUTTON_STYLE;
+ mnCheckBoxStyle &= ~STYLE_CHECKBOX_STYLE;
+ mnPushButtonStyle &= ~STYLE_PUSHBUTTON_STYLE;
+ mnTabControlStyle = 0;
+
+ mnOptions &= ~(STYLE_OPTION_SYSTEMSTYLE | STDSYS_STYLE);
+ mnBorderSize = 1;
+ mnTitleHeight = 18;
+ mnFloatTitleHeight = 13;
+ mnTearOffTitleHeight = 8;
+ mnMenuBarHeight = 14;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplStyleData::SetStandardWinStyles()
+{
+ SetStandardStyles();
+
+ mnRadioButtonStyle &= ~STYLE_RADIOBUTTON_STYLE;
+ mnRadioButtonStyle |= STYLE_RADIOBUTTON_WIN;
+ mnCheckBoxStyle &= ~STYLE_CHECKBOX_STYLE;
+ mnCheckBoxStyle |= STYLE_CHECKBOX_WIN;
+ mnPushButtonStyle &= ~STYLE_PUSHBUTTON_STYLE;
+ mnPushButtonStyle |= STYLE_PUSHBUTTON_WIN;
+ mnTabControlStyle = 0;
+
+ mnOptions &= ~(STYLE_OPTION_SYSTEMSTYLE | STDSYS_STYLE);
+ mnOptions |= STYLE_OPTION_WINSTYLE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplStyleData::SetStandardOS2Styles()
+{
+ Font aStdFont( FAMILY_SWISS, Size( 0, 9 ) );
+ aStdFont.SetCharSet( gsl_getSystemTextEncoding() );
+ aStdFont.SetWeight( WEIGHT_NORMAL );
+ aStdFont.SetName( XubString( RTL_CONSTASCII_USTRINGPARAM( "WarpSans;MS Sans Serif;Geneva;Helv;Tahoma;Arial Unicode MS;Dialog;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Arial;Times;Times New Roman;Interface System" ) ) );
+ maAppFont = aStdFont;
+ maHelpFont = aStdFont;
+ maToolFont = aStdFont;
+ maGroupFont = aStdFont;
+ maLabelFont = aStdFont;
+ maInfoFont = aStdFont;
+ maRadioCheckFont = aStdFont;
+ maPushButtonFont = aStdFont;
+ maFieldFont = aStdFont;
+ maIconFont = aStdFont;
+ maFloatTitleFont = aStdFont;
+ aStdFont.SetWeight( WEIGHT_BOLD );
+ aStdFont.SetName( XubString( RTL_CONSTASCII_USTRINGPARAM( "WarpSans;MS Sans Serif;Charcoal;Chicago;Geneva;Helv;Tahoma;Arial Unicode MS;Dialog;Lucida;Helvetica;MS Sans Serif;Arial;Times;Times New Roman;Interface System" ) ) );
+ maMenuFont = aStdFont;
+ maTitleFont = aStdFont;
+
+ maFaceColor = Color( COL_LIGHTGRAY );
+ maCheckedColor = Color( 0xCC, 0xCC, 0xCC );
+ maLightColor = Color( COL_WHITE );
+ maLightBorderColor = Color( COL_LIGHTGRAY );
+ maShadowColor = Color( COL_GRAY );
+ maDarkShadowColor = Color( COL_BLACK );
+ maButtonTextColor = Color( COL_BLACK );
+ maRadioCheckTextColor = Color( COL_BLACK );
+ maGroupTextColor = Color( COL_BLACK );
+ maLabelTextColor = Color( COL_BLACK );
+ maInfoTextColor = Color( COL_BLACK );
+ maWindowColor = Color( COL_WHITE );
+ maWindowTextColor = Color( COL_BLACK );
+ maDialogColor = Color( COL_LIGHTGRAY );
+ maDialogTextColor = Color( COL_BLACK );
+ maWorkspaceColor = Color( COL_GRAY );
+ maFieldColor = Color( COL_WHITE );
+ maFieldTextColor = Color( COL_BLACK );
+ maActiveColor = Color( COL_BLUE );
+ maActiveColor2 = Color( COL_BLACK );
+ maActiveTextColor = Color( COL_WHITE );
+ maActiveBorderColor = Color( COL_LIGHTGRAY );
+ maDeactiveColor = Color( COL_GRAY );
+ maDeactiveColor2 = Color( COL_BLACK );
+ maDeactiveTextColor = Color( COL_LIGHTGRAY );
+ maDeactiveBorderColor = Color( COL_LIGHTGRAY );
+ maMenuColor = Color( COL_LIGHTGRAY );
+ maMenuTextColor = Color( COL_BLACK );
+ maMenuHighlightColor = Color( COL_BLUE );
+ maMenuHighlightTextColor = Color( COL_WHITE );
+ maHighlightColor = Color( COL_GRAY );
+ maHighlightTextColor = Color( COL_WHITE );
+ maDisableColor = Color( COL_GRAY );
+ maHelpColor = Color( 0xFF, 0xFF, 0xE0 );
+ maHelpTextColor = Color( COL_BLACK );
+
+ mnRadioButtonStyle &= ~STYLE_RADIOBUTTON_STYLE;
+ mnRadioButtonStyle |= STYLE_RADIOBUTTON_OS2;
+ mnCheckBoxStyle &= ~STYLE_CHECKBOX_STYLE;
+ mnCheckBoxStyle |= STYLE_CHECKBOX_OS2;
+ mnPushButtonStyle &= ~STYLE_PUSHBUTTON_STYLE;
+ mnPushButtonStyle |= STYLE_PUSHBUTTON_OS2;
+ mnTabControlStyle = STYLE_TABCONTROL_SINGLELINE |
+ STYLE_TABCONTROL_COLOR;
+
+ mnOptions &= ~(STYLE_OPTION_SYSTEMSTYLE | STDSYS_STYLE);
+ mnOptions |= STYLE_OPTION_OS2STYLE | STYLE_OPTION_SPINARROW;
+ mnBorderSize = 1;
+ mnTitleHeight = 18;
+ mnFloatTitleHeight = 13;
+ mnTearOffTitleHeight = 8;
+ mnMenuBarHeight = 14;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplStyleData::SetStandardMacStyles()
+{
+ Font aStdFont( FAMILY_SWISS, Size( 0, 8 ) );
+ aStdFont.SetCharSet( gsl_getSystemTextEncoding() );
+ aStdFont.SetWeight( WEIGHT_NORMAL );
+ aStdFont.SetName( XubString( RTL_CONSTASCII_USTRINGPARAM( "Geneva;MS Sans Serif;Helv;Tahoma;Arial Unicode MS;WarpSans;Dialog;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Arial;Times;Times New Roman;Interface System" ) ) );
+ maAppFont = aStdFont;
+ maHelpFont = aStdFont;
+ maToolFont = aStdFont;
+ maPushButtonFont = aStdFont;
+ maGroupFont = aStdFont;
+ maLabelFont = aStdFont;
+ maInfoFont = aStdFont;
+ maRadioCheckFont = aStdFont;
+ maFieldFont = aStdFont;
+ maIconFont = aStdFont;
+ maFloatTitleFont = aStdFont;
+ aStdFont.SetName( XubString( RTL_CONSTASCII_USTRINGPARAM( "Charcoal;Chicago;Geneva;MS Sans Serif;Helv;Tahoma;Arial Unicode MS;WarpSans;Dialog;Lucida;Helvetica;MS Sans Serif;Arial;Times;Times New Roman;Interface System" ) ) );
+// aStdFont.SetWeight( WEIGHT_BOLD );
+ maMenuFont = aStdFont;
+ maTitleFont = aStdFont;
+// maPushButtonFont = aStdFont;
+// maGroupFont = aStdFont;
+// maLabelFont = aStdFont;
+
+ maFaceColor = Color( COL_LIGHTGRAY );
+ maCheckedColor = Color( 0x99, 0x99, 0x99 );
+ maLightColor = Color( COL_WHITE );
+ maLightBorderColor = Color( COL_LIGHTGRAY );
+ maShadowColor = Color( COL_GRAY );
+ maDarkShadowColor = Color( COL_BLACK );
+ maButtonTextColor = Color( COL_BLACK );
+ maRadioCheckTextColor = Color( COL_BLACK );
+ maGroupTextColor = Color( COL_BLACK );
+ maLabelTextColor = Color( COL_BLACK );
+ maInfoTextColor = Color( COL_BLACK );
+ maWindowColor = Color( COL_WHITE );
+ maWindowTextColor = Color( COL_BLACK );
+ maDialogColor = Color( COL_LIGHTGRAY );
+ maDialogTextColor = Color( COL_BLACK );
+ maWorkspaceColor = Color( COL_GRAY );
+ maFieldColor = Color( COL_WHITE );
+ maFieldTextColor = Color( COL_BLACK );
+ maActiveColor = Color( COL_LIGHTGRAY );
+ maActiveColor2 = Color( COL_LIGHTGRAY );
+ maActiveTextColor = Color( COL_BLACK );
+ maActiveBorderColor = Color( COL_LIGHTGRAY );
+ maDeactiveColor = Color( COL_LIGHTGRAY );
+ maDeactiveColor2 = Color( COL_LIGHTGRAY );
+ maDeactiveTextColor = Color( COL_GRAY );
+ maDeactiveBorderColor = Color( COL_LIGHTGRAY );
+ maMenuColor = Color( COL_LIGHTGRAY );
+ maMenuTextColor = Color( COL_BLACK );
+ maMenuHighlightColor = Color( COL_BLUE );
+ maMenuHighlightTextColor = Color( COL_WHITE );
+ maHighlightColor = Color( COL_BLUE );
+ maHighlightTextColor = Color( COL_WHITE );
+ maDisableColor = Color( COL_GRAY );
+ maHelpColor = Color( 0xFF, 0xFF, 0xE0 );
+ maHelpTextColor = Color( COL_BLACK );
+
+ mnRadioButtonStyle &= ~STYLE_RADIOBUTTON_STYLE;
+ mnRadioButtonStyle |= STYLE_RADIOBUTTON_MAC;
+ mnCheckBoxStyle &= ~STYLE_CHECKBOX_STYLE;
+ mnCheckBoxStyle |= STYLE_CHECKBOX_MAC;
+ mnPushButtonStyle &= ~STYLE_PUSHBUTTON_STYLE;
+ mnPushButtonStyle |= STYLE_PUSHBUTTON_MAC;
+ mnTabControlStyle = 0;
+
+ mnOptions &= ~(STYLE_OPTION_SYSTEMSTYLE | STDSYS_STYLE);
+ mnOptions |= STYLE_OPTION_MACSTYLE | STYLE_OPTION_NOMNEMONICS | STYLE_OPTION_SPINUPDOWN;
+ mnBorderSize = 2;
+ mnTitleHeight = 16;
+ mnFloatTitleHeight = 12;
+ mnTearOffTitleHeight = 7;
+ mnMenuBarHeight = 14;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplStyleData::SetStandardUnixStyles()
+{
+ SetStandardStyles();
+
+ maActiveColor = Color( 182, 77, 121 );
+ maActiveColor2 = Color( 182, 77, 121 );
+ maActiveTextColor = Color( COL_WHITE );
+ maActiveBorderColor = Color( 182, 77, 121 );
+ maDeactiveColor = Color( 174, 178, 199 );
+ maDeactiveColor2 = Color( 174, 178, 199 );
+ maDeactiveTextColor = Color( COL_BLACK );
+ maDeactiveBorderColor = Color( 174, 178, 199 );
+
+ mnRadioButtonStyle &= ~STYLE_RADIOBUTTON_STYLE;
+ mnRadioButtonStyle |= STYLE_RADIOBUTTON_UNIX;
+ mnCheckBoxStyle &= ~STYLE_CHECKBOX_STYLE;
+ mnCheckBoxStyle |= STYLE_CHECKBOX_UNIX;
+ mnPushButtonStyle &= ~STYLE_PUSHBUTTON_STYLE;
+ mnPushButtonStyle |= STYLE_PUSHBUTTON_UNIX;
+ mnTabControlStyle = 0;
+
+ mnOptions &= ~(STYLE_OPTION_SYSTEMSTYLE | STDSYS_STYLE);
+ mnOptions |= STYLE_OPTION_UNIXSTYLE;
+
+ mnBorderSize = 3;
+}
+
+// -----------------------------------------------------------------------
+
+StyleSettings::StyleSettings()
+{
+ mpData = new ImplStyleData();
+}
+
+// -----------------------------------------------------------------------
+
+StyleSettings::StyleSettings( const StyleSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "StyleSettings: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpData = rSet.mpData;
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+StyleSettings::~StyleSettings()
+{
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+void StyleSettings::Set3DColors( const Color& rColor )
+{
+ CopyData();
+ mpData->maFaceColor = rColor;
+ mpData->maLightBorderColor = rColor;
+ mpData->maDarkShadowColor = Color( COL_BLACK );
+ if ( rColor != Color( COL_LIGHTGRAY ) )
+ {
+ mpData->maLightColor = rColor;
+ mpData->maShadowColor = rColor;
+ mpData->maLightColor.IncreaseLuminance( 64 );
+ mpData->maShadowColor.DecreaseLuminance( 64 );
+ ULONG nRed = mpData->maLightColor.GetRed();
+ ULONG nGreen = mpData->maLightColor.GetGreen();
+ ULONG nBlue = mpData->maLightColor.GetBlue();
+ nRed += (ULONG)(mpData->maShadowColor.GetRed());
+ nGreen += (ULONG)(mpData->maShadowColor.GetGreen());
+ nBlue += (ULONG)(mpData->maShadowColor.GetBlue());
+ mpData->maCheckedColor = Color( (BYTE)(nRed/2), (BYTE)(nGreen/2), (BYTE)(nBlue/2) );
+ }
+ else
+ {
+ mpData->maCheckedColor = Color( 0x99, 0x99, 0x99 );
+ mpData->maLightColor = Color( COL_WHITE );
+ mpData->maShadowColor = Color( COL_GRAY );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StyleSettings::SetStandardStyles()
+{
+ CopyData();
+ mpData->SetStandardStyles();
+}
+
+// -----------------------------------------------------------------------
+
+void StyleSettings::SetStandardWinStyles()
+{
+ CopyData();
+ mpData->SetStandardWinStyles();
+}
+
+// -----------------------------------------------------------------------
+
+void StyleSettings::SetStandardOS2Styles()
+{
+ CopyData();
+ mpData->SetStandardOS2Styles();
+}
+
+// -----------------------------------------------------------------------
+
+void StyleSettings::SetStandardMacStyles()
+{
+ CopyData();
+ mpData->SetStandardMacStyles();
+}
+
+// -----------------------------------------------------------------------
+
+void StyleSettings::SetStandardUnixStyles()
+{
+ CopyData();
+ mpData->SetStandardUnixStyles();
+}
+
+// -----------------------------------------------------------------------
+
+const StyleSettings& StyleSettings::operator =( const StyleSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "StyleSettings: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rSet.mpData->mnRefCount++;
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+
+ mpData = rSet.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void StyleSettings::CopyData()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplStyleData( *mpData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL StyleSettings::operator ==( const StyleSettings& rSet ) const
+{
+ if ( mpData == rSet.mpData )
+ return TRUE;
+
+ if ( (mpData->mnOptions == rSet.mpData->mnOptions) &&
+ (mpData->mnLogoDisplayTime == rSet.mpData->mnLogoDisplayTime) &&
+ (mpData->mnDragFullOptions == rSet.mpData->mnDragFullOptions) &&
+ (mpData->mnAnimationOptions == rSet.mpData->mnAnimationOptions) &&
+ (mpData->mnSelectionOptions == rSet.mpData->mnSelectionOptions) &&
+ (mpData->mnCursorSize == rSet.mpData->mnCursorSize) &&
+ (mpData->mnCursorBlinkTime == rSet.mpData->mnCursorBlinkTime) &&
+ (mpData->mnBorderSize == rSet.mpData->mnBorderSize) &&
+ (mpData->mnTitleHeight == rSet.mpData->mnTitleHeight) &&
+ (mpData->mnFloatTitleHeight == rSet.mpData->mnFloatTitleHeight) &&
+ (mpData->mnTearOffTitleHeight == rSet.mpData->mnTearOffTitleHeight) &&
+ (mpData->mnMenuBarHeight == rSet.mpData->mnMenuBarHeight) &&
+ (mpData->mnScrollBarSize == rSet.mpData->mnScrollBarSize) &&
+ (mpData->mnSplitSize == rSet.mpData->mnSplitSize) &&
+ (mpData->mnSpinSize == rSet.mpData->mnSpinSize) &&
+ (mpData->mnIconHorzSpace == rSet.mpData->mnIconHorzSpace) &&
+ (mpData->mnIconVertSpace == rSet.mpData->mnIconVertSpace) &&
+ (mpData->mnScreenZoom == rSet.mpData->mnScreenZoom) &&
+ (mpData->mnScreenFontZoom == rSet.mpData->mnScreenFontZoom) &&
+ (mpData->mnRadioButtonStyle == rSet.mpData->mnRadioButtonStyle) &&
+ (mpData->mnCheckBoxStyle == rSet.mpData->mnCheckBoxStyle) &&
+ (mpData->mnPushButtonStyle == rSet.mpData->mnPushButtonStyle) &&
+ (mpData->mnTabControlStyle == rSet.mpData->mnTabControlStyle) &&
+ (mpData->maFaceColor == rSet.mpData->maFaceColor) &&
+ (mpData->maCheckedColor == rSet.mpData->maCheckedColor) &&
+ (mpData->maLightColor == rSet.mpData->maLightColor) &&
+ (mpData->maLightBorderColor == rSet.mpData->maLightBorderColor) &&
+ (mpData->maShadowColor == rSet.mpData->maShadowColor) &&
+ (mpData->maDarkShadowColor == rSet.mpData->maDarkShadowColor) &&
+ (mpData->maButtonTextColor == rSet.mpData->maButtonTextColor) &&
+ (mpData->maRadioCheckTextColor == rSet.mpData->maRadioCheckTextColor) &&
+ (mpData->maGroupTextColor == rSet.mpData->maGroupTextColor) &&
+ (mpData->maLabelTextColor == rSet.mpData->maLabelTextColor) &&
+ (mpData->maInfoTextColor == rSet.mpData->maInfoTextColor) &&
+ (mpData->maWindowColor == rSet.mpData->maWindowColor) &&
+ (mpData->maWindowTextColor == rSet.mpData->maWindowTextColor) &&
+ (mpData->maDialogColor == rSet.mpData->maDialogColor) &&
+ (mpData->maDialogTextColor == rSet.mpData->maDialogTextColor) &&
+ (mpData->maWorkspaceColor == rSet.mpData->maWorkspaceColor) &&
+ (mpData->maFieldColor == rSet.mpData->maFieldColor) &&
+ (mpData->maFieldTextColor == rSet.mpData->maFieldTextColor) &&
+ (mpData->maActiveColor == rSet.mpData->maActiveColor) &&
+ (mpData->maActiveColor2 == rSet.mpData->maActiveColor2) &&
+ (mpData->maActiveTextColor == rSet.mpData->maActiveTextColor) &&
+ (mpData->maActiveBorderColor == rSet.mpData->maActiveBorderColor) &&
+ (mpData->maDeactiveColor == rSet.mpData->maDeactiveColor) &&
+ (mpData->maDeactiveColor2 == rSet.mpData->maDeactiveColor2) &&
+ (mpData->maDeactiveTextColor == rSet.mpData->maDeactiveTextColor) &&
+ (mpData->maDeactiveBorderColor == rSet.mpData->maDeactiveBorderColor) &&
+ (mpData->maMenuColor == rSet.mpData->maMenuColor) &&
+ (mpData->maMenuTextColor == rSet.mpData->maMenuTextColor) &&
+ (mpData->maMenuHighlightColor == rSet.mpData->maMenuHighlightColor) &&
+ (mpData->maMenuHighlightTextColor == rSet.mpData->maMenuHighlightTextColor) &&
+ (mpData->maHighlightColor == rSet.mpData->maHighlightColor) &&
+ (mpData->maHighlightTextColor == rSet.mpData->maHighlightTextColor) &&
+ (mpData->maDisableColor == rSet.mpData->maDisableColor) &&
+ (mpData->maHelpColor == rSet.mpData->maHelpColor) &&
+ (mpData->maHelpTextColor == rSet.mpData->maHelpTextColor) &&
+ (mpData->maLinkColor == rSet.mpData->maLinkColor) &&
+ (mpData->maVisitedLinkColor == rSet.mpData->maVisitedLinkColor) &&
+ (mpData->maHighlightLinkColor == rSet.mpData->maHighlightLinkColor) &&
+ (mpData->maAppFont == rSet.mpData->maAppFont) &&
+ (mpData->maHelpFont == rSet.mpData->maHelpFont) &&
+ (mpData->maTitleFont == rSet.mpData->maTitleFont) &&
+ (mpData->maFloatTitleFont == rSet.mpData->maFloatTitleFont) &&
+ (mpData->maMenuFont == rSet.mpData->maMenuFont) &&
+ (mpData->maToolFont == rSet.mpData->maToolFont) &&
+ (mpData->maGroupFont == rSet.mpData->maGroupFont) &&
+ (mpData->maLabelFont == rSet.mpData->maLabelFont) &&
+ (mpData->maInfoFont == rSet.mpData->maInfoFont) &&
+ (mpData->maRadioCheckFont == rSet.mpData->maRadioCheckFont) &&
+ (mpData->maPushButtonFont == rSet.mpData->maPushButtonFont) &&
+ (mpData->maFieldFont == rSet.mpData->maFieldFont) &&
+ (mpData->maIconFont == rSet.mpData->maIconFont) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, StyleSettings& rSet )
+{
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const StyleSettings& rSet )
+{
+ return rOStream;
+}
+
+// =======================================================================
+
+ImplMiscData::ImplMiscData()
+{
+ mnRefCount = 1;
+ mnTwoDigitYearStart = 1930;
+}
+
+// -----------------------------------------------------------------------
+
+ImplMiscData::ImplMiscData( const ImplMiscData& rData )
+{
+ mnRefCount = 1;
+ mnTwoDigitYearStart = rData.mnTwoDigitYearStart;
+}
+
+// -----------------------------------------------------------------------
+
+MiscSettings::MiscSettings()
+{
+ mpData = new ImplMiscData();
+}
+
+// -----------------------------------------------------------------------
+
+MiscSettings::MiscSettings( const MiscSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "MiscSettings: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpData = rSet.mpData;
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+MiscSettings::~MiscSettings()
+{
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+const MiscSettings& MiscSettings::operator =( const MiscSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "MiscSettings: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rSet.mpData->mnRefCount++;
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+
+ mpData = rSet.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void MiscSettings::CopyData()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplMiscData( *mpData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MiscSettings::operator ==( const MiscSettings& rSet ) const
+{
+ if ( mpData == rSet.mpData )
+ return TRUE;
+
+ if ( (mpData->mnTwoDigitYearStart == rSet.mpData->mnTwoDigitYearStart ) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, MiscSettings& rSet )
+{
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const MiscSettings& rSet )
+{
+ return rOStream;
+}
+
+// =======================================================================
+
+ImplSoundData::ImplSoundData()
+{
+ mnRefCount = 1;
+ mnOptions = 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImplSoundData::ImplSoundData( const ImplSoundData& rData )
+{
+ mnRefCount = 1;
+ mnOptions = rData.mnOptions;
+}
+
+// -----------------------------------------------------------------------
+
+SoundSettings::SoundSettings()
+{
+ mpData = new ImplSoundData();
+}
+
+// -----------------------------------------------------------------------
+
+SoundSettings::SoundSettings( const SoundSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "SoundSettings: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpData = rSet.mpData;
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+SoundSettings::~SoundSettings()
+{
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+const SoundSettings& SoundSettings::operator =( const SoundSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "SoundSettings: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rSet.mpData->mnRefCount++;
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+
+ mpData = rSet.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void SoundSettings::CopyData()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplSoundData( *mpData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SoundSettings::operator ==( const SoundSettings& rSet ) const
+{
+ if ( mpData == rSet.mpData )
+ return TRUE;
+
+ if ( (mpData->mnOptions == rSet.mpData->mnOptions) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, SoundSettings& rSet )
+{
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const SoundSettings& rSet )
+{
+ return rOStream;
+}
+
+// =======================================================================
+
+ImplNotificationData::ImplNotificationData()
+{
+ mnRefCount = 1;
+ mnOptions = 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImplNotificationData::ImplNotificationData( const ImplNotificationData& rData )
+{
+ mnRefCount = 1;
+ mnOptions = rData.mnOptions;
+}
+
+// -----------------------------------------------------------------------
+
+NotificationSettings::NotificationSettings()
+{
+ mpData = new ImplNotificationData();
+}
+
+// -----------------------------------------------------------------------
+
+NotificationSettings::NotificationSettings( const NotificationSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "NotificationSettings: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpData = rSet.mpData;
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+NotificationSettings::~NotificationSettings()
+{
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+const NotificationSettings& NotificationSettings::operator =( const NotificationSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "NotificationSettings: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rSet.mpData->mnRefCount++;
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+
+ mpData = rSet.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void NotificationSettings::CopyData()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplNotificationData( *mpData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL NotificationSettings::operator ==( const NotificationSettings& rSet ) const
+{
+ if ( mpData == rSet.mpData )
+ return TRUE;
+
+ if ( (mpData->mnOptions == rSet.mpData->mnOptions) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, NotificationSettings& rSet )
+{
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const NotificationSettings& rSet )
+{
+ return rOStream;
+}
+
+// =======================================================================
+
+ImplHelpData::ImplHelpData()
+{
+ mnRefCount = 1;
+ mnOptions = 0;
+ mnTipDelay = 500;
+ mnTipTimeout = 3000;
+ mnBalloonDelay = 1500;
+}
+
+// -----------------------------------------------------------------------
+
+ImplHelpData::ImplHelpData( const ImplHelpData& rData )
+{
+ mnRefCount = 1;
+ mnOptions = rData.mnOptions;
+ mnTipDelay = rData.mnTipDelay;
+ mnTipTimeout = rData.mnTipTimeout;
+ mnBalloonDelay = rData.mnBalloonDelay;
+}
+
+// -----------------------------------------------------------------------
+
+HelpSettings::HelpSettings()
+{
+ mpData = new ImplHelpData();
+}
+
+// -----------------------------------------------------------------------
+
+HelpSettings::HelpSettings( const HelpSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "HelpSettings: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpData = rSet.mpData;
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+HelpSettings::~HelpSettings()
+{
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+const HelpSettings& HelpSettings::operator =( const HelpSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "HelpSettings: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rSet.mpData->mnRefCount++;
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+
+ mpData = rSet.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void HelpSettings::CopyData()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplHelpData( *mpData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL HelpSettings::operator ==( const HelpSettings& rSet ) const
+{
+ if ( mpData == rSet.mpData )
+ return TRUE;
+
+ if ( (mpData->mnOptions == rSet.mpData->mnOptions ) &&
+ (mpData->mnTipDelay == rSet.mpData->mnTipDelay ) &&
+ (mpData->mnTipTimeout == rSet.mpData->mnTipTimeout ) &&
+ (mpData->mnBalloonDelay == rSet.mpData->mnBalloonDelay ) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, HelpSettings& rSet )
+{
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const HelpSettings& rSet )
+{
+ return rOStream;
+}
+
+// =======================================================================
+
+ImplAllSettingsData::ImplAllSettingsData()
+{
+ mnRefCount = 1;
+ mnSystemUpdate = SETTINGS_ALLSETTINGS;
+ mnWindowUpdate = SETTINGS_ALLSETTINGS;
+}
+
+// -----------------------------------------------------------------------
+
+ImplAllSettingsData::ImplAllSettingsData( const ImplAllSettingsData& rData ) :
+ maMouseSettings( rData.maMouseSettings ),
+ maKeyboardSettings( rData.maKeyboardSettings ),
+ maStyleSettings( rData.maStyleSettings ),
+ maMiscSettings( rData.maMiscSettings ),
+ maSoundSettings( rData.maSoundSettings ),
+ maNotificationSettings( rData.maNotificationSettings ),
+ maHelpSettings( rData.maHelpSettings ),
+ maInternational( rData.maInternational )
+{
+ mnRefCount = 1;
+ mnSystemUpdate = rData.mnSystemUpdate;
+ mnWindowUpdate = rData.mnWindowUpdate;
+}
+
+// -----------------------------------------------------------------------
+
+AllSettings::AllSettings()
+{
+ DBG_CTOR( AllSettings, NULL );
+
+ mpData = new ImplAllSettingsData();
+}
+
+// -----------------------------------------------------------------------
+
+AllSettings::AllSettings( const AllSettings& rSet )
+{
+ DBG_CTOR( AllSettings, NULL );
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "Settings: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpData = rSet.mpData;
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+AllSettings::~AllSettings()
+{
+ DBG_DTOR( AllSettings, NULL );
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+const AllSettings& AllSettings::operator =( const AllSettings& rSet )
+{
+ DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFE, "AllSettings: RefCount overflow" );
+ DBG_CHKTHIS( AllSettings, NULL );
+ DBG_CHKOBJ( &rSet, AllSettings, NULL );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rSet.mpData->mnRefCount++;
+
+ // Daten loeschen, wenn letzte Referenz
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+
+ mpData = rSet.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+void AllSettings::CopyData()
+{
+ DBG_CHKTHIS( AllSettings, NULL );
+
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplAllSettingsData( *mpData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ULONG AllSettings::Update( ULONG nFlags, const AllSettings& rSet )
+{
+ DBG_CHKTHIS( AllSettings, NULL );
+ DBG_CHKOBJ( &rSet, AllSettings, NULL );
+
+ ULONG nChangeFlags = 0;
+
+ if ( nFlags & SETTINGS_MACHINE )
+ {
+ if ( mpData->maMachineSettings != rSet.mpData->maMachineSettings )
+ {
+ CopyData();
+ mpData->maMachineSettings = rSet.mpData->maMachineSettings;
+ nChangeFlags |= SETTINGS_MACHINE;
+ }
+ }
+
+ if ( nFlags & SETTINGS_MOUSE )
+ {
+ if ( mpData->maMouseSettings != rSet.mpData->maMouseSettings )
+ {
+ CopyData();
+ mpData->maMouseSettings = rSet.mpData->maMouseSettings;
+ nChangeFlags |= SETTINGS_MOUSE;
+ }
+ }
+
+ if ( nFlags & SETTINGS_KEYBOARD )
+ {
+ if ( mpData->maKeyboardSettings != rSet.mpData->maKeyboardSettings )
+ {
+ CopyData();
+ mpData->maKeyboardSettings = rSet.mpData->maKeyboardSettings;
+ nChangeFlags |= SETTINGS_KEYBOARD;
+ }
+ }
+
+ if ( nFlags & SETTINGS_STYLE )
+ {
+ if ( mpData->maStyleSettings != rSet.mpData->maStyleSettings )
+ {
+ CopyData();
+ mpData->maStyleSettings = rSet.mpData->maStyleSettings;
+ nChangeFlags |= SETTINGS_STYLE;
+ }
+ }
+
+ if ( nFlags & SETTINGS_MISC )
+ {
+ if ( mpData->maMiscSettings != rSet.mpData->maMiscSettings )
+ {
+ CopyData();
+ mpData->maMiscSettings = rSet.mpData->maMiscSettings;
+ nChangeFlags |= SETTINGS_MISC;
+ }
+ }
+
+ if ( nFlags & SETTINGS_SOUND )
+ {
+ if ( mpData->maSoundSettings != rSet.mpData->maSoundSettings )
+ {
+ CopyData();
+ mpData->maSoundSettings = rSet.mpData->maSoundSettings;
+ nChangeFlags |= SETTINGS_SOUND;
+ }
+ }
+
+ if ( nFlags & SETTINGS_NOTIFICATION )
+ {
+ if ( mpData->maNotificationSettings != rSet.mpData->maNotificationSettings )
+ {
+ CopyData();
+ mpData->maNotificationSettings = rSet.mpData->maNotificationSettings;
+ nChangeFlags |= SETTINGS_NOTIFICATION;
+ }
+ }
+
+ if ( nFlags & SETTINGS_HELP )
+ {
+ if ( mpData->maHelpSettings != rSet.mpData->maHelpSettings )
+ {
+ CopyData();
+ mpData->maHelpSettings = rSet.mpData->maHelpSettings;
+ nChangeFlags |= SETTINGS_HELP;
+ }
+ }
+
+ if ( nFlags & SETTINGS_INTERNATIONAL )
+ {
+ if ( mpData->maInternational != rSet.mpData->maInternational )
+ {
+ CopyData();
+ mpData->maInternational = rSet.mpData->maInternational;
+ nChangeFlags |= SETTINGS_INTERNATIONAL;
+ // Will be calculated in GetLocale();
+ mpData->maLocale = ::com::sun::star::lang::Locale();
+ }
+
+ // Da System-International-Klassen intern in der
+ // International-Klasse automatisch bei Systemaenderungen geaendert
+ // werden, wird der Status innerhalb einer System-International-
+ // Aenderung anders ermittelt, da ansonsten die App nicht
+ // mitbekommt, das sich etwas geaendert hat
+ if ( (mpData->maInternational.GetLanguage() == LANGUAGE_SYSTEM) ||
+ (mpData->maInternational.GetFormatLanguage() == LANGUAGE_SYSTEM) )
+ {
+ if ( ImplGetSVData()->maAppData.mbIntnChanged )
+ nChangeFlags |= SETTINGS_INTERNATIONAL;
+ }
+ }
+
+ if ( nFlags & SETTINGS_LOCALE )
+ {
+ if ( !ImplCompareLocales( mpData->maLocale, rSet.mpData->maLocale ) )
+ {
+ CopyData();
+ mpData->maLocale = rSet.mpData->maLocale;
+ nChangeFlags |= SETTINGS_LOCALE;
+ }
+ }
+
+ return nChangeFlags;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG AllSettings::GetChangeFlags( const AllSettings& rSet ) const
+{
+ DBG_CHKTHIS( AllSettings, NULL );
+ DBG_CHKOBJ( &rSet, AllSettings, NULL );
+
+ ULONG nChangeFlags = 0;
+
+ if ( mpData->maMachineSettings != rSet.mpData->maMachineSettings )
+ nChangeFlags |= SETTINGS_MACHINE;
+
+ if ( mpData->maMouseSettings != rSet.mpData->maMouseSettings )
+ nChangeFlags |= SETTINGS_MOUSE;
+
+ if ( mpData->maKeyboardSettings != rSet.mpData->maKeyboardSettings )
+ nChangeFlags |= SETTINGS_KEYBOARD;
+
+ if ( mpData->maStyleSettings != rSet.mpData->maStyleSettings )
+ nChangeFlags |= SETTINGS_STYLE;
+
+ if ( mpData->maMiscSettings != rSet.mpData->maMiscSettings )
+ nChangeFlags |= SETTINGS_MISC;
+
+ if ( mpData->maSoundSettings != rSet.mpData->maSoundSettings )
+ nChangeFlags |= SETTINGS_SOUND;
+
+ if ( mpData->maNotificationSettings != rSet.mpData->maNotificationSettings )
+ nChangeFlags |= SETTINGS_NOTIFICATION;
+
+ if ( mpData->maHelpSettings != rSet.mpData->maHelpSettings )
+ nChangeFlags |= SETTINGS_HELP;
+
+ if ( mpData->maInternational != rSet.mpData->maInternational )
+ nChangeFlags |= SETTINGS_INTERNATIONAL;
+
+ // Da System-International-Klassen intern in der
+ // International-Klasse automatisch bei Systemaenderungen geaendert
+ // werden, wird der Status innerhalb einer System-International-
+ // Aenderung anders ermittelt, da ansonsten die App nicht
+ // mitbekommt, das sich etwas geaendert hat
+ if ( (mpData->maInternational.GetLanguage() == LANGUAGE_SYSTEM) ||
+ (mpData->maInternational.GetFormatLanguage() == LANGUAGE_SYSTEM) )
+ {
+ if ( ImplGetSVData()->maAppData.mbIntnChanged )
+ nChangeFlags |= SETTINGS_INTERNATIONAL;
+ }
+
+ return nChangeFlags;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL AllSettings::operator ==( const AllSettings& rSet ) const
+{
+ DBG_CHKTHIS( AllSettings, NULL );
+ DBG_CHKOBJ( &rSet, AllSettings, NULL );
+
+ if ( mpData == rSet.mpData )
+ return TRUE;
+
+ if ( (mpData->maMachineSettings == rSet.mpData->maMachineSettings) &&
+ (mpData->maMouseSettings == rSet.mpData->maMouseSettings) &&
+ (mpData->maKeyboardSettings == rSet.mpData->maKeyboardSettings) &&
+ (mpData->maStyleSettings == rSet.mpData->maStyleSettings) &&
+ (mpData->maMiscSettings == rSet.mpData->maMiscSettings) &&
+ (mpData->maSoundSettings == rSet.mpData->maSoundSettings) &&
+ (mpData->maNotificationSettings == rSet.mpData->maNotificationSettings) &&
+ (mpData->maHelpSettings == rSet.mpData->maHelpSettings) &&
+ (mpData->maInternational == rSet.mpData->maInternational) &&
+ (mpData->mnSystemUpdate == rSet.mpData->mnSystemUpdate) &&
+ (mpData->mnWindowUpdate == rSet.mpData->mnWindowUpdate) )
+ {
+ // special treatment for Locale, because maLocale is only
+ // initialized after first call of GetLocale().
+ ::com::sun::star::lang::Locale aEmptyLocale;
+ if ( ( ImplCompareLocales( mpData->maLocale, aEmptyLocale ) && ImplCompareLocales( rSet.mpData->maLocale, aEmptyLocale ) )
+ || ImplCompareLocales( GetLocale(), rSet.GetLocale() ) )
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+const ::com::sun::star::lang::Locale& AllSettings::GetLocale() const
+{
+ if ( !mpData->maLocale.Language.getLength() )
+ {
+ String aLanguage, aCountry;
+ ConvertLanguageToIsoNames( mpData->maInternational.GetLanguage(), aLanguage, aCountry );
+ ((AllSettings*)this)->mpData->maLocale.Language = aLanguage;
+ ((AllSettings*)this)->mpData->maLocale.Country = aCountry;
+ }
+ return mpData->maLocale;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, AllSettings& rSet )
+{
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const AllSettings& rSet )
+{
+ return rOStream;
+}
diff --git a/vcl/source/app/sound.cxx b/vcl/source/app/sound.cxx
new file mode 100644
index 000000000000..c055f95fdd50
--- /dev/null
+++ b/vcl/source/app/sound.cxx
@@ -0,0 +1,361 @@
+/*************************************************************************
+ *
+ * $RCSfile: sound.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SOUND_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALSOUND_HXX
+#include <salsound.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#else
+#include <rmwindow.hxx>
+#include <rmsound.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _NEW_HXX
+#include <tools/new.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_SALSOUND_HXX
+#include <salsound.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_SOUND_HXX
+#include <sound.hxx>
+#endif
+
+#pragma hdrstop
+
+// ----------------------
+// - SalSound-Callback -
+// ----------------------
+
+#ifndef REMOTE_APPSERVER
+
+void SalSoundProc( void* pInst, SoundNotification eNotification, ULONG nError )
+{
+ ( (Sound*) pInst )->ImplNotify( eNotification, nError );
+}
+
+#endif
+
+// ---------
+// - Sound -
+// ---------
+
+Sound::Sound( Window* pWindow ) :
+ mpWindow ( pWindow ),
+ mpSoundData ( NULL ),
+ mnDataLen ( 0UL ),
+ mnSoundLen ( 0UL ),
+ mnStartTime ( 0UL ),
+ mnPlayTime ( SOUND_PLAYALL ),
+ mnErrorCode ( 0UL ),
+ meNotification ( SOUND_NOTIFY_SUCCESS ),
+ mbPlaying ( FALSE ),
+ mbLoopMode ( FALSE )
+{
+#ifndef REMOTE_APPSERVER
+
+ mpSound = new SalSound;
+ mpSound->Create();
+
+ if( mpSound->IsValid() )
+ mpSound->SetNotifyProc( this, SalSoundProc );
+
+#else
+
+ mpSound = new RMSound;
+ mpSound->Create( this );
+
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+Sound::~Sound()
+{
+ if( mpSoundData )
+ SvMemFree( mpSoundData );
+
+ delete mpSound;
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::ImplNotify( SoundNotification eNotification, ULONG nError )
+{
+ meNotification = eNotification;
+ mbPlaying = FALSE;
+
+ if( SOUND_NOTIFY_ERROR == meNotification )
+ mnErrorCode = nError;
+
+ Notify();
+
+ if( maNotifyHdl.IsSet() )
+ maNotifyHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::Notify()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Sound::SetSoundName( const XubString& rSoundName )
+{
+ BOOL bRet;
+
+ if( !rSoundName.Len() )
+ {
+ mnDataLen = 0UL;
+ mnSoundLen = 0UL;
+ mnStartTime = 0UL;
+ mnPlayTime = SOUND_PLAYALL;
+ mnErrorCode = 0UL;
+ meNotification = SOUND_NOTIFY_SUCCESS;
+ mbPlaying = FALSE;
+ mbLoopMode = FALSE;
+ bRet = TRUE;
+
+#ifdef REMOTE_APPSERVER
+ if( mpSoundData )
+ {
+ SvMemFree( mpSoundData );
+ mpSoundData = NULL;
+ }
+
+ // if IFace is init., destroy it and create a new one
+ if( maSoundName.Len() )
+ {
+ delete mpSound;
+ mpSound = new RMSound;
+ mpSound->Create( this );
+ }
+#else
+ mpSound->Init( NULL, rSoundName, mnSoundLen );
+#endif
+ }
+ else if( mpSound->IsValid() )
+ bRet = mpSound->Init( NULL, rSoundName, mnSoundLen );
+ else
+ bRet = FALSE;
+
+ maSoundName = rSoundName;
+
+ // if sound could not be initialized, but we've gotten _no_
+ // notification ==> create common error notification
+ if( !bRet && !mnErrorCode )
+ ImplNotify( SOUND_NOTIFY_ERROR, SOUNDERR_GENERAL_ERROR );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Sound::SetSoundData( const BYTE* pSoundData, ULONG nDataLen )
+{
+ BOOL bRet;
+
+ if( mpSoundData )
+ SvMemFree( mpSoundData );
+
+ mpSoundData = (BYTE*) SvMemAlloc( mnDataLen = nDataLen );
+ HMEMCPY( mpSoundData, pSoundData, nDataLen );
+
+ if( mpSound->IsValid() )
+ bRet = mpSound->Init( NULL, mpSoundData, mnDataLen, mnSoundLen );
+ else
+ bRet = FALSE;
+
+ // if sound could not be initialized, but we've gotten _no_
+ // notification ==> create common error notification
+ if( !bRet && !mnErrorCode )
+ ImplNotify( SOUND_NOTIFY_ERROR, SOUNDERR_GENERAL_ERROR );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::SetStartTime( ULONG nStartTime )
+{
+ mnStartTime = nStartTime;
+
+#ifdef REMOTE_APPSERVER
+ mpSound->SetStartTime( nStartTime );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::SetPlayTime( ULONG nPlayTime )
+{
+ mnPlayTime = nPlayTime;
+
+#ifdef REMOTE_APPSERVER
+ mpSound->SetStartTime( nPlayTime );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::SetLoopMode( BOOL bLoop )
+{
+ mbLoopMode = bLoop;
+
+#ifdef REMOTE_APPSERVER
+ mpSound->SetStartTime( bLoop );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::ClearError()
+{
+ mnErrorCode = 0;
+
+#ifdef REMOTE_APPSERVER
+ mpSound->ClearError();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::Play()
+{
+ BOOL bRet;
+
+ if( mpSound->IsValid() && !mnErrorCode )
+ {
+#ifndef REMOTE_APPSERVER
+ mpSound->Play( mnStartTime, mnPlayTime, mbLoopMode );
+#else
+ mpSound->Play();
+#endif
+
+ mbPlaying = TRUE;
+ }
+ else
+ bRet = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::Stop()
+{
+ mbPlaying = FALSE;
+
+ if( mpSound->IsValid() )
+ mpSound->Stop();
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::Pause()
+{
+ mbPlaying = FALSE;
+
+ if( mpSound->IsValid() )
+ mpSound->Pause();
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::Beep( SoundType eType, Window* pWindow )
+{
+ if( !pWindow )
+ ImplGetDefaultWindow()->ImplGetFrame()->Beep( eType );
+ else
+ pWindow->ImplGetFrame()->Beep( eType );
+}
+
+// -----------------------------------------------------------------------
+
+void Sound::SetSoundPath( const XubString& rSoundPath )
+{
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& Sound::GetSoundPath()
+{
+ return ImplGetSVEmptyStr();
+}
diff --git a/vcl/source/app/stdtext.cxx b/vcl/source/app/stdtext.cxx
new file mode 100644
index 000000000000..8eafc26e474f
--- /dev/null
+++ b/vcl/source/app/stdtext.cxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * $RCSfile: stdtext.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_STDTEXT_CXX
+
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_MSGBOX_HXX
+#include <msgbox.hxx>
+#endif
+#ifndef _VCL_STDTEXT_HXX
+#include <stdtext.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+XubString GetStandardText( USHORT nStdText )
+{
+ XubString aText( ResId( nStdText-STANDARD_TEXT_FIRST+SV_STDTEXT_FIRST, ImplGetResMgr() ) );
+ return aText;
+}
+
+// =======================================================================
+
+void ShowServiceNotAvailableError( Window* pParent,
+ const XubString& rServiceName, BOOL bError )
+{
+ XubString aText( GetStandardText( STANDARD_TEXT_SERVICE_NOT_AVAILABLE ) );
+ aText.SearchAndReplaceAscii( "%s", rServiceName );
+ if ( bError )
+ {
+ ErrorBox aBox( pParent, WB_OK | WB_DEF_OK, aText );
+ aBox.Execute();
+ }
+ else
+ {
+ WarningBox aBox( pParent, WB_OK | WB_DEF_OK, aText );
+ aBox.Execute();
+ }
+}
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
new file mode 100644
index 000000000000..459653156f73
--- /dev/null
+++ b/vcl/source/app/svapp.cxx
@@ -0,0 +1,1770 @@
+/*************************************************************************
+ *
+ * $RCSfile: svapp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_APP_CXX
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#else
+#include "rvp.hxx"
+#include <rmwindow.hxx>
+#include <rmevents.hxx>
+#include <vos/thread.hxx>
+#include <unobrok.hxx>
+#ifndef _SV_MSGBOX_HXX
+#include <msgbox.hxx>
+#endif
+#endif
+
+#ifndef _VOS_PROCESS_HXX
+#include <vos/process.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#if defined( WIN ) || defined( WNT ) || defined( OS2 )
+#ifndef _DLL_HXX
+#include <tools/dll.hxx>
+#endif
+#endif
+#ifndef _TOOLS_H
+#include <tools/tools.h>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _ACCMGR_HXX
+#include <accmgr.hxx>
+#endif
+#ifndef _SV_KEYCOD_HXX
+#include <keycod.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_WINDATA_HXX
+#include <windata.hxx>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_IDLEMGR_HXX
+#include <idlemgr.hxx>
+#endif
+#ifndef _SV_DRAG_HXX
+#include <drag.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_CVTGRF_HXX
+#include <cvtgrf.hxx>
+#endif
+#ifndef _SV_ACCESS_HXX
+#include <access.hxx>
+#endif
+#ifndef _VCL_UNOWRAP_HXX
+#include <unowrap.hxx>
+#endif
+
+#include <com/sun/star/awt/XToolkit.hpp>
+
+// #include <usr/refl.hxx>
+class Reflection;
+
+#pragma hdrstop
+
+// =======================================================================
+
+// --------------
+// - ImplHotKey -
+// --------------
+
+struct ImplHotKey
+{
+ ImplHotKey* mpNext;
+ void* mpUserData;
+ KeyCode maKeyCode;
+ Link maLink;
+};
+
+// =======================================================================
+
+// -----------------
+// - ImplEventHook -
+// -----------------
+
+struct ImplEventHook
+{
+ ImplEventHook* mpNext;
+ void* mpUserData;
+ VCLEventHookProc mpProc;
+};
+
+// =======================================================================
+
+Application* GetpApp()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData )
+ return NULL;
+ return pSVData->mpApp;
+}
+
+// -----------------------------------------------------------------------
+
+Application::Application()
+{
+ ImplInitSVData();
+ ImplGetSVData()->mpApp = this;
+#ifndef REMOTE_APPSERVER
+ InitSalData();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+Application::~Application()
+{
+ ImplDeInitSVData();
+#ifndef REMOTE_APPSERVER
+ DeInitSalData();
+#endif
+ ImplGetSVData()->mpApp = NULL;
+ ImplDestroySVData();
+ GlobalDeInitTools();
+}
+
+// -----------------------------------------------------------------------
+
+void Application::InitAppRes( const ResId& rResId )
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::QueryExit()
+{
+ WorkWindow* pAppWin = ImplGetSVData()->maWinData.mpAppWin;
+
+ // Aufruf des Close-Handlers des Applikationsfensters
+ if ( pAppWin )
+ return pAppWin->Close();
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::UserEvent( ULONG, void* )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Application::ShowStatusText( const XubString& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Application::ShowHelpStatusText( const XubString& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Application::ActivateExtHelp()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Application::DeactivateExtHelp()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Application::HideStatusText()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Application::HideHelpStatusText()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Application::FocusChanged()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Application::DataChanged( const DataChangedEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Application::GetCommandLineParamCount()
+{
+ NAMESPACE_VOS( OStartupInfo ) aStartInfo;
+ return (USHORT)aStartInfo.getCommandArgCount();
+}
+
+// -----------------------------------------------------------------------
+
+XubString Application::GetCommandLineParam( USHORT nParam )
+{
+ NAMESPACE_VOS( OStartupInfo ) aStartInfo;
+ NAMESPACE_RTL( OUString ) aParam;
+ aStartInfo.getCommandArg( nParam, aParam );
+ return XubString( aParam );
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& Application::GetAppFileName()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ DBG_ASSERT( pSVData->maAppData.mpAppFileName, "AppFileName vor SVMain ?!" );
+ if ( pSVData->maAppData.mpAppFileName )
+ return *pSVData->maAppData.mpAppFileName;
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Application::Exception( USHORT nError )
+{
+ switch ( nError & EXC_MAJORTYPE )
+ {
+ // Bei System machen wir nichts und lassen dem System den
+ // vortritt
+ case EXC_SYSTEM:
+ return 0;
+
+ case EXC_DISPLAY:
+ case EXC_REMOTE:
+ return 0;
+
+#ifdef DBG_UTIL
+ case EXC_RSCNOTLOADED:
+ Abort( XubString( RTL_CONSTASCII_USTRINGPARAM( "Resource not loaded" ) ) );
+ break;
+ case EXC_SYSOBJNOTCREATED:
+ Abort( XubString( RTL_CONSTASCII_USTRINGPARAM( "System Object not created" ) ) );
+ break;
+ default:
+ Abort( XubString( RTL_CONSTASCII_USTRINGPARAM( "Unknown Error" ) ) );
+ break;
+#else
+ default:
+ Abort( ImplGetSVEmptyStr() );
+ break;
+#endif
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::Abort( const XubString& rErrorText )
+{
+#ifndef REMOTE_APPSERVER
+ SalAbort( rErrorText );
+#else
+ ErrorBox aErrorBox( NULL, WB_OK, rErrorText );
+ aErrorBox.Execute();
+ exit(-1);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef REMOTE_APPSERVER
+
+ImplRemoteYieldMutex::ImplRemoteYieldMutex()
+{
+ mnCount = 0;
+ mnMainThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier();
+ mnThreadId = 0;
+}
+
+void SAL_CALL ImplRemoteYieldMutex::acquire()
+{
+ OMutex::acquire();
+ mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier();
+ mnCount++;
+}
+
+void SAL_CALL ImplRemoteYieldMutex::release()
+{
+ if ( mnThreadId == NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
+ {
+ if ( mnCount == 1 )
+ mnThreadId = 0;
+ mnCount--;
+ }
+ OMutex::release();
+}
+
+sal_Bool SAL_CALL ImplRemoteYieldMutex::tryToAcquire()
+{
+ if ( OMutex::tryToAcquire() )
+ {
+ mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier();
+ mnCount++;
+ return True;
+ }
+ else
+ return False;
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+
+void ImplDbgTestSolarMutex()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maAppData.mpSolarMutex->GetMainThreadId() !=
+ NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
+ {
+ if ( pSVData->maAppData.mpSolarMutex->GetThreadId() !=
+ NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
+ {
+ DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" );
+ }
+ }
+ else
+ {
+ if ( pSVData->maAppData.mpSolarMutex->GetThreadId() !=
+ NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
+ {
+ DBG_ERROR( "SolarMutex not locked in the main thread" );
+ }
+ }
+}
+
+#endif
+
+
+NAMESPACE_VOS(OThreadData)* getThreadLocalEnvironment();
+
+static void ImplRemoteDispatch( BOOL bWait )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Yield-Semaphore freigeben
+ ULONG nAcquireCount;
+ ULONG i;
+ if ( pSVData->maAppData.mpSolarMutex->GetThreadId() ==
+ ::vos::OThread::getCurrentIdentifier() )
+ {
+ nAcquireCount = pSVData->maAppData.mpSolarMutex->GetAcquireCount();
+ for ( i = 0; i < nAcquireCount; i++ )
+ pSVData->maAppData.mpSolarMutex->release();
+ }
+ else
+ nAcquireCount = 0;
+
+ RmEvent* pEvent = pSVData->mpRmEventQueue->GetNextEvent( bWait );
+
+ // Yield-Semaphore wieder holen
+ while ( nAcquireCount )
+ {
+ pSVData->maAppData.mpSolarMutex->acquire();
+ nAcquireCount--;
+ }
+
+ if ( pEvent )
+ ImplDispatchEvent( (ExtRmEvent*)pEvent );
+ else
+ ::vos::OThread::yield();
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+void Application::Execute()
+{
+ DBG_STARTAPPEXECUTE();
+
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->maAppData.mbInAppExecute = TRUE;
+
+ while ( !pSVData->maAppData.mbAppQuit )
+ Application::Yield();
+
+ pSVData->maAppData.mbInAppExecute = FALSE;
+
+ DBG_ENDAPPEXECUTE();
+}
+
+// -----------------------------------------------------------------------
+
+void Application::Reschedule()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Restliche Timer abarbeitet
+ while ( pSVData->mbNotAllTimerCalled )
+ ImplTimerCallbackProc();
+
+ pSVData->maAppData.mnDispatchLevel++;
+#ifndef REMOTE_APPSERVER
+ pSVData->mpDefInst->Yield( FALSE );
+#else
+ ImplRemoteDispatch( FALSE );
+#endif
+ pSVData->maAppData.mnDispatchLevel--;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::Yield()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Restliche Timer abarbeitet
+ while ( pSVData->mbNotAllTimerCalled )
+ ImplTimerCallbackProc();
+
+ // Wenn Application schon beendet wurde, warten wir nicht mehr auf
+ // Messages, sondern verarbeiten nur noch welche, wenn noch welche
+ // vorliegen
+ pSVData->maAppData.mnDispatchLevel++;
+#ifndef REMOTE_APPSERVER
+ pSVData->mpDefInst->Yield( !pSVData->maAppData.mbAppQuit );
+#else
+ ImplRemoteDispatch( TRUE );
+#endif
+ pSVData->maAppData.mnDispatchLevel--;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_STATIC_LINK( ImplSVAppData, ImplQuitMsg, void*, EMPTYARG )
+{
+ ImplGetSVData()->maAppData.mbAppQuit = TRUE;
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::Quit()
+{
+ Application::PostUserEvent( STATIC_LINK( NULL, ImplSVAppData, ImplQuitMsg ) );
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef _VOS_NO_NAMESPACE
+IMutex& Application::GetSolarMutex()
+#else
+vos::IMutex& Application::GetSolarMutex()
+#endif
+{
+#ifndef REMOTE_APPSERVER
+ ImplSVData* pSVData = ImplGetSVData();
+ return *(pSVData->mpDefInst->GetYieldMutex());
+#else
+ return *(ImplGetSVData()->maAppData.mpSolarMutex);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef _VOS_NO_NAMESPACE
+OThread::TThreadIdentifier Application::GetMainThreadIdentifier()
+#else
+vos::OThread::TThreadIdentifier Application::GetMainThreadIdentifier()
+#endif
+{
+ return ImplGetSVData()->mnMainThreadId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Application::ReleaseSolarMutex()
+{
+#ifndef REMOTE_APPSERVER
+ ImplSVData* pSVData = ImplGetSVData();
+ return pSVData->mpDefInst->ReleaseYieldMutex();
+#else
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Wenn wir gelockt haben, dann freigeben
+ if ( pSVData->maAppData.mpSolarMutex->GetThreadId() ==
+ NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
+ {
+ ULONG nCount = pSVData->maAppData.mpSolarMutex->GetAcquireCount();
+ ULONG n = nCount;
+ while ( n )
+ {
+ pSVData->maAppData.mpSolarMutex->release();
+ n--;
+ }
+
+ return nCount;
+ }
+ else
+ return 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Application::AcquireSolarMutex( ULONG nCount )
+{
+#ifndef REMOTE_APPSERVER
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->mpDefInst->AcquireYieldMutex( nCount );
+#else
+ ImplSVData* pSVData = ImplGetSVData();
+ while ( nCount )
+ {
+ pSVData->maAppData.mpSolarMutex->acquire();
+ nCount--;
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsInMain()
+{
+ return ImplGetSVData()->maAppData.mbInAppMain;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsInExecute()
+{
+ return ImplGetSVData()->maAppData.mbInAppExecute;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsShutDown()
+{
+ return ImplGetSVData()->maAppData.mbAppQuit;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsInModalMode()
+{
+ return (ImplGetSVData()->maAppData.mnModalMode != 0);
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Application::GetDispatchLevel()
+{
+ return ImplGetSVData()->maAppData.mnDispatchLevel;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::AnyInput( USHORT nType )
+{
+#ifndef REMOTE_APPSERVER
+ return SalInstance::AnyInput( nType );
+#else
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if( ( nType & ( INPUT_ANY ) ) == ( INPUT_ANY ) )
+ {
+ return( pSVData->mpRmEventQueue->HasMouseEvent() ||
+ pSVData->mpRmEventQueue->HasKeyEvent() ||
+ pSVData->mpRmEventQueue->HasPaintEvent() ||
+ pSVData->mpRmEventQueue->HasTimerEvent() ||
+ pSVData->mpRmEventQueue->HasOtherEvent() );
+ }
+ else if( ( nType & ( INPUT_MOUSEANDKEYBOARD ) ) == ( INPUT_MOUSEANDKEYBOARD ) )
+ {
+ return( pSVData->mpRmEventQueue->HasMouseEvent() ||
+ pSVData->mpRmEventQueue->HasKeyEvent() );
+ }
+ else
+ {
+ if( nType & INPUT_MOUSE )
+ return pSVData->mpRmEventQueue->HasMouseEvent();
+
+ if( nType & INPUT_KEYBOARD )
+ return pSVData->mpRmEventQueue->HasKeyEvent();
+
+ if( nType & INPUT_PAINT )
+ return pSVData->mpRmEventQueue->HasPaintEvent();
+
+ if( nType & INPUT_TIMER )
+ return pSVData->mpRmEventQueue->HasTimerEvent();
+
+ if( nType & INPUT_OTHER )
+ return pSVData->mpRmEventQueue->HasOtherEvent();
+ }
+
+ return FALSE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Application::GetLastInputInterval()
+{
+ return (Time::GetSystemTicks()-ImplGetSVData()->maAppData.mnLastInputTime);
+}
+
+// -----------------------------------------------------------------------
+
+extern int nImplSysDialog;
+
+BOOL Application::IsUICaptured()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ // Wenn Mouse gecaptured, oder im TrackingModus oder im Auswahlmodus
+ // eines FloatingWindows (wie Menus, Aufklapp-ToolBoxen) soll kein
+ // weiteres Fenster aufgezogen werden
+ if ( pSVData->maWinData.mpCaptureWin || pSVData->maWinData.mpTrackWin ||
+ pSVData->maWinData.mpFirstFloat || DragManager::GetDragManager() ||
+ nImplSysDialog )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsUserActive( USHORT nTest )
+{
+ if ( nTest & (USERACTIVE_MOUSEDRAG | USERACTIVE_INPUT) )
+ {
+ if ( IsUICaptured() )
+ return TRUE;
+ }
+
+ if ( nTest & USERACTIVE_INPUT )
+ {
+ if ( GetLastInputInterval() < 500 )
+ return TRUE;
+
+ if ( AnyInput( INPUT_KEYBOARD ) )
+ return TRUE;
+ }
+
+ if ( nTest & USERACTIVE_MODALDIALOG )
+ {
+ if ( ImplGetSVData()->maAppData.mnModalDialog )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SystemSettingsChanging( AllSettings& rSettings,
+ Window* pFrame )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Application::MergeSystemSettings( AllSettings& rSettings )
+{
+#ifndef REMOTE_APPSERVER
+ ImplGetDefaultWindow()->ImplGetFrame()->UpdateSettings( rSettings );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetSettings( const AllSettings& rSettings )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->maAppData.mpSettings )
+ {
+ pSVData->maAppData.mpSettings = new AllSettings();
+ *pSVData->maAppData.mpSettings = rSettings;
+ }
+ else
+ {
+ AllSettings aOldSettings = *pSVData->maAppData.mpSettings;
+ *pSVData->maAppData.mpSettings = rSettings;
+ ULONG nChangeFlags = aOldSettings.GetChangeFlags( *pSVData->maAppData.mpSettings );
+ if ( nChangeFlags )
+ {
+ DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
+ GetpApp()->DataChanged( aDCEvt );
+
+ // Update all windows
+ Window* pFirstFrame = pSVData->maWinData.mpFirstFrame;
+ // Daten, die neu berechnet werden muessen, zuruecksetzen
+ long nOldDPIX;
+ long nOldDPIY;
+ if ( pFirstFrame )
+ {
+ nOldDPIX = pFirstFrame->mnDPIX;
+ nOldDPIY = pFirstFrame->mnDPIY;
+ pSVData->maGDIData.mnAppFontX = 0;
+ }
+ Window* pFrame = pFirstFrame;
+ while ( pFrame )
+ {
+ // AppFont-Cache-Daten zuruecksetzen
+ pFrame->mpFrameData->meMapUnit = MAP_PIXEL;
+
+ // UpdateSettings am ClientWindow aufrufen, damit
+ // die Daten nicht doppelt geupdatet werden
+ Window* pClientWin = pFrame;
+ while ( pClientWin->ImplGetClientWindow() )
+ pClientWin = pClientWin->ImplGetClientWindow();
+ pClientWin->UpdateSettings( rSettings, TRUE );
+
+ Window* pTempWin = pFrame->mpFrameData->mpFirstOverlap;
+ while ( pTempWin )
+ {
+ // UpdateSettings am ClientWindow aufrufen, damit
+ // die Daten nicht doppelt geupdatet werden
+ pClientWin = pTempWin;
+ while ( pClientWin->ImplGetClientWindow() )
+ pClientWin = pClientWin->ImplGetClientWindow();
+ pClientWin->UpdateSettings( rSettings, TRUE );
+ pTempWin = pTempWin->mpNextOverlap;
+ }
+
+ pFrame = pFrame->mpFrameData->mpNextFrame;
+ }
+
+ // Wenn sich die DPI-Aufloesung fuer Screen-Ausgaben
+ // geaendert hat, setzen wir auch bei allen
+ // Screen-Kompatiblen VirDev's die neue Aufloesung
+ pFirstFrame = pSVData->maWinData.mpFirstFrame;
+ if ( pFirstFrame )
+ {
+ if ( (pFirstFrame->mnDPIX != nOldDPIX) ||
+ (pFirstFrame->mnDPIY != nOldDPIY) )
+ {
+ VirtualDevice* pVirDev = pSVData->maGDIData.mpFirstVirDev;
+ while ( pVirDev )
+ {
+ if ( pVirDev->mbScreenComp &&
+ (pVirDev->mnDPIX == nOldDPIX) &&
+ (pVirDev->mnDPIY == nOldDPIY) )
+ {
+ pVirDev->mnDPIX = pFirstFrame->mnDPIX;
+ pVirDev->mnDPIY = pFirstFrame->mnDPIY;
+ if ( pVirDev->IsMapMode() )
+ {
+ MapMode aMapMode = pVirDev->GetMapMode();
+ pVirDev->SetMapMode();
+ pVirDev->SetMapMode( aMapMode );
+ }
+ }
+
+ pVirDev = pVirDev->mpNext;
+ }
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+const AllSettings& Application::GetSettings()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->maAppData.mpSettings )
+ pSVData->maAppData.mpSettings = new AllSettings();
+ return *(pSVData->maAppData.mpSettings);
+}
+
+// -----------------------------------------------------------------------
+
+void Application::NotifyAllWindows( DataChangedEvent& rDCEvt )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pFrame = pSVData->maWinData.mpFirstFrame;
+ while ( pFrame )
+ {
+ pFrame->NotifyAllChilds( rDCEvt );
+
+ Window* pSysWin = pFrame->mpFrameData->mpFirstOverlap;
+ while ( pSysWin )
+ {
+ pSysWin->NotifyAllChilds( rDCEvt );
+ pSysWin = pSysWin->mpNextOverlap;
+ }
+
+ pFrame = pFrame->mpFrameData->mpNextFrame;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Application::PostUserEvent( ULONG nEvent, void* pEventData )
+{
+ ULONG nEventId;
+ PostUserEvent( nEventId, nEvent, pEventData );
+ return nEventId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Application::PostUserEvent( const Link& rLink, void* pCaller )
+{
+ ULONG nEventId;
+ PostUserEvent( nEventId, rLink, pCaller );
+ return nEventId;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::PostUserEvent( ULONG& rEventId, ULONG nEvent, void* pEventData )
+{
+ ImplSVEvent* pSVEvent = new ImplSVEvent;
+ pSVEvent->mnEvent = nEvent;
+ pSVEvent->mpData = pEventData;
+ pSVEvent->mpLink = NULL;
+ pSVEvent->mpWindow = NULL;
+ pSVEvent->mbCall = TRUE;
+ rEventId = (ULONG)pSVEvent;
+#ifndef REMOTE_APPSERVER
+ if ( ImplGetDefaultWindow()->ImplGetFrame()->PostEvent( pSVEvent ) )
+ return TRUE;
+ else
+ {
+ rEventId = 0;
+ delete pSVEvent;
+ return FALSE;
+ }
+#else
+ ExtRmEvent* pEvt = new ExtRmEvent( RMEVENT_USEREVENT, NULL, pSVEvent );
+ ImplPostEvent( pEvt );
+ return TRUE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::PostUserEvent( ULONG& rEventId, const Link& rLink, void* pCaller )
+{
+ ImplSVEvent* pSVEvent = new ImplSVEvent;
+ pSVEvent->mnEvent = 0;
+ pSVEvent->mpData = pCaller;
+ pSVEvent->mpLink = new Link( rLink );
+ pSVEvent->mpWindow = NULL;
+ pSVEvent->mbCall = TRUE;
+ rEventId = (ULONG)pSVEvent;
+#ifndef REMOTE_APPSERVER
+ if ( ImplGetDefaultWindow()->ImplGetFrame()->PostEvent( pSVEvent ) )
+ return TRUE;
+ else
+ {
+ rEventId = 0;
+ delete pSVEvent;
+ return FALSE;
+ }
+#else
+ ExtRmEvent* pEvt = new ExtRmEvent( RMEVENT_USEREVENT, NULL, pSVEvent );
+ ImplPostEvent( pEvt );
+ return TRUE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Application::RemoveUserEvent( ULONG nUserEvent )
+{
+ ImplSVEvent* pSVEvent = (ImplSVEvent*)nUserEvent;
+
+ DBG_ASSERT( !pSVEvent->mpWindow,
+ "Application::RemoveUserEvent(): Event is send to a window" );
+ DBG_ASSERT( pSVEvent->mbCall,
+ "Application::RemoveUserEvent(): Event is already removed" );
+
+ if ( pSVEvent->mpWindow )
+ {
+ pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
+ pSVEvent->mpWindow = NULL;
+ }
+
+ pSVEvent->mbCall = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::InsertIdleHdl( const Link& rLink, USHORT nPrio )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Falls er noch nicht existiert, dann anlegen
+ if ( !pSVData->maAppData.mpIdleMgr )
+ pSVData->maAppData.mpIdleMgr = new ImplIdleMgr;
+
+ return pSVData->maAppData.mpIdleMgr->InsertIdleHdl( rLink, nPrio );
+}
+
+// -----------------------------------------------------------------------
+
+void Application::RemoveIdleHdl( const Link& rLink )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maAppData.mpIdleMgr )
+ pSVData->maAppData.mpIdleMgr->RemoveIdleHdl( rLink );
+}
+
+// -----------------------------------------------------------------------
+
+WorkWindow* Application::GetAppWindow()
+{
+ return ImplGetSVData()->maWinData.mpAppWin;
+}
+
+// -----------------------------------------------------------------------
+
+Window* Application::GetFocusWindow()
+{
+ return ImplGetSVData()->maWinData.mpFocusWin;
+}
+
+// -----------------------------------------------------------------------
+
+OutputDevice* Application::GetDefaultDevice()
+{
+ return ImplGetDefaultWindow();
+}
+
+// -----------------------------------------------------------------------
+
+Window* Application::GetFirstTopLevelWindow()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ return pSVData->maWinData.mpFirstFrame;
+}
+
+// -----------------------------------------------------------------------
+
+Window* Application::GetNextTopLevelWindow( Window* pWindow )
+{
+ return pWindow->mpFrameData->mpNextFrame;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetAppName( const XubString& rUniqueName )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Falls er noch nicht existiert, dann anlegen
+ if ( !pSVData->maAppData.mpAppName )
+ pSVData->maAppData.mpAppName = new XubString( rUniqueName );
+ else
+ *(pSVData->maAppData.mpAppName) = rUniqueName;
+}
+
+// -----------------------------------------------------------------------
+
+XubString Application::GetAppName()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maAppData.mpAppName )
+ return *(pSVData->maAppData.mpAppName);
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetDisplayName( const UniString& rName )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Falls er noch nicht existiert, dann anlegen
+ if ( !pSVData->maAppData.mpDisplayName )
+ pSVData->maAppData.mpDisplayName = new UniString( rName );
+ else
+ *(pSVData->maAppData.mpDisplayName) = rName;
+}
+
+// -----------------------------------------------------------------------
+
+UniString Application::GetDisplayName()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maAppData.mpDisplayName )
+ return *(pSVData->maAppData.mpDisplayName);
+ else if ( pSVData->maWinData.mpAppWin )
+ return pSVData->maWinData.mpAppWin->GetText();
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::InsertAccel( Accelerator* pAccel )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( !pSVData->maAppData.mpAccelMgr )
+ pSVData->maAppData.mpAccelMgr = new ImplAccelManager();
+ return pSVData->maAppData.mpAccelMgr->InsertAccel( pAccel );
+}
+
+// -----------------------------------------------------------------------
+
+void Application::RemoveAccel( Accelerator* pAccel )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maAppData.mpAccelMgr )
+ pSVData->maAppData.mpAccelMgr->RemoveAccel( pAccel );
+}
+
+// -----------------------------------------------------------------------
+
+void Application::FlushAccel()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maAppData.mpAccelMgr )
+ pSVData->maAppData.mpAccelMgr->FlushAccel();
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetHelp( Help* pHelp )
+{
+ ImplGetSVData()->maAppData.mpHelp = pHelp;
+}
+
+// -----------------------------------------------------------------------
+
+Help* Application::GetHelp()
+{
+ return ImplGetSVData()->maAppData.mpHelp;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::EnableAutoHelpId( BOOL bEnabled )
+{
+ ImplGetSVData()->maHelpData.mbAutoHelpId = bEnabled;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsAutoHelpIdEnabled()
+{
+ return ImplGetSVData()->maHelpData.mbAutoHelpId;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::EnableAutoMnemonic( BOOL bEnabled )
+{
+ ImplGetSVData()->maAppData.mbAutoMnemonics = bEnabled;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsAutoMnemonicEnabled()
+{
+ return ImplGetSVData()->maAppData.mbAutoMnemonics;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetDialogScaleX( short nScale )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->maAppData.mnDialogScaleX = nScale;
+ pSVData->maGDIData.mnAppFontX = pSVData->maGDIData.mnRealAppFontX;
+ if ( nScale )
+ pSVData->maGDIData.mnAppFontX += (pSVData->maGDIData.mnAppFontX*nScale)/100;
+}
+
+// -----------------------------------------------------------------------
+
+short Application::GetDialogScaleX()
+{
+ return ImplGetSVData()->maAppData.mnDialogScaleX;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetDefDialogParent( Window* pWindow )
+{
+ ImplGetSVData()->maWinData.mpDefDialogParent = pWindow;
+}
+
+// -----------------------------------------------------------------------
+
+Window* Application::GetDefDialogParent()
+{
+ return ImplGetSVData()->maWinData.mpDefDialogParent;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::EnableDialogCancel( BOOL bDialogCancel )
+{
+ ImplGetSVData()->maAppData.mbDialogCancel = bDialogCancel;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsDialogCancelEnabled()
+{
+ return ImplGetSVData()->maAppData.mbDialogCancel;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetSystemWindowMode( USHORT nMode )
+{
+ ImplGetSVData()->maAppData.mnSysWinMode = nMode;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Application::GetSystemWindowMode()
+{
+ return ImplGetSVData()->maAppData.mnSysWinMode;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetResourcePath( const XubString& rPath )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Falls er noch nicht existiert, dann anlegen
+ if ( !pSVData->maAppData.mpResPath )
+ pSVData->maAppData.mpResPath = new XubString( rPath );
+ else
+ *(pSVData->maAppData.mpResPath) = rPath;
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& Application::GetResourcePath()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maAppData.mpResPath )
+ return *(pSVData->maAppData.mpResPath);
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void Application::EnterMultiThread( BOOL bEnter )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+#if defined( WIN ) || defined( WNT ) || defined( OS2 )
+ ::EnterMultiThread( bEnter );
+#endif
+
+ if ( bEnter )
+ {
+ pSVData->mnThreadCount++;
+
+#ifndef REMOTE_APPSERVER
+ // Unser DefaultWindow muss vor einem Thread-Starten erzeugt werden,
+ // damit dieses im Hauptthread laeuft
+ ImplGetDefaultWindow();
+#endif
+ }
+ else
+ pSVData->mnThreadCount--;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsMultiThread()
+{
+ return (ImplGetSVData()->mnThreadCount != 0);
+}
+
+// -----------------------------------------------------------------------
+
+UniqueItemId Application::CreateUniqueId()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( !pSVData->maAppData.mpUniqueIdCont )
+ pSVData->maAppData.mpUniqueIdCont = new UniqueIdContainer( UNIQUEID_SV_BEGIN );
+ return pSVData->maAppData.mpUniqueIdCont->CreateId();
+}
+
+// -----------------------------------------------------------------------
+
+SystemInfoType Application::GetClientSystem()
+{
+#ifndef REMOTE_APPSERVER
+ return GetServerSystem();
+#else
+ static SystemInfoType nImplClientSystemInfo = 0;
+ if ( !nImplClientSystemInfo )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->mxStatus.is() )
+ nImplClientSystemInfo = (SystemInfoType)pSVData->mxStatus->GetSystemType();
+ }
+
+ return nImplClientSystemInfo;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+SystemInfoType Application::GetServerSystem()
+{
+#if defined( WIN )
+ return SYSTEMINFO_SYSTEM_WINDOWS | SYSTEMINFO_SYSTEMBASE_DOS;
+#elif defined( WNT )
+ return SYSTEMINFO_SYSTEM_WINDOWS | SYSTEMINFO_SYSTEMBASE_NT;
+#elif defined( OS2 )
+ return SYSTEMINFO_SYSTEM_OS2;
+#elif defined( MAC )
+ return SYSTEMINFO_SYSTEM_MAC;
+#elif defined( UNX )
+#if defined( LINUX )
+ return SYSTEMINFO_SYSTEM_UNIX | SYSTEMINFO_SYSTEMBASE_LINUX;
+#elif defined( SOLARIS )
+ return SYSTEMINFO_SYSTEM_UNIX | SYSTEMINFO_SYSTEMBASE_SOLARIS;
+#elif defined( SCO )
+ return SYSTEMINFO_SYSTEM_UNIX | SYSTEMINFO_SYSTEMBASE_SCO;
+#elif defined( NETBSD )
+ return SYSTEMINFO_SYSTEM_UNIX | SYSTEMINFO_SYSTEMBASE_NETBSD;
+#elif defined( AIX )
+ return SYSTEMINFO_SYSTEM_UNIX | SYSTEMINFO_SYSTEMBASE_AIX;
+#elif defined( IRIX )
+ return SYSTEMINFO_SYSTEM_UNIX | SYSTEMINFO_SYSTEMBASE_IRIX;
+#elif defined( HPUX )
+ return SYSTEMINFO_SYSTEM_UNIX | SYSTEMINFO_SYSTEMBASE_HPUX;
+#elif defined( FREEBSD )
+ return SYSTEMINFO_SYSTEM_UNIX | SYSTEMINFO_SYSTEMBASE_FREEBSD;
+#elif defined( MACOSX )
+ return SYSTEMINFO_SYSTEM_UNIX | SYSTEMINFO_SYSTEMBASE_MACOSX;
+#else
+#error Unknown Unix-System, new SystemBase must be defined!
+#endif
+#else
+#error Unknown System, new System must be defined!
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::IsRemoteServer()
+{
+#ifndef REMOTE_APPSERVER
+ return FALSE;
+#else
+ return TRUE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void* Application::GetRemoteEnvironment()
+{
+#ifndef REMOTE_APPSERVER
+ return NULL;
+#else
+ return ImplGetSVData()->mhRemoteEnv;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > Application::GetVCLToolkit()
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > xT;
+ UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
+ if ( pWrapper )
+ xT = pWrapper->GetVCLToolkit();
+ return xT;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::RegisterUnoServices()
+{
+ UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
+ if ( pWrapper )
+ pWrapper->RegisterUnoServices();
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetUnoWrapper( UnoWrapperBase* pWrapper )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ DBG_ASSERT( !pSVData->mpUnoWrapper, "SetUnoWrapper: Wrapper allready exists" );
+ pSVData->mpUnoWrapper = pWrapper;
+}
+
+// -----------------------------------------------------------------------
+
+UnoWrapperBase* Application::GetUnoWrapper()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ return pSVData->mpUnoWrapper;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetFilterHdl( const Link& rLink )
+{
+ ImplGetSVData()->maGDIData.mpGrfConverter->SetFilterHdl( rLink );
+}
+
+// -----------------------------------------------------------------------
+
+const Link& Application::GetFilterHdl()
+{
+ return ImplGetSVData()->maGDIData.mpGrfConverter->GetFilterHdl();
+}
+
+// -----------------------------------------------------------------------
+
+void Application::AccessNotify( const AccessNotification& rNotification )
+{
+ GetFirstAccessHdl().Call( (void*) &rNotification );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Application::GenerateAccessEvent( ULONG nAccessEvent,
+ long nData1,
+ long nData2,
+ long nData3 )
+{
+ BOOL bRet = FALSE;
+
+ switch( nAccessEvent )
+ {
+ case( ACCESS_EVENT_DLGCONTROLS ):
+ {
+ if( IsInModalMode() )
+ {
+ Window* pDlgWin = GetFocusWindow();
+ BOOL bFound = FALSE;
+
+ // find modal dialog
+ while( pDlgWin && !bFound )
+ {
+ switch( pDlgWin->GetType() )
+ {
+ case( WINDOW_MESSBOX ):
+ case( WINDOW_INFOBOX ):
+ case( WINDOW_WARNINGBOX ):
+ case( WINDOW_ERRORBOX ):
+ case( WINDOW_QUERYBOX ):
+ case( WINDOW_MODALDIALOG ):
+ case( WINDOW_PATHDIALOG ):
+ case( WINDOW_FILEDIALOG ):
+ case( WINDOW_PRINTERSETUPDIALOG ):
+ case( WINDOW_PRINTDIALOG ):
+ case( WINDOW_COLORDIALOG ):
+ case( WINDOW_FONTDIALOG ):
+ case( WINDOW_TABDIALOG ):
+ case( WINDOW_BUTTONDIALOG ):
+ bFound = TRUE;
+ break;
+
+ default:
+ pDlgWin = pDlgWin->GetWindow( WINDOW_PARENT );
+ break;
+ }
+ }
+
+ if( pDlgWin )
+ {
+ AccessNotify( AccessNotification( ACCESS_EVENT_DLGCONTROLS, pDlgWin ) );
+ bRet = TRUE;
+ }
+ }
+ }
+ break;
+
+ case( ACCESS_EVENT_KEY ):
+ AccessNotify( AccessNotification( ACCESS_EVENT_KEY, nData1, nData2, nData3 ) );
+ break;
+
+ default:
+ break;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::AddAccessHdl( const Link& rLink )
+{
+ if( !ImplGetSVData()->maAppData.mpAccessList )
+ ImplGetSVData()->maAppData.mpAccessList = new List;
+
+ List* pList = ImplGetSVData()->maAppData.mpAccessList;
+ BOOL bInserted = FALSE;
+
+ for( void* pLink = pList->First(); pLink; pLink = pList->Next() )
+ {
+ if( *(Link*) pLink == rLink )
+ {
+ bInserted = TRUE;
+ break;
+ }
+ }
+
+ if( !bInserted )
+ {
+ ImplGetSVData()->maAppData.mnAccessCount++;
+ pList->Insert( new Link( rLink ), LIST_APPEND );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Application::RemoveAccessHdl( const Link& rLink )
+{
+ List* pList = ImplGetSVData()->maAppData.mpAccessList;
+
+ if( pList )
+ {
+ for( void* pLink = pList->First(); pLink; pLink = pList->Next() )
+ {
+ if( *(Link*) pLink == rLink )
+ {
+ ImplGetSVData()->maAppData.mnAccessCount--;
+ delete (Link*) pList->Remove( pLink );
+ break;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Application::GetAccessHdlCount()
+{
+ return ImplGetSVData()->maAppData.mnAccessCount;
+}
+
+// -----------------------------------------------------------------------
+
+Link Application::GetFirstAccessHdl()
+{
+ List* pList = ImplGetSVData()->maAppData.mpAccessList;
+
+ if( pList && pList->Count() )
+ return *(Link*) pList->First();
+ else
+ return Link();
+}
+
+// -----------------------------------------------------------------------
+
+void Application::CallNextAccessHdl( AccessNotification* pData )
+{
+ List* pList = ImplGetSVData()->maAppData.mpAccessList;
+
+ if( pList )
+ {
+ Link* pNext = (Link*) pList->Next();
+
+ if( pNext )
+ pNext->Call( pData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplCallHotKey( const KeyCode& rKeyCode )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplHotKey* pHotKeyData = pSVData->maAppData.mpFirstHotKey;
+ while ( pHotKeyData )
+ {
+ if ( pHotKeyData->maKeyCode.IsDefinedKeyCodeEqual( rKeyCode ) )
+ {
+ pHotKeyData->maLink.Call( pHotKeyData->mpUserData );
+ return TRUE;
+ }
+
+ pHotKeyData = pHotKeyData->mpNext;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFreeHotKeyData()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplHotKey* pTempHotKeyData;
+ ImplHotKey* pHotKeyData = pSVData->maAppData.mpFirstHotKey;
+ while ( pHotKeyData )
+ {
+ pTempHotKeyData = pHotKeyData->mpNext;
+ delete pHotKeyData;
+ pHotKeyData = pTempHotKeyData;
+ }
+
+ pSVData->maAppData.mpFirstHotKey = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Application::AddHotKey( const KeyCode& rKeyCode, const Link& rLink, void* pData )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplHotKey* pHotKeyData = new ImplHotKey;
+ pHotKeyData->mpUserData = pData;
+ pHotKeyData->maKeyCode = rKeyCode;
+ pHotKeyData->maLink = rLink;
+ pHotKeyData->mpNext = pSVData->maAppData.mpFirstHotKey;
+ pSVData->maAppData.mpFirstHotKey = pHotKeyData;
+ return (ULONG)pHotKeyData;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::RemoveHotKey( ULONG nId )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplHotKey* pFindHotKeyData = (ImplHotKey*)nId;
+ ImplHotKey* pPrevHotKeyData = NULL;
+ ImplHotKey* pHotKeyData = pSVData->maAppData.mpFirstHotKey;
+ while ( pHotKeyData )
+ {
+ if ( pHotKeyData == pFindHotKeyData )
+ {
+ if ( pPrevHotKeyData )
+ pPrevHotKeyData->mpNext = pFindHotKeyData->mpNext;
+ else
+ pSVData->maAppData.mpFirstHotKey = pFindHotKeyData->mpNext;
+ delete pFindHotKeyData;
+ break;
+ }
+
+ pPrevHotKeyData = pHotKeyData;
+ pHotKeyData = pHotKeyData->mpNext;
+ }
+
+ DBG_ASSERT( pHotKeyData, "Application::RemoveHotKey() - HotKey is not added" );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFreeEventHookData()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplEventHook* pTempEventHookData;
+ ImplEventHook* pEventHookData = pSVData->maAppData.mpFirstEventHook;
+ while ( pEventHookData )
+ {
+ pTempEventHookData = pEventHookData->mpNext;
+ delete pEventHookData;
+ pEventHookData = pTempEventHookData;
+ }
+
+ pSVData->maAppData.mpFirstEventHook = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Application::AddEventHook( VCLEventHookProc pProc, void* pData )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplEventHook* pEventHookData = new ImplEventHook;
+ pEventHookData->mpUserData = pData;
+ pEventHookData->mpProc = pProc;
+ pEventHookData->mpNext = pSVData->maAppData.mpFirstEventHook;
+ pSVData->maAppData.mpFirstEventHook = pEventHookData;
+ return (ULONG)pEventHookData;
+}
+
+// -----------------------------------------------------------------------
+
+void Application::RemoveEventHook( ULONG nId )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplEventHook* pFindEventHookData = (ImplEventHook*)nId;
+ ImplEventHook* pPrevEventHookData = NULL;
+ ImplEventHook* pEventHookData = pSVData->maAppData.mpFirstEventHook;
+ while ( pEventHookData )
+ {
+ if ( pEventHookData == pFindEventHookData )
+ {
+ if ( pPrevEventHookData )
+ pPrevEventHookData->mpNext = pFindEventHookData->mpNext;
+ else
+ pSVData->maAppData.mpFirstEventHook = pFindEventHookData->mpNext;
+ delete pFindEventHookData;
+ break;
+ }
+
+ pPrevEventHookData = pEventHookData;
+ pEventHookData = pEventHookData->mpNext;
+ }
+
+ DBG_ASSERT( pEventHookData, "Application::RemoveEventHook() - EventHook is not added" );
+}
+
+// -----------------------------------------------------------------------
+
+long Application::CallEventHooks( NotifyEvent& rEvt )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ long nRet = 0;
+ ImplEventHook* pTempEventHookData;
+ ImplEventHook* pEventHookData = pSVData->maAppData.mpFirstEventHook;
+ while ( pEventHookData )
+ {
+ pTempEventHookData = pEventHookData->mpNext;
+ nRet = pEventHookData->mpProc( rEvt, pEventHookData->mpUserData );
+ if ( nRet )
+ break;
+ pEventHookData = pTempEventHookData;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+long Application::CallPreNotify( NotifyEvent& rEvt )
+{
+ return ImplCallPreNotify( rEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long Application::CallEvent( NotifyEvent& rEvt )
+{
+ return ImplCallEvent( rEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Application::SetAppInternational( const International& rIntn )
+{
+ AllSettings aSettings = GetSettings();
+ aSettings.SetInternational( rIntn );
+ SetSettings( aSettings );
+}
+
+// -----------------------------------------------------------------------
+
+const International& Application::GetAppInternational()
+{
+ return GetSettings().GetInternational();
+}
+
+// =======================================================================
+
+void InitVCL()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void DeInitVCL()
+{
+}
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
new file mode 100644
index 000000000000..7b7e1c38b2ed
--- /dev/null
+++ b/vcl/source/app/svdata.cxx
@@ -0,0 +1,237 @@
+/*************************************************************************
+ *
+ * $RCSfile: svdata.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#define _SV_SVDATA_CXX
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#endif
+
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#define private public
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+
+#ifndef _VCL_UNOWRAP_HXX
+#include <unowrap.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+// static Empty-SV-String
+static XubString aImplSVEmptyStr;
+XubString& rImplSVEmptyStr = aImplSVEmptyStr;
+#ifdef ENABLEUNICODE
+static ByteString aImplSVEmptyByteStr;
+ByteString& rImplSVEmptyByteStr = aImplSVEmptyByteStr;
+#endif
+
+#ifndef WIN
+ImplSVData private_aImplSVData;
+// static SV-Data
+ImplSVData* pImplSVData = &private_aImplSVData;
+#endif
+
+// static SharedLib SV-Data
+ImplSVShlData aImplSVShlData;
+
+// =======================================================================
+
+void ImplInitSVData()
+{
+#ifndef WIN
+ ImplSVData* pSVData = pImplSVData;
+ ImplSVData** ppSVData = (ImplSVData**)GetAppData( SHL_SV );
+ *ppSVData = &private_aImplSVData;
+#else
+ // alloc global instance data
+ ImplSVData* pSVData = new ImplSVData;
+ ImplSVData** ppSVData = (ImplSVData**)GetAppData( SHL_SV );
+ *ppSVData = pSVData;
+#endif
+
+ // init global sharedlib data
+ // ...
+
+ // init global instance data
+ memset( pSVData, 0, sizeof( ImplSVData ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDeInitSVData()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // delete global instance data
+
+ if ( pSVData->mpUnoWrapper )
+ {
+ pSVData->mpUnoWrapper->Destroy();
+ pSVData->mpUnoWrapper = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDestroySVData()
+{
+ ImplSVData** ppSVData = (ImplSVData**)GetAppData( SHL_SV );
+ ImplSVData* pSVData = *ppSVData;
+#ifdef WIN
+ delete pSVData;
+#endif
+
+ // delete global sharedlib data
+ // ...
+
+ *ppSVData = NULL;
+#ifndef WIN
+ pImplSVData = NULL;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+Window* ImplGetDefaultWindow()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maWinData.mpAppWin )
+ return pSVData->maWinData.mpAppWin;
+
+ if ( !pSVData->mpDefaultWin )
+ {
+ DBG_WARNING( "ImplGetDefaultWindow(): No AppWindow" );
+ Application::GetSolarMutex().acquire();
+ pSVData->mpDefaultWin = new WorkWindow( 0, 0 );
+ Application::GetSolarMutex().release();
+ }
+
+ return pSVData->mpDefaultWin;
+}
+
+// -----------------------------------------------------------------------
+
+#define VCL_CREATERESMGR_NAME( Name ) #Name MAKE_NUMSTR( SUPD )
+#define VCL_CREATERESMGR( Name ) ResMgr::CreateResMgr( VCL_CREATERESMGR_NAME( Name ) )
+
+ResMgr* ImplGetResMgr()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->mpResMgr )
+ pSVData->mpResMgr = VCL_CREATERESMGR( vcl );
+ return pSVData->mpResMgr;
+}
+
+// -----------------------------------------------------------------------
+
+#ifndef REMOTE_APPSERVER
+
+Window* ImplFindWindow( const SalFrame* pFrame, Point& rSalFramePos )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pFrameWindow = pSVData->maWinData.mpFirstFrame;
+ while ( pFrameWindow )
+ {
+ if ( pFrameWindow->ImplGetFrame() == pFrame )
+ {
+ Window* pWindow = pFrameWindow->ImplFindWindow( rSalFramePos );
+ if ( !pWindow )
+ pWindow = pFrameWindow->ImplGetWindow();
+ rSalFramePos = pWindow->ImplFrameToOutput( rSalFramePos );
+ return pWindow;
+ }
+ pFrameWindow = pFrameWindow->mpFrameData->mpNextFrame;
+ }
+
+ return NULL;
+}
+
+#endif
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
new file mode 100644
index 000000000000..2b7d389a5aeb
--- /dev/null
+++ b/vcl/source/app/svmain.cxx
@@ -0,0 +1,714 @@
+/*************************************************************************
+ *
+ * $RCSfile: svmain.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SVMAIN_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALSOUND_HXX
+#include <salsound.hxx>
+#endif
+#ifndef _SV_SALOGL_HXX
+#include <salogl.hxx>
+#endif
+#ifndef _SV_SALWTYPE_HXX
+#include <salwtype.hxx>
+#endif
+#ifndef _OSL_UTIL_H
+#include <osl/util.h>
+#endif
+#ifndef _VOS_SIGNAL_HXX
+#include <vos/signal.hxx>
+#endif
+#ifndef _VOS_CHANNEL_HXX
+#include <vos/channel.hxx>
+#endif
+#ifndef _VOS_SOCKET_HXX
+#include <vos/socket.hxx>
+#endif
+#ifndef _TOOLS_H
+#include <tools/tools.h>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _UNIQID_HXX
+#include <tools/unqid.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_DBGGUI_HXX
+#include <dbggui.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_CVTGRF_HXX
+#include <cvtgrf.hxx>
+#endif
+#ifndef _SV_IMAGE_HXX
+#include <image.hxx>
+#endif
+#ifndef _SV_RESMGR_HXX
+#include <resmgr.hxx>
+#endif
+#ifndef _SV_ACCMGR_HXX
+#include <accmgr.hxx>
+#endif
+#ifndef _SV_IDLEMGR_HXX
+#include <idlemgr.hxx>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+#ifndef _SV_PRINT_H
+#include <print.h>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+// HACK: Only for Exception-Hack
+#ifndef _SV_SYSEXCHG_HXX
+#include <sysexchg.hxx>
+#endif
+
+#include <vos/process.hxx>
+#include <osl/file.hxx>
+
+#ifdef REMOTE_APPSERVER
+#include <config.hxx>
+#include <ooffice.hxx>
+#include <rversion.h>
+#include <xevthdl.hxx>
+#include <rmevents.hxx>
+#include <rmprint.hxx>
+#include <outdev.h>
+#include <vos/mutex.hxx>
+#include <vos/timer.hxx>
+#include <unobrok.hxx>
+#include "rvp.hxx"
+#include <atom.hxx>
+
+#include <cppuhelper/servicefactory.hxx>
+#include <unotools/processfactory.hxx>
+#include <unotools/regpathhelper.hxx>
+
+#include <com/sun/star/portal/client/XRmStatus.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::portal::client;
+using namespace ::cppu;
+using namespace ::rtl;
+
+#ifdef UNX
+class SalData
+{
+ void Init (int *pIPointer, char *pCPointer[] );
+};
+void SalData::Init (int *pIPointer, char *pCPointer[] )
+{};
+#endif /* UNX */
+
+#endif /* REMOTE_APPSERVER */
+
+#pragma hdrstop
+
+// =======================================================================
+
+class ImplVCLExceptionHandler : public ::vos::OSignalHandler
+{
+public:
+ virtual ::vos::OSignalHandler::TSignalAction SAL_CALL signal( ::vos::OSignalHandler::TSignalInfo* pInfo );
+};
+
+// -----------------------------------------------------------------------
+
+::vos::OSignalHandler::TSignalAction SAL_CALL ImplVCLExceptionHandler::signal( ::vos::OSignalHandler::TSignalInfo* pInfo )
+{
+ static BOOL bIn = FALSE;
+
+ // Wenn wir nocheinmal abstuerzen, verabschieden wir uns gleich
+ if ( !bIn )
+ {
+ USHORT nVCLException = 0;
+
+ // UAE
+ if ( (pInfo->Signal == TSignal_AccessViolation) ||
+ (pInfo->Signal == TSignal_IntegerDivideByZero) ||
+ (pInfo->Signal == TSignal_FloatDivideByZero) ||
+ (pInfo->Signal == TSignal_DebugBreak) )
+ nVCLException = EXC_SYSTEM;
+
+ // RC
+ if ((pInfo->Signal == TSignal_SignalUser) &&
+ (pInfo->UserSignal == OSL_SIGNAL_USER_RESOURCEFAILURE) )
+ nVCLException = EXC_RSCNOTLOADED;
+
+ // DISPLAY-Unix
+ if ((pInfo->Signal == TSignal_SignalUser) &&
+ (pInfo->UserSignal == OSL_SIGNAL_USER_X11SUBSYSTEMERROR) )
+ nVCLException = EXC_DISPLAY;
+
+ // Remote-Client
+ if ((pInfo->Signal == TSignal_SignalUser) &&
+ (pInfo->UserSignal == OSL_SIGNAL_USER_RVPCONNECTIONERROR) )
+ nVCLException = EXC_REMOTE;
+
+ if ( nVCLException )
+ {
+ bIn = TRUE;
+ // Timer nicht mehr anhalten, da ansonsten die UAE-Box
+ // auch nicht mehr gepaintet wird
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->mpApp )
+ {
+ USHORT nOldMode = Application::GetSystemWindowMode();
+ Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
+ pSVData->mpApp->Exception( nVCLException );
+ Application::SetSystemWindowMode( nOldMode );
+ }
+ bIn = FALSE;
+
+#ifndef REMOTE_APPSERVER
+ return NAMESPACE_VOS(OSignalHandler)::TAction_CallNextHandler;
+#else
+ return NAMESPACE_VOS(OSignalHandler)::TAction_KillApplication;
+#endif
+ }
+ }
+
+ return NAMESPACE_VOS(OSignalHandler)::TAction_CallNextHandler;
+}
+
+BOOL SVMain()
+{
+ osl_setSUPD( SUPD );
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+
+ DBG_ASSERT( pSVData->mpApp, "no instance of class Application" );
+
+ // SV bei den Tools anmelden
+ InitTools();
+
+ // Main-Thread-Id merken
+ pSVData->mnMainThreadId = ::vos::OThread::getCurrentIdentifier();
+
+ NAMESPACE_VOS( OStartupInfo ) aStartInfo;
+ NAMESPACE_RTL( OUString ) aExeFileName;
+
+#ifdef REMOTE_APPSERVER
+ // create a readonly applicat rdb.
+ // NOTE : This is a hack, a servicemanager is needed before SFX, so
+ // there is created one with the readonly registry. There
+ // now exists 2 Servicemanager
+
+ Application::EnterMultiThread( TRUE );
+
+ Reference< XMultiServiceFactory > rSMgr = createServiceFactory();
+ Reference< XInterface > x = rSMgr->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry" ) ) );
+ Reference< XSimpleRegistry > rSimple( x , UNO_QUERY );
+ rSimple->open( ::utl::getPathToSystemRegistry() , sal_True , sal_False );
+ if( rSimple->isValid() )
+ {
+ Reference < XInitialization > rInit( rSMgr , UNO_QUERY );
+ Any a;
+ a <<= rSimple;
+ Sequence< Any > seq( &a , 1 );
+ rInit->initialize( seq );
+ }
+ // servicemanager up -> copy user installation
+ Any aAny;
+ Reference <XInterface> xRef = rSMgr->createInstanceWithArguments(
+ OUString::createFromAscii( "com.sun.star.portal.InstallUser" ),
+ Sequence<Any>( &aAny, 1 ) );
+
+
+ // OSL_ENSURE( 0 , "Office is waiting ....\n" );
+
+
+// sal_Bool bStandAloneMode = sal_False;
+// sal_Bool bStartDesktop = sal_True;
+
+ OUString conDcp;
+
+ // Anderes Flag setzen, wenn der Server von Hand gestartet wird...
+ USHORT nArgs = Application::GetCommandLineParamCount();
+ for( USHORT n = 0; n < nArgs; n++ )
+ {
+ XubString aParam = Application::GetCommandLineParam( n );
+ if ( (aParam.GetChar( 0 ) == '/') || (aParam.GetChar( 0 ) == '-') )
+ {
+ aParam.SetChar( 0 , (sal_Unicode)'-' );
+ if ( aParam.EqualsIgnoreCaseAscii( "-appserver" ) )
+ ; //bStandAloneMode = sal_True;
+
+ else if ( aParam.EqualsIgnoreCaseAscii( "-bean" ) )
+ ; //bStartDesktop = sal_False;
+
+ else if(aParam.Copy(0, 8).EqualsIgnoreCaseAscii("-accept="))
+ {
+// ++ n;
+// conDcp = Application::GetCommandLineParam(n);
+ conDcp = aParam.Copy(8);
+
+#ifdef DEBUG
+ OString tmp = OUStringToOString(conDcp, RTL_TEXTENCODING_ASCII_US);
+ OSL_TRACE("svmain.cxx: -accept with %s", tmp.getStr());
+#endif
+ }
+ }
+ }
+
+// ::vos::OThread *pUnoBroker = 0;
+
+// if (bStandAloneMode)
+// {
+ Config aCfg( UniString::CreateFromAscii( "remote.ini" ) );
+ aCfg.SetGroup( ByteString("Remote" ) );
+ ByteString s = aCfg.ReadKey( "ROffice" );
+ OUString aROffice = OUString::createFromAscii( s.GetBuffer() );
+ aROffice.trim();
+ if ( ! aROffice.getLength() )
+ aROffice = OUString(
+ RTL_CONSTASCII_USTRINGPARAM("socket,host=localhost,port=8125;urp;"));
+
+
+ if(conDcp.getLength() > 0)
+ aROffice = conDcp;
+
+ // create condition now to avoid race
+ pSVData->mpStartUpCond = new NAMESPACE_VOS(OCondition);
+
+ pSVData->mpUserInfo = new UserOnPrintServer;
+
+ // accept incoming connections
+ if(!vcl_accept::accept(aROffice, rSMgr))
+ return sal_False;
+
+// pUnoBroker = new vcl_AcceptorThread(
+// rSMgr ,
+// NULL, /*rInitialObject ,*/
+// aROffice );
+// }
+// else
+// pUnoBroker = new UnoBrokerThread( rSMgr , NULL /*rInitialObject*/);
+
+
+ pSVData->mpRmEventQueue = new RmEventQueue;
+ pSVData->mpRemotePrinterList = new RemotePrinterList( rSMgr );
+ pSVData->mpWindowObjectMutex = new VOS_NAMESPACE(OMutex,vos);
+ pSVData->maAppData.mpSolarMutex = new ImplRemoteYieldMutex;
+
+ pSVData->maGDIData.mpScreenFontList = new ImplDevFontList;
+ pSVData->maGDIData.mpScreenFontCache = new ImplFontCache( FALSE );
+
+
+// pUnoBroker->create();
+ pSVData->mpStartUpCond->wait();
+ delete pSVData->mpStartUpCond;
+ pSVData->mpStartUpCond = NULL;
+
+ if( pSVData->mxClientFactory.is() )
+ {
+ pSVData->mpAtoms = new ::vcl::AtomClient(
+ Reference< ::com::sun::star::portal::client::XAtomServer >(
+ pSVData->mxClientFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "ClientAtomServer.stardiv.de" ) ) ), UNO_QUERY ) );
+
+ Reference< XInterface > rX = pSVData->mxClientFactory->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "OfficeStatus.stardiv.de" ) ) );
+
+ pSVData->mxStatus = Reference < ::com::sun::star::portal::client::XRmStatus > ( rX , UNO_QUERY );
+ if( pSVData->mxStatus->GetRemoteVersion() != REMOTE_VCLVERSION )
+ {
+ pSVData->mxStatus->ShowError(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("Wrong Office-Version")), 0 );
+ pSVData->mxStatus->Quit();
+ return sal_False;
+ }
+ }
+ else
+ {
+ return sal_False;
+ }
+
+ // add client printers
+ REF( NMSP_CLIENT::XRmPrinterEnvironment ) xClientPrinterEnvironment(
+ pSVData->mxClientFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OfficePrinterEnvironment.stardiv.de" ) ) ), NMSP_UNO::UNO_QUERY );
+ if( xClientPrinterEnvironment.is() )
+ {
+ ::rtl::OUString aDefPrinter = xClientPrinterEnvironment->GetDefaultPrinterName();
+ NMSP_UNO::Sequence< ::rtl::OUString > aPrinters;
+ xClientPrinterEnvironment->GetPrinterNames( aPrinters );
+ int nPrinters = aPrinters.getLength();
+ if( nPrinters )
+ {
+ while( nPrinters-- )
+ {
+ ImplAddRemotePrinter(
+ aPrinters.getConstArray()[nPrinters],
+ String::CreateFromAscii( RVP_CLIENT_SERVER_NAME ),
+ aDefPrinter == aPrinters.getConstArray()[nPrinters] ? TRUE : FALSE,
+ FALSE
+ );
+ }
+ }
+ }
+
+ // add printers on print servers
+ ::rtl::OUString aValue;
+ if( aStartInfo.getEnvironment( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SOFFICE_PRINTER_URL" ) ), aValue ) ==
+ NAMESPACE_VOS( OStartupInfo ) :: E_None )
+ {
+ String aPrinterEnv = aValue;
+ if( aPrinterEnv.Len() > 0 )
+ {
+ USHORT nPrinters = aPrinterEnv.GetTokenCount( ';' );
+ for ( USHORT n = 0; n < nPrinters; n++ )
+ {
+ String aPrinterInfo = aPrinterEnv.GetToken( n, ';' );
+
+ String aServer = aPrinterInfo.GetToken( 0, '@' );
+ String aPrinter = aPrinterInfo.GetToken( 1, '@' );
+ BOOL bSetDef = aPrinterInfo.GetToken( 2, '@' ).EqualsAscii( "1" );
+ ImplAddRemotePrinter( aPrinter, aServer, bSetDef, FALSE );
+ }
+ }
+ }
+
+ pSVData->maAppData.mpSolarMutex->acquire();
+
+
+#endif
+
+ // Sal initialisieren
+#ifndef REMOTE_APPSERVER
+ pSVData->mpDefInst = CreateSalInstance();
+ if ( !pSVData->mpDefInst )
+ return FALSE;
+#endif
+
+ // Den AppFileName gleich holen und absolut machen, bevor das
+ // WorkingDirectory sich aendert...
+ aStartInfo.getExecutableFile( aExeFileName );
+
+ // convert path to native file format
+ rtl::OUString aNativeFileName;
+ osl::FileBase::getSystemPathFromNormalizedPath(aExeFileName, aNativeFileName);
+
+ pSVData->maAppData.mpAppFileName = new String( aNativeFileName );
+
+ // Initialize global data
+ pSVData->maGDIData.mpScreenFontList = new ImplDevFontList;
+ pSVData->maGDIData.mpScreenFontCache = new ImplFontCache( FALSE );
+ pSVData->maGDIData.mpGrfConverter = new GraphicConverter;
+
+ // Exception-Handler setzen
+ // HACK: Hier SystemExchange initialisieren, damit Exception-Handler unter Windows funktioniert
+ CreateSystemExchange();
+ ImplVCLExceptionHandler aExceptionHandler;
+
+ // Debug-Daten initialisieren
+ DBGGUI_INIT();
+
+ // Application-Main rufen
+ pSVData->maAppData.mbInAppMain = TRUE;
+ pSVData->mpApp->Main();
+ pSVData->maAppData.mbInAppMain = FALSE;
+
+ // Debug Daten zuruecksetzen
+ DBGGUI_DEINIT();
+
+// #ifdef REMOTE_APPSERVER
+// if( pUnoBroker )
+// pUnoBroker->terminate();
+// #endif
+
+ // Access list
+ List* pList = pSVData->maAppData.mpAccessList;
+ if( pList )
+ {
+ for( void* pLink = pList->First(); pLink; pLink = pList->Next() )
+ delete (Link*) pLink;
+ delete pList;
+ pSVData->maAppData.mpAccessList = NULL;
+ }
+
+ // globale daten wieder freigeben
+#ifndef REMOTE_APPSERVER
+ SalSound::Release();
+ SalOpenGL::Release();
+#endif
+
+ // free global data
+ delete pSVData->maGDIData.mpGrfConverter;
+
+ if ( pSVData->maAppData.mpIdleMgr )
+ delete pSVData->maAppData.mpIdleMgr;
+ ImplDeInitTimer();
+
+ if ( pSVData->maWinData.mpMsgBoxImgList )
+ {
+ delete pSVData->maWinData.mpMsgBoxImgList;
+ pSVData->maWinData.mpMsgBoxImgList = NULL;
+ }
+ if ( pSVData->maCtrlData.mpCheckImgList )
+ {
+ delete pSVData->maCtrlData.mpCheckImgList;
+ pSVData->maCtrlData.mpCheckImgList = NULL;
+ }
+ if ( pSVData->maCtrlData.mpRadioImgList )
+ {
+ delete pSVData->maCtrlData.mpRadioImgList;
+ pSVData->maCtrlData.mpRadioImgList = NULL;
+ }
+ if ( pSVData->maCtrlData.mpPinImgList )
+ {
+ delete pSVData->maCtrlData.mpPinImgList;
+ pSVData->maCtrlData.mpPinImgList = NULL;
+ }
+ if ( pSVData->maCtrlData.mpSplitHPinImgList )
+ {
+ delete pSVData->maCtrlData.mpSplitHPinImgList;
+ pSVData->maCtrlData.mpSplitHPinImgList = NULL;
+ }
+ if ( pSVData->maCtrlData.mpSplitVPinImgList )
+ {
+ delete pSVData->maCtrlData.mpSplitVPinImgList;
+ pSVData->maCtrlData.mpSplitVPinImgList = NULL;
+ }
+ if ( pSVData->maCtrlData.mpSplitHArwImgList )
+ {
+ delete pSVData->maCtrlData.mpSplitHArwImgList;
+ pSVData->maCtrlData.mpSplitHArwImgList = NULL;
+ }
+ if ( pSVData->maCtrlData.mpSplitVArwImgList )
+ {
+ delete pSVData->maCtrlData.mpSplitVArwImgList;
+ pSVData->maCtrlData.mpSplitVArwImgList = NULL;
+ }
+ if ( pSVData->mpDefaultWin )
+ {
+ delete pSVData->mpDefaultWin;
+ pSVData->mpDefaultWin = NULL;
+ }
+ if ( pSVData->mpResMgr )
+ {
+ delete pSVData->mpResMgr;
+ pSVData->mpResMgr = NULL;
+ }
+
+#ifdef REMOTE_APPSERVER
+ if( pSVData->mpUserInfo )
+ {
+ try
+ {
+ delete pSVData->mpUserInfo;
+ }
+ catch(...)
+ {
+ }
+ pSVData->mpUserInfo = NULL;
+ }
+ if( pSVData->mpRemotePrinterList )
+ {
+ try
+ {
+ delete pSVData->mpRemotePrinterList;
+ }
+ catch(...)
+ {
+ }
+ pSVData->mpRemotePrinterList = NULL;
+ }
+ if( pSVData->mxClientFactory.is() )
+ {
+ try
+ {
+ pSVData->mxClientFactory = Reference < XMultiServiceFactory >();
+ }
+ catch(...)
+ {
+ }
+ }
+
+ if( pSVData->mxMultiFactory.is() )
+ {
+ try
+ {
+ pSVData->mxMultiFactory.clear();
+ }
+ catch(...)
+ {
+ }
+
+ }
+ CORmStarOffice::eraseRemoteCaches();
+ if( pSVData->mxStatus.is() )
+ {
+ try
+ {
+ pSVData->mxStatus->Quit();
+ pSVData->mxStatus = Reference < ::com::sun::star::portal::client::XRmStatus >();
+ }
+ catch(...)
+ {
+ }
+
+ }
+
+ pSVData->maAppData.mpSolarMutex->release();
+ delete pSVData->maAppData.mpSolarMutex;
+ pSVData->maAppData.mpSolarMutex = NULL;
+ pSVData->mpOTimer->release();
+ pSVData->mpOTimer = NULL;
+ delete pSVData->mpRmEventQueue;
+ pSVData->mpRmEventQueue = NULL;
+ delete pSVData->mpWindowObjectMutex;
+ pSVData->mpWindowObjectMutex = NULL;
+
+ if ( pSVData->mpKeyNames )
+ {
+ for( String* pObj = pSVData->mpKeyNames->First(); pObj; pObj = pSVData->mpKeyNames->Next() )
+ delete pObj;
+ delete pSVData->mpKeyNames;
+ }
+ delete pSVData->mpAtoms;
+#endif
+
+ if ( pSVData->maAppData.mpSettings )
+ {
+ delete pSVData->maAppData.mpSettings;
+ pSVData->maAppData.mpSettings = NULL;
+ }
+ if ( pSVData->maAppData.mpAccelMgr )
+ {
+ delete pSVData->maAppData.mpAccelMgr;
+ pSVData->maAppData.mpAccelMgr = NULL;
+ }
+ if ( pSVData->maAppData.mpUniqueIdCont )
+ {
+ delete pSVData->maAppData.mpUniqueIdCont;
+ pSVData->maAppData.mpUniqueIdCont = NULL;
+ }
+ if ( pSVData->maAppData.mpAppFileName )
+ {
+ delete pSVData->maAppData.mpAppFileName;
+ pSVData->maAppData.mpAppFileName = NULL;
+ }
+ if ( pSVData->maAppData.mpAppName )
+ {
+ delete pSVData->maAppData.mpAppName;
+ pSVData->maAppData.mpAppName = NULL;
+ }
+ if ( pSVData->maAppData.mpDisplayName )
+ {
+ delete pSVData->maAppData.mpDisplayName;
+ pSVData->maAppData.mpDisplayName = NULL;
+ }
+ if ( pSVData->maAppData.mpResPath )
+ {
+ delete pSVData->maAppData.mpResPath;
+ pSVData->maAppData.mpResPath = NULL;
+ }
+
+ if ( pSVData->maAppData.mpFirstHotKey )
+ ImplFreeHotKeyData();
+ if ( pSVData->maAppData.mpFirstEventHook )
+ ImplFreeEventHookData();
+
+ ImplDeletePrnQueueList();
+ delete pSVData->maGDIData.mpScreenFontList;
+ pSVData->maGDIData.mpScreenFontList = NULL;
+ delete pSVData->maGDIData.mpScreenFontCache;
+ pSVData->maGDIData.mpScreenFontCache = NULL;
+ ImplFreeOutDevFontData();
+
+ ResMgr::DestroyAllResMgr();
+
+ // Sal deinitialisieren
+#ifndef REMOTE_APPSERVER
+ DestroySalInstance( pSVData->mpDefInst );
+#endif
+
+ DeInitTools();
+
+ return TRUE;
+
+ return FALSE;
+}
diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx
new file mode 100644
index 000000000000..78235032e919
--- /dev/null
+++ b/vcl/source/app/timer.cxx
@@ -0,0 +1,490 @@
+/*************************************************************************
+ *
+ * $RCSfile: timer.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_TIMER_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+#else
+#include <rmevents.hxx>
+#endif
+
+#ifndef _TIME_HXX
+#include <tools/time.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+
+#define protected public
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#undef protected
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define MAX_TIMER_PERIOD ((ULONG)0xFFFFFFFF)
+
+// ---------------------
+// - TimeManager-Types -
+// ---------------------
+
+struct ImplTimerData
+{
+ ImplTimerData* mpNext; // Pointer to the next Instance
+ Timer* mpSVTimer; // Pointer to SV Timer instance
+ ULONG mnUpdateTime; // Last Update Time
+ ULONG mnTimerUpdate; // TimerCallbackProcs on stack
+ BOOL mbDelete; // Wurde Timer waehren Update() geloescht
+ BOOL mbInTimeout; // Befinden wir uns im Timeout-Handler
+};
+
+// =======================================================================
+
+void ImplDeInitTimer()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplTimerData* pTimerData = pSVData->mpFirstTimerData;
+
+ if ( pTimerData )
+ {
+ do
+ {
+ ImplTimerData* pTempTimerData = pTimerData;
+ if ( pTimerData->mpSVTimer )
+ {
+ pTimerData->mpSVTimer->mbActive = FALSE;
+ pTimerData->mpSVTimer->mpTimerData = NULL;
+ }
+ pTimerData = pTimerData->mpNext;
+ delete pTempTimerData;
+ }
+ while ( pTimerData );
+
+ pSVData->mpFirstTimerData = NULL;
+ pSVData->mnTimerPeriod = 0;
+#ifndef REMOTE_APPSERVER
+ SalTimer::Stop();
+#else
+ if ( pSVData->mpOTimer )
+ pSVData->mpOTimer->StopTimer();
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplStartTimer( ImplSVData* pSVData, ULONG nMS )
+{
+ if ( !nMS )
+ nMS = 1;
+
+#ifndef REMOTE_APPSERVER
+ if ( nMS != pSVData->mnTimerPeriod )
+ {
+ pSVData->mnTimerPeriod = nMS;
+ SalTimer::Start( nMS );
+ }
+#else
+ pSVData->mnTimerPeriod = nMS;
+ if ( !pSVData->mpOTimer )
+ {
+ pSVData->mpOTimer = new VclOTimer;
+ pSVData->mpOTimer->acquire();
+ }
+ else
+ pSVData->mpOTimer->StopTimer();
+ pSVData->mpOTimer->setRemainingTime( nMS, 0 );
+ pSVData->mpOTimer->StartTimer();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTimerCallbackProc()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplTimerData* pTimerData;
+ ImplTimerData* pPrevTimerData;
+ ULONG nMinPeriod = MAX_TIMER_PERIOD;
+ ULONG nDeltaTime;
+ ULONG nTime = Time::GetSystemTicks();
+
+ if ( pSVData->mbNoCallTimer )
+ return;
+
+ pSVData->mnTimerUpdate++;
+ pSVData->mbNotAllTimerCalled = TRUE;
+
+ // Suche Timer raus, wo der Timeout-Handler gerufen werden muss
+ pTimerData = pSVData->mpFirstTimerData;
+ while ( pTimerData )
+ {
+ // Wenn Timer noch nicht neu ist und noch nicht geloescht wurde
+ // und er sich nicht im Timeout-Handler befindet,
+ // dann den Handler rufen, wenn die Zeit abgelaufen ist
+ if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) &&
+ !pTimerData->mbDelete && !pTimerData->mbInTimeout )
+ {
+ // Zeit abgelaufen
+ if ( (pTimerData->mnUpdateTime+pTimerData->mpSVTimer->mnTimeout) <= nTime )
+ {
+ // Neue Updatezeit setzen
+ pTimerData->mnUpdateTime = nTime;
+
+ // kein AutoTimer, dann anhalten
+ if ( !pTimerData->mpSVTimer->mbAuto )
+ {
+ pTimerData->mpSVTimer->mbActive = FALSE;
+ pTimerData->mbDelete = TRUE;
+ }
+
+ // call Timeout
+ pTimerData->mbInTimeout = TRUE;
+ pTimerData->mpSVTimer->Timeout();
+ pTimerData->mbInTimeout = FALSE;
+ }
+ }
+
+ pTimerData = pTimerData->mpNext;
+ }
+
+ // Neue Zeit ermitteln
+ ULONG nNewTime = Time::GetSystemTicks();
+ pPrevTimerData = NULL;
+ pTimerData = pSVData->mpFirstTimerData;
+ while ( pTimerData )
+ {
+ // Befindet sich Timer noch im Timeout-Handler, dann ignorieren
+ if ( pTimerData->mbInTimeout )
+ {
+ pPrevTimerData = pTimerData;
+ pTimerData = pTimerData->mpNext;
+ }
+ // Wurde Timer zwischenzeitlich zerstoert ?
+ else if ( pTimerData->mbDelete )
+ {
+ if ( pPrevTimerData )
+ pPrevTimerData->mpNext = pTimerData->mpNext;
+ else
+ pSVData->mpFirstTimerData = pTimerData->mpNext;
+ if ( pTimerData->mpSVTimer )
+ pTimerData->mpSVTimer->mpTimerData = NULL;
+ ImplTimerData* pTempTimerData = pTimerData;
+ pTimerData = pTimerData->mpNext;
+ delete pTempTimerData;
+ }
+ else
+ {
+ pTimerData->mnTimerUpdate = 0;
+ // kleinste Zeitspanne ermitteln
+ if ( pTimerData->mnUpdateTime == nTime )
+ {
+ nDeltaTime = pTimerData->mpSVTimer->mnTimeout;
+ if ( nDeltaTime < nMinPeriod )
+ nMinPeriod = nDeltaTime;
+ }
+ else
+ {
+ nDeltaTime = pTimerData->mnUpdateTime + pTimerData->mpSVTimer->mnTimeout;
+ if ( nDeltaTime < nNewTime )
+ nMinPeriod = 1;
+ else
+ {
+ nDeltaTime -= nNewTime;
+ if ( nDeltaTime < nMinPeriod )
+ nMinPeriod = nDeltaTime;
+ }
+ }
+ pPrevTimerData = pTimerData;
+ pTimerData = pTimerData->mpNext;
+ }
+ }
+
+ // Wenn keine Timer mehr existieren, dann Clock loeschen
+ if ( !pSVData->mpFirstTimerData )
+ {
+#ifndef REMOTE_APPSERVER
+ SalTimer::Stop();
+#else
+ if ( pSVData->mpOTimer )
+ pSVData->mpOTimer->StopTimer();
+#endif
+ pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
+ }
+ else
+ ImplStartTimer( pSVData, nMinPeriod );
+
+ pSVData->mnTimerUpdate--;
+ pSVData->mbNotAllTimerCalled = FALSE;
+}
+
+// =======================================================================
+
+#ifdef REMOTE_APPSERVER
+
+VclOTimer::VclOTimer() :
+ maTimeoutHdl( LINK( this, VclOTimer, Timeout ) )
+{
+ mbSend = FALSE;
+}
+
+void SAL_CALL VclOTimer::onShot()
+{
+ stop(); // start wird durch ImplTimerCallbackProc() gerufen
+ if ( !mbSend )
+ {
+ mbSend = TRUE;
+ if ( !Application::PostUserEvent( maTimeoutHdl ) )
+ {
+ mbSend = FALSE;
+ start();
+ }
+ }
+}
+
+IMPL_LINK( VclOTimer, Timeout, void*, EMPTYARG )
+{
+ mbSend = FALSE;
+ ImplTimerCallbackProc();
+ return 0;
+}
+
+void VclOTimer::StartTimer()
+{
+ start();
+}
+
+void VclOTimer::StopTimer()
+{
+ stop();
+}
+
+#endif
+
+// =======================================================================
+
+Timer::Timer()
+{
+ mpTimerData = NULL;
+ mnTimeout = 1;
+ mbAuto = FALSE;
+ mbActive = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Timer::Timer( const Timer& rTimer )
+{
+ mpTimerData = NULL;
+ mnTimeout = rTimer.mnTimeout;
+ mbAuto = FALSE;
+ mbActive = FALSE;
+ maTimeoutHdl = rTimer.maTimeoutHdl;
+
+ if ( rTimer.IsActive() )
+ Start();
+}
+
+// -----------------------------------------------------------------------
+
+Timer::~Timer()
+{
+ if ( mpTimerData )
+ {
+ mpTimerData->mbDelete = TRUE;
+ mpTimerData->mpSVTimer = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Timer::Timeout()
+{
+ maTimeoutHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Timer::SetTimeout( ULONG nNewTimeout )
+{
+ mnTimeout = nNewTimeout;
+
+ // Wenn Timer aktiv, dann Clock erneuern
+ if ( mbActive )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->mnTimerUpdate && (mnTimeout < pSVData->mnTimerPeriod) )
+ ImplStartTimer( pSVData, mnTimeout );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Timer::Start()
+{
+ mbActive = TRUE;
+
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !mpTimerData )
+ {
+ if ( !pSVData->mpFirstTimerData )
+ {
+ pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
+#ifndef REMOTE_APPSERVER
+ SalTimer::SetCallback( ImplTimerCallbackProc );
+#endif
+ }
+
+ // insert timer and start
+ mpTimerData = new ImplTimerData;
+ mpTimerData->mpSVTimer = this;
+ mpTimerData->mnUpdateTime = Time::GetSystemTicks();
+ mpTimerData->mnTimerUpdate = pSVData->mnTimerUpdate;
+ mpTimerData->mbDelete = FALSE;
+ mpTimerData->mbInTimeout = FALSE;
+
+ // !!!!! Wegen SFX hinten einordnen !!!!!
+ ImplTimerData* pPrev = NULL;
+ ImplTimerData* pData = pSVData->mpFirstTimerData;
+ while ( pData )
+ {
+ pPrev = pData;
+ pData = pData->mpNext;
+ }
+ mpTimerData->mpNext = NULL;
+ if ( pPrev )
+ pPrev->mpNext = mpTimerData;
+ else
+ pSVData->mpFirstTimerData = mpTimerData;
+
+ if ( mnTimeout < pSVData->mnTimerPeriod )
+ ImplStartTimer( pSVData, mnTimeout );
+ }
+ else
+ {
+ mpTimerData->mnUpdateTime = Time::GetSystemTicks();
+ mpTimerData->mnTimerUpdate = pSVData->mnTimerUpdate;
+ mpTimerData->mbDelete = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Timer::Stop()
+{
+ mbActive = FALSE;
+
+ if ( mpTimerData )
+ mpTimerData->mbDelete = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Timer& Timer::operator=( const Timer& rTimer )
+{
+ if ( IsActive() )
+ Stop();
+
+ mbActive = FALSE;
+ mnTimeout = rTimer.mnTimeout;
+ maTimeoutHdl = rTimer.maTimeoutHdl;
+
+ if ( rTimer.IsActive() )
+ Start();
+
+ return *this;
+}
+
+// =======================================================================
+
+AutoTimer::AutoTimer()
+{
+ mbAuto = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+AutoTimer::AutoTimer( const AutoTimer& rTimer ) : Timer( rTimer )
+{
+ mbAuto = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+AutoTimer& AutoTimer::operator=( const AutoTimer& rTimer )
+{
+ Timer::operator=( rTimer );
+ return *this;
+}
diff --git a/vcl/source/app/unohelp.cxx b/vcl/source/app/unohelp.cxx
new file mode 100644
index 000000000000..c01deefc4897
--- /dev/null
+++ b/vcl/source/app/unohelp.cxx
@@ -0,0 +1,275 @@
+/*************************************************************************
+ *
+ * $RCSfile: unohelp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#pragma hdrstop
+
+#include <unohelp.hxx>
+
+#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#endif
+
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_
+#include <unotools/processfactory.hxx>
+#endif
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <cppuhelper/factory.hxx>
+
+#include <uno/environment.h>
+#include <uno/mapping.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/module.h>
+
+#ifndef _COM_SUN_STAR_TEXT_XBREAKITERATOR_HPP_
+#include <com/sun/star/text/XBreakIterator.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_XCHARACTERCLASSIFICATION_HPP_
+#include <com/sun/star/lang/XCharacterClassification.hpp>
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::rtl;
+
+#define DOSTRING( x ) #x
+#define STRING( x ) DOSTRING( x )
+
+#define DOCONCAT4( x, y, z, a ) x##y##z##a
+#define CONCAT4( x, y, z, a ) DOCONCAT4(x,y,z,a)
+#define DOCONCAT5( x, y, z, a, b ) x##y##z##a##b
+#define CONCAT5( x, y, z, a, b ) DOCONCAT5(x,y,z,a,b)
+
+#ifdef UNX
+#define LIBNAME(name) STRING(CONCAT5(lib,name,SUPD, DLLSUFFIX,.so))
+#else
+#define LIBNAME(name) STRING(CONCAT4( name, SUPD, DLLSUFFIX, .dll))
+#endif
+
+Reference< XSingleServiceFactory > ImplLoadLibComponentFactory(
+ const OUString & rLibName, const OUString & rImplName,
+ const Reference< XMultiServiceFactory > & xSF, const Reference< XRegistryKey > & xKey )
+{
+ Reference< XSingleServiceFactory > xRet;
+
+ oslModule lib = osl_loadModule( rLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
+ if (lib)
+ {
+ void * pSym;
+
+ // ========================= LATEST VERSION =========================
+ OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) );
+ if (pSym = osl_getSymbol( lib, aGetEnvName.pData ))
+ {
+ uno_Environment * pCurrentEnv = 0;
+ uno_Environment * pEnv = 0;
+ const sal_Char * pEnvTypeName = 0;
+ (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv );
+
+ sal_Bool bNeedsMapping =
+ (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME ));
+
+ OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) );
+
+ if (bNeedsMapping)
+ {
+ if (! pEnv)
+ uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 );
+ if (pEnv)
+ {
+ OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
+ uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 );
+ if (pCurrentEnv)
+ bNeedsMapping = (pEnv != pCurrentEnv);
+ }
+ }
+
+ OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) );
+ if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
+ {
+ OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
+
+ if (bNeedsMapping)
+ {
+ if (pEnv && pCurrentEnv)
+ {
+ Mapping aCurrent2Env( pCurrentEnv, pEnv );
+ Mapping aEnv2Current( pEnv, pCurrentEnv );
+
+ if (aCurrent2Env.is() && aEnv2Current.is())
+ {
+ void * pSMgr = aCurrent2Env.mapInterface(
+ xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) );
+ void * pKey = aCurrent2Env.mapInterface(
+ xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) );
+
+ void * pSSF = (*((component_getFactoryFunc)pSym))(
+ aImplName.getStr(), pSMgr, pKey );
+
+ if (pKey)
+ (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey );
+ if (pSMgr)
+ (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr );
+
+ if (pSSF)
+ {
+ aEnv2Current.mapInterface(
+ reinterpret_cast< void ** >( &xRet ),
+ pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
+ (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF );
+ }
+ }
+ }
+ }
+ else
+ {
+ XSingleServiceFactory * pRet = (XSingleServiceFactory *)
+ (*((component_getFactoryFunc)pSym))(
+ aImplName.getStr(), xSF.get(), xKey.get() );
+ if (pRet)
+ {
+ xRet = pRet;
+ pRet->release();
+ }
+ }
+ }
+
+ if (pEnv)
+ (*pEnv->release)( pEnv );
+ if (pCurrentEnv)
+ (*pCurrentEnv->release)( pCurrentEnv );
+ }
+
+
+ if (! xRet.is())
+ osl_unloadModule( lib );
+ }
+
+ return xRet;
+}
+
+uno::Reference < text::XBreakIterator > vcl::unohelper::CreateBreakIterator()
+{
+ uno::Reference < text::XBreakIterator > xB;
+ uno::Reference< lang::XMultiServiceFactory > xMSF = ::utl::getProcessServiceFactory();
+ if ( xMSF.is() )
+ {
+ uno::Reference < uno::XInterface > xI = xMSF->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.text.BreakIterator" ) );
+ if ( xI.is() )
+ {
+ uno::Any x = xI->queryInterface( ::getCppuType((const uno::Reference< text::XBreakIterator >*)0) );
+ x >>= xB;
+ }
+ }
+ if( !xB.is() )
+ {
+ uno::Reference< lang::XSingleServiceFactory > xSSF = ImplLoadLibComponentFactory(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( LIBNAME( int ) ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.BreakIterator" ) ),
+ Reference< XMultiServiceFactory >(), Reference< XRegistryKey >() );
+
+ uno::Reference < uno::XInterface > xI = xSSF->createInstance();
+ if ( xI.is() )
+ {
+ uno::Any x = xI->queryInterface( ::getCppuType((const uno::Reference< text::XBreakIterator >*)0) );
+ x >>= xB;
+ }
+ }
+ return xB;
+}
+
+uno::Reference < lang::XCharacterClassification > vcl::unohelper::CreateCharacterClassification()
+{
+ uno::Reference < lang::XCharacterClassification > xB;
+ uno::Reference< lang::XMultiServiceFactory > xMSF = ::utl::getProcessServiceFactory();
+ if ( xMSF.is() )
+ {
+ uno::Reference < uno::XInterface > xI = xMSF->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.lang.CharacterClassification" ) );
+ if ( xI.is() )
+ {
+ uno::Any x = xI->queryInterface( ::getCppuType((const uno::Reference< lang::XCharacterClassification >*)0) );
+ x >>= xB;
+ }
+ }
+ if( !xB.is() )
+ {
+ uno::Reference< lang::XSingleServiceFactory > xSSF = ImplLoadLibComponentFactory(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( LIBNAME( int ) ) ), OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.lang.CharacterClassification" ) ),
+ Reference< XMultiServiceFactory >(), Reference< XRegistryKey >() );
+
+ uno::Reference < uno::XInterface > xI = xSSF->createInstance();
+ if ( xI.is() )
+ {
+ uno::Any x = xI->queryInterface( ::getCppuType((const uno::Reference< lang::XCharacterClassification >*)0) );
+ x >>= xB;
+ }
+ }
+ return xB;
+}
+
+
+
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
new file mode 100644
index 000000000000..1ac338e26755
--- /dev/null
+++ b/vcl/source/control/button.cxx
@@ -0,0 +1,3010 @@
+/*************************************************************************
+ *
+ * $RCSfile: button.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_BUTTON_CXX
+
+#include <tools/debug.hxx>
+
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_IAMGE_HXX
+#include <image.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_BITMAPEX_HXX
+#include <bitmapex.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_DIALOG_HXX
+#include <dialog.hxx>
+#endif
+#ifndef _SV_FIXED_HXX
+#include <fixed.hxx>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_BUTTON_HXX
+#include <button.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define PUSHBUTTON_VIEW_STYLE (WB_3DLOOK | \
+ WB_LEFT | WB_CENTER | WB_RIGHT | \
+ WB_TOP | WB_VCENTER | WB_BOTTOM | \
+ WB_WORDBREAK | WB_NOLABEL | \
+ WB_DEFBUTTON | WB_NOLIGHTBORDER | \
+ WB_RECTSTYLE | WB_SMALLSTYLE)
+#define RADIOBUTTON_VIEW_STYLE (WB_3DLOOK | \
+ WB_LEFT | WB_CENTER | WB_RIGHT | \
+ WB_TOP | WB_VCENTER | WB_BOTTOM | \
+ WB_WORDBREAK | WB_NOLABEL)
+#define CHECKBOX_VIEW_STYLE (WB_3DLOOK | \
+ WB_LEFT | WB_CENTER | WB_RIGHT | \
+ WB_TOP | WB_VCENTER | WB_BOTTOM | \
+ WB_WORDBREAK | WB_NOLABEL)
+
+// =======================================================================
+
+Button::Button( WindowType nType ) :
+ Control( nType )
+{
+}
+
+// -----------------------------------------------------------------------
+
+Button::Button( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_BUTTON )
+{
+ ImplInit( pParent, nStyle, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+Button::Button( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_BUTTON )
+{
+ rResId.SetRT( RSC_BUTTON );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle, NULL );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void Button::Click()
+{
+ maClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+XubString Button::GetStandardText( StandardButtonType eButton )
+{
+ static USHORT aResIdAry[BUTTON_COUNT] =
+ {
+ SV_BUTTONTEXT_OK,
+ SV_BUTTONTEXT_CANCEL,
+ SV_BUTTONTEXT_YES,
+ SV_BUTTONTEXT_NO,
+ SV_BUTTONTEXT_RETRY,
+ SV_BUTTONTEXT_HELP,
+ SV_BUTTONTEXT_CLOSE,
+ SV_BUTTONTEXT_MORE
+ };
+
+ ResId aResId( aResIdAry[(USHORT)eButton], ImplGetResMgr() );
+ XubString aText( aResId );
+ return aText;
+}
+
+// -----------------------------------------------------------------------
+
+XubString Button::GetStandardHelpText( StandardButtonType /* eButton */ )
+{
+ XubString aHelpText;
+ return aHelpText;
+}
+
+// =======================================================================
+
+void PushButton::ImplInitData()
+{
+ mbPushButton = TRUE;
+
+ meSymbol = SYMBOL_NOSYMBOL;
+ meImageAlign = IMAGEALIGN_TOP;
+ meState = STATE_NOCHECK;
+ meSaveValue = STATE_NOCHECK;
+ mnDDStyle = 0;
+ mnButtonState = 0;
+ mbPressed = FALSE;
+ mbInUserDraw = FALSE;
+ mpBitmapEx = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
+ Button::ImplInit( pParent, nStyle, NULL );
+
+ if ( nStyle & WB_NOLIGHTBORDER )
+ mnButtonState |= BUTTON_DRAW_NOLIGHTBORDER;
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits PushButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOTABSTOP) )
+ nStyle |= WB_TABSTOP;
+ if ( !(nStyle & WB_NOGROUP) &&
+ (!pPrevWindow ||
+ ((pPrevWindow->GetType() != WINDOW_PUSHBUTTON) &&
+ (pPrevWindow->GetType() != WINDOW_OKBUTTON) &&
+ (pPrevWindow->GetType() != WINDOW_CANCELBUTTON) &&
+ (pPrevWindow->GetType() != WINDOW_HELPBUTTON)) ) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetPushButtonFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetButtonTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ SetBackground();
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::ImplDrawPushButtonFrame( Window* pDev,
+ Rectangle& rRect, USHORT nStyle )
+{
+ if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) )
+ {
+ StyleSettings aStyleSettings = pDev->GetSettings().GetStyleSettings();
+ if ( pDev->IsControlBackground() )
+ aStyleSettings.Set3DColors( pDev->GetControlBackground() );
+
+ USHORT nPushButtonSysStyle = aStyleSettings.GetPushButtonStyle() & STYLE_PUSHBUTTON_STYLE;
+ if ( nPushButtonSysStyle == STYLE_PUSHBUTTON_MAC )
+ {
+ pDev->SetLineColor();
+ pDev->SetFillColor( aStyleSettings.GetFaceColor() );
+ pDev->DrawRect( rRect );
+
+ if ( (aStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
+ (pDev->GetOutDevType() == OUTDEV_PRINTER) )
+ nStyle |= BUTTON_DRAW_MONO;
+
+ if ( nStyle & BUTTON_DRAW_DEFAULT )
+ {
+ if ( nStyle & BUTTON_DRAW_MONO )
+ pDev->SetLineColor( Color( COL_BLACK ) );
+ else
+ pDev->SetLineColor( aStyleSettings.GetDarkShadowColor() );
+
+ pDev->DrawLine( Point( rRect.Left()+3, rRect.Top() ),
+ Point( rRect.Right()-3, rRect.Top() ) );
+ pDev->DrawLine( Point( rRect.Left()+3, rRect.Bottom() ),
+ Point( rRect.Right()-3, rRect.Bottom() ) );
+ pDev->DrawLine( Point( rRect.Left(), rRect.Top()+3 ),
+ Point( rRect.Left(), rRect.Bottom()-3 ) );
+ pDev->DrawLine( Point( rRect.Right(), rRect.Top()+3 ),
+ Point( rRect.Right(), rRect.Bottom()-3 ) );
+ pDev->DrawPixel( Point( rRect.Left()+2, rRect.Top()+1 ) );
+ pDev->DrawPixel( Point( rRect.Left()+1, rRect.Top()+2 ) );
+ pDev->DrawPixel( Point( rRect.Right()-2, rRect.Top()+1 ) );
+ pDev->DrawPixel( Point( rRect.Right()-1, rRect.Top()+2 ) );
+ pDev->DrawPixel( Point( rRect.Left()+2, rRect.Bottom()-1 ) );
+ pDev->DrawPixel( Point( rRect.Left()+1, rRect.Bottom()-2 ) );
+ pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-1 ) );
+ pDev->DrawPixel( Point( rRect.Right()-1, rRect.Bottom()-2 ) );
+
+ if ( nStyle & BUTTON_DRAW_MONO )
+ pDev->SetLineColor( Color( COL_BLACK ) );
+ else
+ pDev->SetLineColor( aStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( rRect.Left()+3, rRect.Bottom()-1 ),
+ Point( rRect.Right()-3, rRect.Bottom()-1 ) );
+ pDev->DrawLine( Point( rRect.Right()-1, rRect.Top()+3 ),
+ Point( rRect.Right()-1, rRect.Bottom()-3 ) );
+ pDev->DrawPixel( Point( rRect.Right()-3, rRect.Bottom()-2 ) );
+ pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-2 ) );
+ pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-3 ) );
+ }
+
+ rRect.Left() += 2;
+ rRect.Top() += 2;
+ rRect.Right() -= 2;
+ rRect.Bottom() -= 2;
+
+ if ( nStyle & BUTTON_DRAW_MONO )
+ pDev->SetLineColor( Color( COL_BLACK ) );
+ else
+ pDev->SetLineColor( aStyleSettings.GetDarkShadowColor() );
+
+ pDev->DrawLine( Point( rRect.Left()+2, rRect.Top() ),
+ Point( rRect.Right()-2, rRect.Top() ) );
+ pDev->DrawLine( Point( rRect.Left()+2, rRect.Bottom() ),
+ Point( rRect.Right()-2, rRect.Bottom() ) );
+ pDev->DrawLine( Point( rRect.Left(), rRect.Top()+2 ),
+ Point( rRect.Left(), rRect.Bottom()-2 ) );
+ pDev->DrawLine( Point( rRect.Right(), rRect.Top()+2 ),
+ Point( rRect.Right(), rRect.Bottom()-2 ) );
+ pDev->DrawPixel( Point( rRect.Left()+1, rRect.Top()+1 ) );
+ pDev->DrawPixel( Point( rRect.Right()-1, rRect.Top()+1 ) );
+ pDev->DrawPixel( Point( rRect.Left()+1, rRect.Bottom()-1 ) );
+ pDev->DrawPixel( Point( rRect.Right()-1, rRect.Bottom()-1 ) );
+
+ pDev->SetLineColor();
+ if ( nStyle & BUTTON_DRAW_CHECKED )
+ pDev->SetFillColor( aStyleSettings.GetCheckedColor() );
+ else
+ pDev->SetFillColor( aStyleSettings.GetFaceColor() );
+ pDev->DrawRect( Rectangle( rRect.Left()+2, rRect.Top()+2, rRect.Right()-2, rRect.Bottom()-2 ) );
+
+ if ( !(nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED)) )
+ {
+ if ( nStyle & BUTTON_DRAW_MONO )
+ pDev->SetLineColor( Color( COL_BLACK ) );
+ else
+ pDev->SetLineColor( aStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( rRect.Left()+2, rRect.Bottom()-1 ),
+ Point( rRect.Right()-2, rRect.Bottom()-1 ) );
+ pDev->DrawLine( Point( rRect.Right()-1, rRect.Top()+2 ),
+ Point( rRect.Right()-1, rRect.Bottom()-2 ) );
+ pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-2 ) );
+ pDev->SetLineColor( aStyleSettings.GetLightColor() );
+ }
+ else
+ pDev->SetLineColor( aStyleSettings.GetShadowColor() );
+
+ if ( !(nStyle & BUTTON_DRAW_MONO) )
+ {
+ pDev->DrawLine( Point( rRect.Left()+2, rRect.Top()+1 ),
+ Point( rRect.Right()-2, rRect.Top()+1 ) );
+ pDev->DrawLine( Point( rRect.Left()+1, rRect.Top()+2 ),
+ Point( rRect.Left()+1, rRect.Bottom()-2 ) );
+ pDev->DrawPixel( Point( rRect.Top()+2, rRect.Right()+2 ) );
+ }
+
+ rRect.Left() += 2;
+ rRect.Top() += 2;
+ rRect.Right() -= 2;
+ rRect.Bottom() -= 2;
+
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ {
+ rRect.Left()++;
+ rRect.Top()++;
+ rRect.Right()++;
+ rRect.Bottom()++;
+ }
+
+ return;
+ }
+ }
+
+ DecorationView aDecoView( pDev );
+ if ( pDev->IsControlBackground() )
+ {
+ AllSettings aSettings = pDev->GetSettings();
+ AllSettings aOldSettings = aSettings;
+ StyleSettings aStyleSettings = aSettings.GetStyleSettings();
+ aStyleSettings.Set3DColors( pDev->GetControlBackground() );
+ aSettings.SetStyleSettings( aStyleSettings );
+ ((OutputDevice*)pDev)->SetSettings( aSettings );
+ rRect = aDecoView.DrawButton( rRect, nStyle );
+ ((OutputDevice*)pDev)->SetSettings( aOldSettings );
+ }
+ else
+ rRect = aDecoView.DrawButton( rRect, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL PushButton::ImplHitTestPushButton( Window* pDev,
+ const Point& rPos, USHORT nStyle )
+{
+ Point aTempPoint;
+ Rectangle aTestRect( aTempPoint, pDev->GetOutputSizePixel() );
+
+ if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) )
+ {
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+
+ USHORT nPushButtonSysStyle = rStyleSettings.GetPushButtonStyle() & STYLE_PUSHBUTTON_STYLE;
+ if ( nPushButtonSysStyle == STYLE_PUSHBUTTON_MAC )
+ {
+ aTestRect.Left() += 2;
+ aTestRect.Top() += 2;
+ aTestRect.Right() -= 2;
+ aTestRect.Bottom() -= 2;
+ }
+ }
+
+ return aTestRect.IsInside( rPos );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT PushButton::ImplGetTextStyle() const
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ USHORT nTextStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_MULTILINE | TEXT_DRAW_ENDELLIPSIS;
+
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
+ nTextStyle |= TEXT_DRAW_MONO;
+ if ( GetStyle() & WB_WORDBREAK )
+ nTextStyle |= TEXT_DRAW_WORDBREAK;
+ if ( GetStyle() & WB_NOLABEL )
+ nTextStyle &= ~TEXT_DRAW_MNEMONIC;
+ nTextStyle |= TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER;
+
+ return nTextStyle;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawBtnDropDownArrow( OutputDevice* pDev,
+ long nX, long nY,
+ Color& rColor, BOOL bBlack )
+{
+ Color aOldLineColor = pDev->GetLineColor();
+ Color aOldFillColor = pDev->GetFillColor();
+
+ pDev->SetLineColor();
+ if ( bBlack )
+ pDev->SetFillColor( Color( COL_BLACK ) );
+ else
+ pDev->SetFillColor( rColor );
+ pDev->DrawRect( Rectangle( nX+0, nY+0, nX+6, nY+0 ) );
+ pDev->DrawRect( Rectangle( nX+1, nY+1, nX+5, nY+1 ) );
+ pDev->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) );
+ pDev->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
+ if ( bBlack )
+ {
+ pDev->SetFillColor( rColor );
+ pDev->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) );
+ pDev->DrawRect( Rectangle( nX+3, nY+2, nX+3, nY+2 ) );
+ }
+ pDev->SetLineColor( aOldLineColor );
+ pDev->SetFillColor( aOldFillColor );
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, ULONG nDrawFlags,
+ const Rectangle& rRect, Rectangle& rTextRect )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aInRect = rRect;
+ Color aColor = rStyleSettings.GetButtonTextColor();
+ XubString aText = PushButton::GetText(); // PushButton:: wegen MoreButton
+ USHORT nTextStyle;
+ USHORT nStyle;
+
+ if ( nDrawFlags & WINDOW_DRAW_MONO )
+ aColor = Color( COL_BLACK );
+ else
+ {
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ }
+
+ rTextRect = aInRect;
+ if ( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON )
+ {
+ if ( aText.Len() )
+ {
+ // Symbol- und Textrect ermitteln
+ long nSymbolSize = pDev->GetTextHeight();
+ aInRect.Right() -= 5;
+ rTextRect.Left() += 2;
+ rTextRect.Right() = aInRect.Right()-nSymbolSize;
+ aInRect.Left() = rTextRect.Right();
+
+ nTextStyle = ImplGetTextStyle();
+ if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC )
+ {
+ if ( nTextStyle & TEXT_DRAW_MNEMONIC )
+ {
+ aText = GetNonMnemonicString( aText );
+ nTextStyle &= ~TEXT_DRAW_MNEMONIC;
+ }
+ }
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ }
+ nTextStyle &= ~(TEXT_DRAW_RIGHT | TEXT_DRAW_CENTER);
+ nTextStyle |= TEXT_DRAW_LEFT;
+ rTextRect = pDev->GetTextRect( rTextRect, aText, nTextStyle );
+ pDev->SetTextColor( aColor );
+ pDev->DrawText( rTextRect, aText, nTextStyle );
+ }
+ else
+ ImplCalcSymbolRect( aInRect );
+
+ nStyle = 0;
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nStyle |= SYMBOL_DRAW_DISABLE;
+ }
+
+ DecorationView aDecoView( pDev );
+ aDecoView.DrawSymbol( aInRect, SYMBOL_SPIN_DOWN, aColor, nStyle );
+ }
+ else
+ {
+ if ( aText.Len() )
+ {
+ nTextStyle = ImplGetTextStyle();
+ if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC )
+ {
+ if ( nTextStyle & TEXT_DRAW_MNEMONIC )
+ {
+ aText = GetNonMnemonicString( aText );
+ nTextStyle &= ~TEXT_DRAW_MNEMONIC;
+ }
+ }
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ }
+ rTextRect = pDev->GetTextRect( aInRect, aText, nTextStyle );
+ }
+
+ if ( IsSymbol() )
+ {
+ ImplCalcSymbolRect( aInRect );
+
+ nStyle = 0;
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nStyle |= SYMBOL_DRAW_DISABLE;
+ }
+
+ DecorationView aDecoView( pDev );
+ aDecoView.DrawSymbol( aInRect, meSymbol, aColor, nStyle );
+ }
+
+ if ( aText.Len() )
+ {
+ pDev->SetTextColor( aColor );
+ pDev->DrawText( rTextRect, aText, nTextStyle );
+ }
+
+ // Den Fall Text+Image erstmal ignoriert, TH ignoriert auch Text+Symbol
+ if ( IsImage() )
+ {
+ // Image zentrieren...
+ Size aImageSize( maImage.GetSizePixel() );
+ aImageSize.Width() = CalcZoom( aImageSize.Width() );
+ aImageSize.Height() = CalcZoom( aImageSize.Height() );
+ if ( mpBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
+ {
+ // Die Groesse richtet sich nach dem Bildschirm, soll auf
+ // dem Drucker genau so aussehen...
+ aImageSize = PixelToLogic( aImageSize, MAP_100TH_MM );
+ aImageSize = pDev->LogicToPixel( aImageSize, MAP_100TH_MM );
+ }
+
+ Point aImagePos( rRect.Left()+((aInRect.GetWidth()-aImageSize.Width())/2),
+ rRect.Top()+((aInRect.GetHeight()-aImageSize.Height())/2) );
+ nStyle = 0;
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nStyle |= IMAGE_DRAW_DISABLE;
+ }
+ if ( mpBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
+ {
+ // Fuer die BitmapEx ueberlegt sich KA noch, wie man die disablete
+ // Darstellung hinbekommt...
+ aImageSize = pDev->PixelToLogic( aImageSize );
+ mpBitmapEx->Draw( pDev, aImagePos, aImageSize /*, nStyle*/ );
+ }
+ else
+ {
+ if ( IsZoom() )
+ pDev->DrawImage( aImagePos, aImageSize, maImage, nStyle );
+ else
+ pDev->DrawImage( aImagePos, maImage, nStyle );
+ }
+ }
+
+ if ( mnDDStyle == PUSHBUTTON_DROPDOWN_TOOLBOX )
+ {
+ BOOL bBlack = FALSE;
+ Color aArrowColor( COL_BLACK );
+ if ( !(nDrawFlags & WINDOW_DRAW_MONO) )
+ {
+ if ( !IsEnabled() )
+ aArrowColor = rStyleSettings.GetShadowColor();
+ else
+ {
+ aArrowColor = Color( COL_LIGHTGREEN );
+ bBlack = TRUE;
+ }
+ }
+
+ ImplDrawBtnDropDownArrow( pDev, aInRect.Right()-6, aInRect.Top()+1,
+ aArrowColor, bBlack );
+ }
+ }
+
+ UserDrawEvent aUDEvt( this, aInRect, 0 );
+ UserDraw( aUDEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::UserDraw( const UserDrawEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::ImplDrawPushButton()
+{
+ HideFocus();
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ USHORT nButtonStyle = mnButtonState;
+ Point aPoint;
+ Size aOutSz( GetOutputSizePixel() );
+ Rectangle aRect( aPoint, aOutSz );
+ Rectangle aInRect = aRect;
+ Rectangle aTextRect;
+
+ // Wenn Button gedrueckt gezeichnet werden soll, dann Pressed dazuordern
+ if ( mbPressed )
+ nButtonStyle |= BUTTON_DRAW_PRESSED;
+
+ // PushButtonFrame ausgeben
+ ImplDrawPushButtonFrame( this, aInRect, nButtonStyle );
+
+ // PushButton-Inhalt ausgeben
+ ImplDrawPushButtonContent( this, 0, aInRect, aTextRect );
+
+ maFocusRect = aTextRect;
+ maFocusRect.Left()--;
+ maFocusRect.Top()--;
+ maFocusRect.Right()++;
+ maFocusRect.Bottom()++;
+ if ( HasFocus() )
+ ShowFocus( maFocusRect );
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::ImplSetDefButton( BOOL bSet )
+{
+ if ( bSet )
+ mnButtonState |= BUTTON_DRAW_DEFAULT;
+ else
+ mnButtonState &= ~BUTTON_DRAW_DEFAULT;
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL PushButton::ImplIsDefButton() const
+{
+ return (mnButtonState & BUTTON_DRAW_DEFAULT) != 0;
+}
+
+// -----------------------------------------------------------------------
+
+PushButton::PushButton( WindowType nType ) :
+ Button( nType )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+PushButton::PushButton( Window* pParent, WinBits nStyle ) :
+ Button( WINDOW_PUSHBUTTON )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+PushButton::PushButton( Window* pParent, const ResId& rResId ) :
+ Button( WINDOW_PUSHBUTTON )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_PUSHBUTTON );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+PushButton::~PushButton()
+{
+ delete mpBitmapEx;
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() &&
+ ImplHitTestPushButton( this, rMEvt.GetPosPixel(), mnButtonState ) )
+ {
+ USHORT nTrackFlags = 0;
+
+ if ( GetStyle() & WB_REPEAT )
+ nTrackFlags |= STARTTRACK_BUTTONREPEAT;
+
+ mnButtonState |= BUTTON_DRAW_PRESSED;
+ ImplDrawPushButton();
+ StartTracking( nTrackFlags );
+
+ if ( GetStyle() & WB_REPEAT )
+ Click();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
+ GrabFocus();
+
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawPushButton();
+
+ // Bei Abbruch kein Click-Handler rufen
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ if ( !(GetStyle() & WB_REPEAT) )
+ Click();
+ }
+ }
+ }
+ else
+ {
+ if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel(), mnButtonState ) )
+ {
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) )
+ Click();
+ }
+ else
+ {
+ mnButtonState |= BUTTON_DRAW_PRESSED;
+ ImplDrawPushButton();
+ }
+ }
+ else
+ {
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawPushButton();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::KeyInput( const KeyEvent& rKEvt )
+{
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ if ( !aKeyCode.GetModifier() &&
+ ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
+ {
+ if ( !(mnButtonState & BUTTON_DRAW_PRESSED) )
+ {
+ mnButtonState |= BUTTON_DRAW_PRESSED;
+ ImplDrawPushButton();
+ }
+
+ if ( GetStyle() & WB_REPEAT )
+ Click();
+ }
+ else if ( (mnButtonState & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawPushButton();
+ }
+ else
+ Button::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::KeyUp( const KeyEvent& rKEvt )
+{
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ if ( (mnButtonState & BUTTON_DRAW_PRESSED) &&
+ ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawPushButton();
+
+ if ( !(GetStyle() & WB_REPEAT) )
+ Click();
+ }
+ else
+ Button::KeyUp( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::Paint( const Rectangle& rRect )
+{
+ ImplDrawPushButton();
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Rectangle aRect( aPos, aSize );
+ Rectangle aTextRect;
+ Font aFont = GetDrawPixelFont( pDev );
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ if ( nFlags & WINDOW_DRAW_MONO )
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ else
+ pDev->SetTextColor( GetTextColor() );
+ pDev->SetTextFillColor();
+
+ DecorationView aDecoView( pDev );
+ USHORT nButtonStyle = 0;
+ if ( nFlags & WINDOW_DRAW_MONO )
+ nButtonStyle |= BUTTON_DRAW_MONO;
+ if ( IsChecked() )
+ nButtonStyle |= BUTTON_DRAW_CHECKED;
+ aRect = aDecoView.DrawButton( aRect, nButtonStyle );
+
+ ImplDrawPushButtonContent( pDev, nFlags, aRect, aTextRect );
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::GetFocus()
+{
+ ShowFocus( maFocusRect );
+ SetInputContext( InputContext( GetFont() ) );
+ Button::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::LoseFocus()
+{
+ EndSelection();
+ HideFocus();
+ Button::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::StateChanged( StateChangedType nType )
+{
+ Button::StateChanged( nType );
+
+ if ( (nType == STATE_CHANGE_ENABLE) ||
+ (nType == STATE_CHANGE_TEXT) ||
+ (nType == STATE_CHANGE_IMAGE) ||
+ (nType == STATE_CHANGE_DATA) ||
+ (nType == STATE_CHANGE_STATE) ||
+ (nType == STATE_CHANGE_UPDATEMODE) )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+
+ if ( nType == STATE_CHANGE_STATE )
+ Toggle();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
+
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) !=
+ (GetStyle() & PUSHBUTTON_VIEW_STYLE) )
+ Invalidate();
+ }
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Button::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::Toggle()
+{
+ maToggleHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::SetSymbol( SymbolType eSymbol )
+{
+ if ( meSymbol != eSymbol )
+ {
+ meSymbol = eSymbol;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::SetImage( const Image& rImage )
+{
+ delete mpBitmapEx;
+ mpBitmapEx = NULL;
+ if ( rImage != maImage )
+ {
+ maImage = rImage;
+ meSymbol = SYMBOL_IMAGE;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::SetBitmap( const BitmapEx& rBmp )
+{
+ SetImage( rBmp );
+ DBG_ASSERT( !mpBitmapEx, "BitmapEx nach SetImage?!" );
+ mpBitmapEx = new BitmapEx( rBmp );
+}
+
+// -----------------------------------------------------------------------
+
+BitmapEx PushButton::GetBitmap() const
+{
+ BitmapEx aBmp;
+ if ( mpBitmapEx )
+ aBmp = *mpBitmapEx;
+ return aBmp;
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::SetImageAlign( ImageAlign eAlign )
+{
+ if ( meImageAlign != eAlign )
+ {
+ meImageAlign = eAlign;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::SetDropDown( USHORT nStyle )
+{
+ if ( mnDDStyle != nStyle )
+ {
+ mnDDStyle = nStyle;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::SetState( TriState eState )
+{
+ if ( meState != eState )
+ {
+ meState = eState;
+ if ( meState == STATE_NOCHECK )
+ mnButtonState &= ~(BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW);
+ else if ( meState == STATE_CHECK )
+ {
+ mnButtonState &= ~BUTTON_DRAW_DONTKNOW;
+ mnButtonState |= BUTTON_DRAW_CHECKED;
+ }
+ else // STATE_DONTKNOW
+ {
+ mnButtonState &= ~BUTTON_DRAW_CHECKED;
+ mnButtonState |= BUTTON_DRAW_DONTKNOW;
+ }
+
+ StateChanged( STATE_CHANGE_STATE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::SetPressed( BOOL bPressed )
+{
+ if ( mbPressed != bPressed )
+ {
+ mbPressed = bPressed;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PushButton::EndSelection()
+{
+ EndTracking( ENDTRACK_CANCEL );
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ if ( !mbPressed )
+ ImplDrawPushButton();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size PushButton::CalcMinimumSize( long nMaxWidth ) const
+{
+ Size aSize;
+
+ if ( IsSymbol() )
+ aSize = Size( 12, 12 );
+ else if ( IsImage() )
+ aSize = maImage.GetSizePixel();
+ else if ( PushButton::GetText().Len() )
+ {
+ aSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
+ PushButton::GetText(), ImplGetTextStyle() ).GetSize();
+ }
+
+ return CalcWindowSize( aSize );
+}
+
+// =======================================================================
+
+void OKButton::ImplInit( Window* pParent, WinBits nStyle )
+{
+ PushButton::ImplInit( pParent, nStyle );
+
+ SetText( Button::GetStandardText( BUTTON_OK ) );
+ SetHelpText( Button::GetStandardHelpText( BUTTON_OK ) );
+}
+
+// -----------------------------------------------------------------------
+
+OKButton::OKButton( Window* pParent, WinBits nStyle ) :
+ PushButton( WINDOW_OKBUTTON )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+OKButton::OKButton( Window* pParent, const ResId& rResId ) :
+ PushButton( WINDOW_OKBUTTON )
+{
+ rResId.SetRT( RSC_OKBUTTON );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void OKButton::Click()
+{
+ // Ist kein Link gesetzt, dann schliesse Parent
+ if ( !GetClickHdl() )
+ {
+ Window* pParent = GetParent();
+ if ( pParent->IsSystemWindow() )
+ {
+ if ( pParent->IsDialog() )
+ {
+ // gegen rekursive Aufrufe schuetzen
+ if ( !((Dialog*)pParent)->IsInClose() )
+ {
+ if ( ((Dialog*)pParent)->IsInExecute() )
+ ((Dialog*)pParent)->EndDialog( TRUE );
+ else if ( pParent->GetStyle() & WB_CLOSEABLE )
+ ((Dialog*)pParent)->Close();
+ }
+ }
+ else
+ {
+ if ( pParent->GetStyle() & WB_CLOSEABLE )
+ ((SystemWindow*)pParent)->Close();
+ }
+ }
+ }
+ else
+ PushButton::Click();
+}
+
+// =======================================================================
+
+void CancelButton::ImplInit( Window* pParent, WinBits nStyle )
+{
+ PushButton::ImplInit( pParent, nStyle );
+
+ SetText( Button::GetStandardText( BUTTON_CANCEL ) );
+ SetHelpText( Button::GetStandardHelpText( BUTTON_CANCEL ) );
+}
+
+// -----------------------------------------------------------------------
+
+CancelButton::CancelButton( Window* pParent, WinBits nStyle ) :
+ PushButton( WINDOW_CANCELBUTTON )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+CancelButton::CancelButton( Window* pParent, const ResId& rResId ) :
+ PushButton( WINDOW_CANCELBUTTON )
+{
+ rResId.SetRT( RSC_CANCELBUTTON );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void CancelButton::Click()
+{
+ // Ist kein Link gesetzt, dann schliesse Parent
+ if ( !GetClickHdl() )
+ {
+ Window* pParent = GetParent();
+ if ( pParent->IsSystemWindow() )
+ {
+ if ( pParent->IsDialog() )
+ {
+ // gegen rekursive Aufrufe schuetzen
+ if ( !((Dialog*)pParent)->IsInClose() )
+ {
+ if ( ((Dialog*)pParent)->IsInExecute() )
+ ((Dialog*)pParent)->EndDialog( FALSE );
+ else if ( pParent->GetStyle() & WB_CLOSEABLE )
+ ((Dialog*)pParent)->Close();
+ }
+ }
+ else
+ {
+ if ( pParent->GetStyle() & WB_CLOSEABLE )
+ ((SystemWindow*)pParent)->Close();
+ }
+ }
+ }
+ else
+ PushButton::Click();
+}
+
+// =======================================================================
+
+void HelpButton::ImplInit( Window* pParent, WinBits nStyle )
+{
+ PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS );
+
+ SetText( Button::GetStandardText( BUTTON_HELP ) );
+ SetHelpText( Button::GetStandardHelpText( BUTTON_HELP ) );
+}
+
+// -----------------------------------------------------------------------
+
+HelpButton::HelpButton( Window* pParent, WinBits nStyle ) :
+ PushButton( WINDOW_HELPBUTTON )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+HelpButton::HelpButton( Window* pParent, const ResId& rResId ) :
+ PushButton( WINDOW_HELPBUTTON )
+{
+ rResId.SetRT( RSC_HELPBUTTON );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void HelpButton::Click()
+{
+ // Ist kein Link gesetzt, loese Hilfe aus
+ if ( !GetClickHdl() )
+ {
+ Window* pFocusWin = Application::GetFocusWindow();
+ if ( !pFocusWin )
+ pFocusWin = this;
+
+ HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HELPMODE_CONTEXT );
+ pFocusWin->RequestHelp( aEvt );
+ }
+ else
+ PushButton::Click();
+}
+
+// =======================================================================
+
+void RadioButton::ImplInitData()
+{
+ mnButtonState = 0;
+ mbChecked = FALSE;
+ mbSaveValue = FALSE;
+ mbRadioCheck = TRUE;
+ mbStateChanged = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
+ Button::ImplInit( pParent, nStyle, NULL );
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits RadioButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOGROUP) &&
+ (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_RADIOBUTTON)) )
+ nStyle |= WB_GROUP;
+ if ( !(nStyle & WB_NOTABSTOP) )
+ {
+ if ( IsChecked() )
+ nStyle |= WB_TABSTOP;
+ else
+ nStyle &= ~WB_TABSTOP;
+ }
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetRadioCheckFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetRadioCheckTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Window* pParent = GetParent();
+ if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::ImplDrawRadioButtonState()
+{
+ USHORT nStyle = 0;
+
+ // kein Image-RadioButton
+ if ( !maImage )
+ {
+ USHORT nStyle = mnButtonState;
+ if ( !IsEnabled() )
+ nStyle |= BUTTON_DRAW_DISABLED;
+ if ( mbChecked )
+ nStyle |= BUTTON_DRAW_CHECKED;
+ Image aImage = GetRadioImage( GetSettings(), nStyle );
+ if ( IsZoom() )
+ DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
+ else
+ DrawImage( maStateRect.TopLeft(), aImage );
+ }
+ else
+ {
+ HideFocus();
+
+ DecorationView aDecoView( this );
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aImageRect = maStateRect;
+ Size aImageSize = maImage.GetSizePixel();
+ BOOL bEnabled = IsEnabled();
+
+ aImageSize.Width() = CalcZoom( aImageSize.Width() );
+ aImageSize.Height() = CalcZoom( aImageSize.Height() );
+
+ // Border und Selektionsstatus ausgeben
+ nStyle = FRAME_DRAW_DOUBLEIN;
+ aImageRect = aDecoView.DrawFrame( aImageRect, nStyle );
+ if ( (mnButtonState & BUTTON_DRAW_PRESSED) || !bEnabled )
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ else
+ SetFillColor( rStyleSettings.GetFieldColor() );
+ SetLineColor();
+ DrawRect( aImageRect );
+
+ // Image ausgeben
+ nStyle = 0;
+ if ( !bEnabled )
+ nStyle |= IMAGE_DRAW_DISABLE;
+ Point aImagePos( aImageRect.TopLeft() );
+ aImagePos.X() += (aImageRect.GetWidth()-aImageSize.Width())/2;
+ aImagePos.Y() += (aImageRect.GetHeight()-aImageSize.Height())/2;
+ if ( IsZoom() )
+ DrawImage( aImagePos, aImageSize, maImage, nStyle );
+ else
+ DrawImage( aImagePos, maImage, nStyle );
+
+ aImageRect.Left()++;
+ aImageRect.Top()++;
+ aImageRect.Right()--;
+ aImageRect.Bottom()--;
+
+ maFocusRect = aImageRect;
+
+ if ( mbChecked )
+ {
+ SetLineColor( rStyleSettings.GetHighlightColor() );
+ SetFillColor();
+ if ( (aImageSize.Width() >= 20) || (aImageSize.Height() >= 20) )
+ {
+ aImageRect.Left()++;
+ aImageRect.Top()++;
+ aImageRect.Right()--;
+ aImageRect.Bottom()--;
+ }
+ DrawRect( aImageRect );
+ aImageRect.Left()++;
+ aImageRect.Top()++;
+ aImageRect.Right()--;
+ aImageRect.Bottom()--;
+ DrawRect( aImageRect );
+ }
+
+ if ( HasFocus() )
+ ShowFocus( maFocusRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
+ const Point& rPos, const Size& rSize,
+ const Size& rImageSize, long nImageSep,
+ Rectangle& rStateRect,
+ Rectangle& rMouseRect,
+ Rectangle& rFocusRect )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ WinBits nWinStyle = GetStyle();
+ XubString aText( GetText() );
+ Rectangle aRect( rPos, rSize );
+
+ // kein Image-RadioButton
+ if ( !maImage )
+ {
+ if ( aText.Len() )
+ {
+ USHORT nTextStyle = FixedText::ImplGetTextStyle( nWinStyle );
+ if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC )
+ {
+ if ( nTextStyle & TEXT_DRAW_MNEMONIC )
+ {
+ aText = GetNonMnemonicString( aText );
+ nTextStyle &= ~TEXT_DRAW_MNEMONIC;
+ }
+ }
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ }
+ if ( (nDrawFlags & WINDOW_DRAW_MONO) ||
+ (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ nTextStyle |= TEXT_DRAW_MONO;
+
+ aRect.Left() += rImageSize.Width()+nImageSep;
+ rMouseRect = pDev->GetTextRect( aRect, aText, nTextStyle );
+
+ pDev->DrawText( aRect, aText, nTextStyle );
+ rFocusRect = rMouseRect;
+ rFocusRect.Left()--;
+ rFocusRect.Right()++;
+
+ rMouseRect.Left() = rPos.X();
+ rStateRect.Left() = rPos.X();
+ rStateRect.Top() = rMouseRect.Top();
+ long nTextHeight = GetTextHeight();
+ if ( nTextHeight > rImageSize.Height() )
+ rStateRect.Top() += (nTextHeight-rImageSize.Height())/2;
+ rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
+ rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
+ if ( rStateRect.Bottom() > rMouseRect.Bottom() )
+ rMouseRect.Bottom() = rStateRect.Bottom();
+ }
+ else
+ {
+ if ( nWinStyle & WB_CENTER )
+ rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
+ else if ( nWinStyle & WB_RIGHT )
+ rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); //-1;
+ else
+ rStateRect.Left() = rPos.X(); //+1;
+ if ( nWinStyle & WB_VCENTER )
+ rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
+ else if ( nWinStyle & WB_BOTTOM )
+ rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); //-1;
+ else
+ rStateRect.Top() = rPos.Y(); //+1;
+ rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
+ rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
+ rMouseRect = rStateRect;
+ rFocusRect = Rectangle();
+/* und oben -1, da CalcSize() auch Focus-Rechteck nicht mit einrechnet,
+da im Writer ansonsten die Images noch weiter oben haengen
+ rFocusRect = rStateRect;
+ rFocusRect.Left()--;
+ rFocusRect.Top()--;
+ rFocusRect.Right()++;
+ rFocusRect.Bottom()++;
+*/
+ }
+ }
+ else
+ {
+ BOOL bTopImage = (nWinStyle & WB_TOP) != 0;
+ Size aImageSize = maImage.GetSizePixel();
+ Rectangle aImageRect( rPos, rSize );
+ long nTextHeight = pDev->GetTextHeight();
+ long nTextWidth = pDev->GetCtrlTextWidth( aText );
+
+ // Positionen und Groessen berechnen
+ if ( aText.Len() )
+ {
+ Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) );
+ if ( bTopImage )
+ {
+ aImageRect.Left() = (rSize.Width()-aTmpSize.Width())/2;
+ aImageRect.Top() = (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2;
+ }
+ else
+ aImageRect.Top() = (rSize.Height()-aTmpSize.Height())/2;
+
+ aImageRect.Right() = aImageRect.Left()+aTmpSize.Width();
+ aImageRect.Bottom() = aImageRect.Top()+aTmpSize.Height();
+ }
+
+ // Text ausgeben
+ if ( aText.Len() )
+ {
+ Point aTxtPos = rPos;
+ if ( bTopImage )
+ {
+ aTxtPos.X() += (rSize.Width()-nTextWidth)/2;
+ aTxtPos.Y() += aImageRect.Bottom()+6;
+ }
+ else
+ {
+ aTxtPos.X() += aImageRect.Right()+8;
+ aTxtPos.Y() += (rSize.Height()-nTextHeight)/2;
+ }
+ pDev->DrawCtrlText( aTxtPos, aText );
+ }
+
+ rMouseRect = aImageRect;
+ rStateRect = aImageRect;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::ImplDrawRadioButton()
+{
+ HideFocus();
+
+ Size aImageSize;
+ if ( !maImage )
+ aImageSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel();
+ else
+ aImageSize = maImage.GetSizePixel();
+ aImageSize.Width() = CalcZoom( aImageSize.Width() );
+ aImageSize.Height() = CalcZoom( aImageSize.Height() );
+
+ ImplDraw( this, 0, Point(), GetOutputSizePixel(),
+ aImageSize, IMPL_SEP_BUTTON_IMAGE, maStateRect, maMouseRect, maFocusRect );
+
+ if ( !maImage )
+ {
+ if ( HasFocus() && !maFocusRect.IsEmpty() )
+ ShowFocus( maFocusRect );
+ }
+ ImplDrawRadioButtonState();
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::ImplUncheckAllOther()
+{
+ mnStyle |= WB_TABSTOP;
+
+ // Gruppe mit RadioButtons durchgehen und die gecheckten Buttons
+ Window* pWindow;
+ WinBits nStyle;
+ if ( !(GetStyle() & WB_GROUP) )
+ {
+ pWindow = GetWindow( WINDOW_PREV );
+ while ( pWindow )
+ {
+ nStyle = pWindow->GetStyle();
+
+ if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
+ {
+ if ( ((RadioButton*)pWindow)->IsChecked() )
+ {
+ ImplDelData aDelData;
+ pWindow->ImplAddDel( &aDelData );
+ ((RadioButton*)pWindow)->SetState( FALSE );
+ if ( aDelData.IsDelete() )
+ return;
+ pWindow->ImplRemoveDel( &aDelData );
+ }
+ // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
+ // innerhalb der if-Abfrage
+ pWindow->mnStyle &= ~WB_TABSTOP;
+ }
+
+ if ( nStyle & WB_GROUP )
+ break;
+
+ pWindow = pWindow->GetWindow( WINDOW_PREV );
+ }
+ }
+
+ pWindow = GetWindow( WINDOW_NEXT );
+ while ( pWindow )
+ {
+ nStyle = pWindow->GetStyle();
+
+ if ( nStyle & WB_GROUP )
+ break;
+
+ if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
+ {
+ if ( ((RadioButton*)pWindow)->IsChecked() )
+ {
+ ImplDelData aDelData;
+ pWindow->ImplAddDel( &aDelData );
+ ((RadioButton*)pWindow)->SetState( FALSE );
+ if ( aDelData.IsDelete() )
+ return;
+ pWindow->ImplRemoveDel( &aDelData );
+ }
+ // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
+ // innerhalb der if-Abfrage
+ pWindow->mnStyle &= ~WB_TABSTOP;
+ }
+
+ pWindow = pWindow->GetWindow( WINDOW_NEXT );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::ImplCallClick( BOOL bGrabFocus, USHORT nFocusFlags )
+{
+ mbStateChanged = !mbChecked;
+ mbChecked = TRUE;
+ mnStyle |= WB_TABSTOP;
+ ImplDrawRadioButtonState();
+ ImplDelData aDelData;
+ ImplAddDel( &aDelData );
+ if ( mbRadioCheck )
+ ImplUncheckAllOther();
+ if ( aDelData.IsDelete() )
+ return;
+ if ( bGrabFocus )
+ ImplGrabFocus( nFocusFlags );
+ if ( aDelData.IsDelete() )
+ return;
+ if ( mbStateChanged )
+ Toggle();
+ if ( aDelData.IsDelete() )
+ return;
+ Click();
+ if ( aDelData.IsDelete() )
+ return;
+ ImplRemoveDel( &aDelData );
+ mbStateChanged = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+RadioButton::RadioButton( Window* pParent, WinBits nStyle ) :
+ Button( WINDOW_RADIOBUTTON )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+RadioButton::RadioButton( Window* pParent, const ResId& rResId ) :
+ Button( WINDOW_RADIOBUTTON )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_RADIOBUTTON );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::ImplLoadRes( const ResId& rResId )
+{
+ Button::ImplLoadRes( rResId );
+
+ //anderer Wert als Default ?
+ USHORT nChecked = ReadShortRes();
+ if ( nChecked )
+ SetState( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+RadioButton::~RadioButton()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
+ {
+ mnButtonState |= BUTTON_DRAW_PRESSED;
+ ImplDrawRadioButtonState();
+ StartTracking();
+ return;
+ }
+
+ Button::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
+ GrabFocus();
+
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+
+ // Bei Abbruch kein Click-Handler rufen
+ if ( !rTEvt.IsTrackingCanceled() )
+ ImplCallClick();
+ else
+ ImplDrawRadioButtonState();
+ }
+ }
+ else
+ {
+ if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
+ {
+ if ( !(mnButtonState & BUTTON_DRAW_PRESSED) )
+ {
+ mnButtonState |= BUTTON_DRAW_PRESSED;
+ ImplDrawRadioButtonState();
+ }
+ }
+ else
+ {
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawRadioButtonState();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::KeyInput( const KeyEvent& rKEvt )
+{
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
+ {
+ if ( !(mnButtonState & BUTTON_DRAW_PRESSED) )
+ {
+ mnButtonState |= BUTTON_DRAW_PRESSED;
+ ImplDrawRadioButtonState();
+ }
+ }
+ else if ( (mnButtonState & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawRadioButtonState();
+ }
+ else
+ Button::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::KeyUp( const KeyEvent& rKEvt )
+{
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ if ( (mnButtonState & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplCallClick();
+ }
+ else
+ Button::KeyUp( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::Paint( const Rectangle& rRect )
+{
+ ImplDrawRadioButton();
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ if ( !maImage )
+ {
+ MapMode aResMapMode( MAP_100TH_MM );
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
+ Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
+ Size aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode );
+ Font aFont = GetDrawPixelFont( pDev );
+ Rectangle aStateRect;
+ Rectangle aMouseRect;
+ Rectangle aFocusRect;
+
+ aImageSize.Width() = CalcZoom( aImageSize.Width() );
+ aImageSize.Height() = CalcZoom( aImageSize.Height() );
+ aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() );
+ aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() );
+ aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() );
+ aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() );
+
+ if ( !aBrd1Size.Width() )
+ aBrd1Size.Width() = 1;
+ if ( !aBrd1Size.Height() )
+ aBrd1Size.Height() = 1;
+ if ( !aBrd2Size.Width() )
+ aBrd2Size.Width() = 1;
+ if ( !aBrd2Size.Height() )
+ aBrd2Size.Height() = 1;
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ if ( nFlags & WINDOW_DRAW_MONO )
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ else
+ pDev->SetTextColor( GetTextColor() );
+ pDev->SetTextFillColor();
+
+ ImplDraw( pDev, nFlags, aPos, aSize,
+ aImageSize, GetDrawPixel( pDev, IMPL_SEP_BUTTON_IMAGE ),
+ aStateRect, aMouseRect, aFocusRect );
+
+ Point aCenterPos = aStateRect.Center();
+ long nRadX = aImageSize.Width()/2;
+ long nRadY = aImageSize.Height()/2;
+
+ pDev->SetLineColor();
+ pDev->SetFillColor( Color( COL_BLACK ) );
+ pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
+ nRadX -= aBrd1Size.Width();
+ nRadY -= aBrd1Size.Height();
+ pDev->SetFillColor( Color( COL_WHITE ) );
+ pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
+ if ( mbChecked )
+ {
+ nRadX -= aBrd1Size.Width();
+ nRadY -= aBrd1Size.Height();
+ if ( !nRadX )
+ nRadX = 1;
+ if ( !nRadY )
+ nRadY = 1;
+ pDev->SetFillColor( Color( COL_BLACK ) );
+ pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
+ }
+
+ pDev->Pop();
+ }
+ else
+ {
+ DBG_ERROR( "RadioButton::Draw() - not implemented for RadioButton with Image" );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::GetFocus()
+{
+ ShowFocus( maFocusRect );
+ SetInputContext( InputContext( GetFont() ) );
+ Button::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::LoseFocus()
+{
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawRadioButtonState();
+ }
+
+ HideFocus();
+ Button::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::StateChanged( StateChangedType nType )
+{
+ Button::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_STATE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ if ( HasPaintEvent() )
+ Invalidate( maStateRect );
+ else
+ ImplDrawRadioButtonState();
+ }
+ Toggle();
+ }
+ else if ( (nType == STATE_CHANGE_ENABLE) ||
+ (nType == STATE_CHANGE_TEXT) ||
+ (nType == STATE_CHANGE_IMAGE) ||
+ (nType == STATE_CHANGE_DATA) ||
+ (nType == STATE_CHANGE_UPDATEMODE) )
+ {
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
+
+ if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) !=
+ (GetStyle() & RADIOBUTTON_VIEW_STYLE) )
+ {
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Button::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::Toggle()
+{
+ maToggleHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::SetImage( const Image& rImage )
+{
+ if ( rImage != maImage )
+ {
+ maImage = rImage;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::SetState( BOOL bCheck )
+{
+ // TabStop-Flag richtig mitfuehren
+ if ( bCheck )
+ mnStyle |= WB_TABSTOP;
+ else
+ mnStyle &= ~WB_TABSTOP;
+
+ if ( mbChecked != bCheck )
+ {
+ mbChecked = bCheck;
+ StateChanged( STATE_CHANGE_STATE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void RadioButton::Check( BOOL bCheck )
+{
+ // TabStop-Flag richtig mitfuehren
+ if ( bCheck )
+ mnStyle |= WB_TABSTOP;
+ else
+ mnStyle &= ~WB_TABSTOP;
+
+ if ( mbChecked != bCheck )
+ {
+ mbChecked = bCheck;
+ ImplDelData aDelData;
+ ImplAddDel( &aDelData );
+ StateChanged( STATE_CHANGE_STATE );
+ if ( aDelData.IsDelete() )
+ return;
+ ImplRemoveDel( &aDelData );
+ if ( bCheck && mbRadioCheck )
+ ImplUncheckAllOther();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image RadioButton::GetRadioImage( const AllSettings& rSettings, USHORT nFlags )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
+ USHORT nStyle = rStyleSettings.GetRadioButtonStyle() & STYLE_RADIOBUTTON_STYLE;
+
+ if ( !pSVData->maCtrlData.mpRadioImgList ||
+ (pSVData->maCtrlData.mnRadioStyle != nStyle) ||
+ (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor().GetColor()) ||
+ (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor().GetColor()) ||
+ (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor().GetColor()) )
+ {
+ if ( pSVData->maCtrlData.mpRadioImgList )
+ delete pSVData->maCtrlData.mpRadioImgList;
+
+ pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor().GetColor();
+ pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor().GetColor();
+ pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor().GetColor();
+
+ long aTempAry1[(6*sizeof(Color))/sizeof(long)];
+ long aTempAry2[(6*sizeof(Color))/sizeof(long)];
+ Color* pColorAry1 = (Color*)aTempAry1;
+ Color* pColorAry2 = (Color*)aTempAry2;
+ pColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
+ pColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
+ pColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
+ pColorAry1[3] = Color( 0x80, 0x80, 0x80 );
+ pColorAry1[4] = Color( 0x00, 0x00, 0x00 );
+ pColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
+ pColorAry2[0] = rStyleSettings.GetFaceColor();
+ pColorAry2[1] = rStyleSettings.GetWindowColor();
+ pColorAry2[2] = rStyleSettings.GetLightColor();
+ pColorAry2[3] = rStyleSettings.GetShadowColor();
+ pColorAry2[4] = rStyleSettings.GetDarkShadowColor();
+ pColorAry2[5] = rStyleSettings.GetWindowTextColor();
+
+ Bitmap aBmp( ResId( SV_RESID_BITMAP_RADIO+nStyle, ImplGetResMgr() ) );
+ aBmp.Replace( pColorAry1, pColorAry2, 6, NULL );
+ pSVData->maCtrlData.mpRadioImgList = new ImageList( aBmp, Color( 0x00, 0x00, 0xFF ), 6 );
+ pSVData->maCtrlData.mnRadioStyle = nStyle;
+ }
+
+ USHORT nId;
+ if ( nFlags & BUTTON_DRAW_DISABLED )
+ {
+ if ( nFlags & BUTTON_DRAW_CHECKED )
+ nId = 6;
+ else
+ nId = 5;
+ }
+ else if ( nFlags & BUTTON_DRAW_PRESSED )
+ {
+ if ( nFlags & BUTTON_DRAW_CHECKED )
+ nId = 4;
+ else
+ nId = 3;
+ }
+ else
+ {
+ if ( nFlags & BUTTON_DRAW_CHECKED )
+ nId = 2;
+ else
+ nId = 1;
+ }
+ return pSVData->maCtrlData.mpRadioImgList->GetImage( nId );
+}
+
+// -----------------------------------------------------------------------
+
+Size RadioButton::CalcMinimumSize( long nMaxWidth ) const
+{
+ Size aSize;
+ if ( !maImage )
+ aSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel();
+ else
+ aSize = maImage.GetSizePixel();
+
+ XubString aText = GetText();
+ if ( aText.Len() )
+ {
+ Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
+ aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
+ aSize.Width() += IMPL_SEP_BUTTON_IMAGE;
+ aSize.Width() += aTextSize.Width();
+ if ( aSize.Height() < aTextSize.Height() )
+ aSize.Height() = aTextSize.Height();
+ }
+ else if ( !maImage )
+ {
+/* da ansonsten im Writer die Control zu weit oben haengen
+ aSize.Width() += 2;
+ aSize.Height() += 2;
+*/
+ }
+
+ return CalcWindowSize( aSize );
+}
+
+// =======================================================================
+
+void CheckBox::ImplInitData()
+{
+ mnButtonState = 0;
+ meState = STATE_NOCHECK;
+ meSaveValue = STATE_NOCHECK;
+ mbTriState = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
+ Button::ImplInit( pParent, nStyle, NULL );
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits CheckBox::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOTABSTOP) )
+ nStyle |= WB_TABSTOP;
+ if ( !(nStyle & WB_NOGROUP) &&
+ (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_CHECKBOX)) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetRadioCheckFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetRadioCheckTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Window* pParent = GetParent();
+ if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::ImplLoadRes( const ResId& rResId )
+{
+ Button::ImplLoadRes( rResId );
+
+ if ( rResId.GetRT() != RSC_TRISTATEBOX )
+ {
+ USHORT nChecked = ReadShortRes();
+ //anderer Wert als Default ?
+ if( nChecked )
+ Check( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::ImplDrawCheckBoxState()
+{
+ USHORT nStyle = mnButtonState;
+ if ( !IsEnabled() )
+ nStyle |= BUTTON_DRAW_DISABLED;
+ if ( meState == STATE_DONTKNOW )
+ nStyle |= BUTTON_DRAW_DONTKNOW;
+ else if ( meState == STATE_CHECK )
+ nStyle |= BUTTON_DRAW_CHECKED;
+ Image aImage = GetCheckImage( GetSettings(), nStyle );
+ if ( IsZoom() )
+ DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
+ else
+ DrawImage( maStateRect.TopLeft(), aImage );
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
+ const Point& rPos, const Size& rSize,
+ const Size& rImageSize, long nImageSep,
+ Rectangle& rStateRect,
+ Rectangle& rMouseRect,
+ Rectangle& rFocusRect )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ WinBits nWinStyle = GetStyle();
+ XubString aText( GetText() );
+ Rectangle aRect( rPos, rSize );
+
+ if ( aText.Len() )
+ {
+ USHORT nTextStyle = FixedText::ImplGetTextStyle( nWinStyle );
+ if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC )
+ {
+ if ( nTextStyle & TEXT_DRAW_MNEMONIC )
+ {
+ aText = GetNonMnemonicString( aText );
+ nTextStyle &= ~TEXT_DRAW_MNEMONIC;
+ }
+ }
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ }
+ if ( (nDrawFlags & WINDOW_DRAW_MONO) ||
+ (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ nTextStyle |= TEXT_DRAW_MONO;
+
+ aRect.Left() += rImageSize.Width()+nImageSep;
+ rMouseRect = pDev->GetTextRect( aRect, aText, nTextStyle );
+
+ pDev->DrawText( aRect, aText, nTextStyle );
+ rFocusRect = rMouseRect;
+ rFocusRect.Left()--;
+ rFocusRect.Right()++;
+
+ rMouseRect.Left() = rPos.X();
+ rStateRect.Left() = rPos.X();
+ rStateRect.Top() = rMouseRect.Top();
+ long nTextHeight = GetTextHeight();
+ if ( nTextHeight > rImageSize.Height() )
+ rStateRect.Top() += (nTextHeight-rImageSize.Height())/2;
+ rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
+ rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
+ if ( rStateRect.Bottom() > rMouseRect.Bottom() )
+ rMouseRect.Bottom() = rStateRect.Bottom();
+ }
+ else
+ {
+ if ( nWinStyle & WB_CENTER )
+ rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
+ else if ( nWinStyle & WB_RIGHT )
+ rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); //-1;
+ else
+ rStateRect.Left() = rPos.X(); //+1;
+ if ( nWinStyle & WB_VCENTER )
+ rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
+ else if ( nWinStyle & WB_BOTTOM )
+ rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); //-1;
+ else
+ rStateRect.Top() = rPos.Y(); //+1;
+ rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
+ rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
+ rMouseRect = rStateRect;
+ rFocusRect = Rectangle();
+/* und oben -1, da CalcSize() auch Focus-Rechteck nicht mit einrechnet,
+da im Writer ansonsten die Images noch weiter oben haengen
+ rFocusRect = rStateRect;
+ rFocusRect.Left()--;
+ rFocusRect.Top()--;
+ rFocusRect.Right()++;
+ rFocusRect.Bottom()++;
+*/
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::ImplDrawCheckBox()
+{
+ Size aImageSize = GetCheckImage( GetSettings(), 0 ).GetSizePixel();
+ aImageSize.Width() = CalcZoom( aImageSize.Width() );
+ aImageSize.Height() = CalcZoom( aImageSize.Height() );
+
+ HideFocus();
+ ImplDraw( this, 0, Point(), GetOutputSizePixel(),
+ aImageSize, IMPL_SEP_BUTTON_IMAGE, maStateRect, maMouseRect, maFocusRect );
+ if ( HasFocus() && !maFocusRect.IsEmpty() )
+ ShowFocus( maFocusRect );
+ ImplDrawCheckBoxState();
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::ImplCheck()
+{
+ TriState eNewState;
+ if ( meState == STATE_NOCHECK )
+ eNewState = STATE_CHECK;
+ else if ( !mbTriState )
+ eNewState = STATE_NOCHECK;
+ else if ( meState == STATE_CHECK )
+ eNewState = STATE_DONTKNOW;
+ else
+ eNewState = STATE_NOCHECK;
+ meState = eNewState;
+ ImplDrawCheckBoxState();
+ Toggle();
+ Click();
+}
+
+// -----------------------------------------------------------------------
+
+CheckBox::CheckBox( Window* pParent, WinBits nStyle ) :
+ Button( WINDOW_CHECKBOX )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+CheckBox::CheckBox( Window* pParent, const ResId& rResId ) :
+ Button( WINDOW_CHECKBOX )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_CHECKBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
+ {
+ mnButtonState |= BUTTON_DRAW_PRESSED;
+ ImplDrawCheckBoxState();
+ StartTracking();
+ return;
+ }
+
+ Button::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
+ GrabFocus();
+
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+
+ // Bei Abbruch kein Click-Handler rufen
+ if ( !rTEvt.IsTrackingCanceled() )
+ ImplCheck();
+ else
+ ImplDrawCheckBoxState();
+ }
+ }
+ else
+ {
+ if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
+ {
+ if ( !(mnButtonState & BUTTON_DRAW_PRESSED) )
+ {
+ mnButtonState |= BUTTON_DRAW_PRESSED;
+ ImplDrawCheckBoxState();
+ }
+ }
+ else
+ {
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawCheckBoxState();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::KeyInput( const KeyEvent& rKEvt )
+{
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
+ {
+ if ( !(mnButtonState & BUTTON_DRAW_PRESSED) )
+ {
+ mnButtonState |= BUTTON_DRAW_PRESSED;
+ ImplDrawCheckBoxState();
+ }
+ }
+ else if ( (mnButtonState & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawCheckBoxState();
+ }
+ else
+ Button::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::KeyUp( const KeyEvent& rKEvt )
+{
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ if ( (mnButtonState & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplCheck();
+ }
+ else
+ Button::KeyUp( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::Paint( const Rectangle& rRect )
+{
+ ImplDrawCheckBox();
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ MapMode aResMapMode( MAP_100TH_MM );
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
+ Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
+ Size aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode );
+ long nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width();
+ Font aFont = GetDrawPixelFont( pDev );
+ Rectangle aStateRect;
+ Rectangle aMouseRect;
+ Rectangle aFocusRect;
+
+ aImageSize.Width() = CalcZoom( aImageSize.Width() );
+ aImageSize.Height() = CalcZoom( aImageSize.Height() );
+ aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() );
+ aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() );
+ aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() );
+ aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() );
+
+ if ( !aBrd1Size.Width() )
+ aBrd1Size.Width() = 1;
+ if ( !aBrd1Size.Height() )
+ aBrd1Size.Height() = 1;
+ if ( !aBrd2Size.Width() )
+ aBrd2Size.Width() = 1;
+ if ( !aBrd2Size.Height() )
+ aBrd2Size.Height() = 1;
+ if ( !nCheckWidth )
+ nCheckWidth = 1;
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ if ( nFlags & WINDOW_DRAW_MONO )
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ else
+ pDev->SetTextColor( GetTextColor() );
+ pDev->SetTextFillColor();
+
+ ImplDraw( pDev, nFlags, aPos, aSize,
+ aImageSize, GetDrawPixel( pDev, IMPL_SEP_BUTTON_IMAGE ),
+ aStateRect, aMouseRect, aFocusRect );
+
+ pDev->SetLineColor();
+ pDev->SetFillColor( Color( COL_BLACK ) );
+ pDev->DrawRect( aStateRect );
+ aStateRect.Left() += aBrd1Size.Width();
+ aStateRect.Top() += aBrd1Size.Height();
+ aStateRect.Right() -= aBrd1Size.Width();
+ aStateRect.Bottom() -= aBrd1Size.Height();
+ if ( meState == STATE_DONTKNOW )
+ pDev->SetFillColor( Color( COL_LIGHTGRAY ) );
+ else
+ pDev->SetFillColor( Color( COL_WHITE ) );
+ pDev->DrawRect( aStateRect );
+
+ if ( meState == STATE_CHECK )
+ {
+ aStateRect.Left() += aBrd2Size.Width();
+ aStateRect.Top() += aBrd2Size.Height();
+ aStateRect.Right() -= aBrd2Size.Width();
+ aStateRect.Bottom() -= aBrd2Size.Height();
+ Point aPos11( aStateRect.TopLeft() );
+ Point aPos12( aStateRect.BottomRight() );
+ Point aPos21( aStateRect.TopRight() );
+ Point aPos22( aStateRect.BottomLeft() );
+ Point aTempPos11( aPos11 );
+ Point aTempPos12( aPos12 );
+ Point aTempPos21( aPos21 );
+ Point aTempPos22( aPos22 );
+ pDev->SetLineColor( Color( COL_BLACK ) );
+ long nDX = 0;
+ for ( long i = 0; i < nCheckWidth; i++ )
+ {
+ if ( !(i % 2) )
+ {
+ aTempPos11.X() = aPos11.X()+nDX;
+ aTempPos12.X() = aPos12.X()+nDX;
+ aTempPos21.X() = aPos21.X()+nDX;
+ aTempPos22.X() = aPos22.X()+nDX;
+ }
+ else
+ {
+ nDX++;
+ aTempPos11.X() = aPos11.X()-nDX;
+ aTempPos12.X() = aPos12.X()-nDX;
+ aTempPos21.X() = aPos21.X()-nDX;
+ aTempPos22.X() = aPos22.X()-nDX;
+ }
+ pDev->DrawLine( aTempPos11, aTempPos12 );
+ pDev->DrawLine( aTempPos21, aTempPos22 );
+ }
+ }
+
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::GetFocus()
+{
+ ShowFocus( maFocusRect );
+ SetInputContext( InputContext( GetFont() ) );
+ Button::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::LoseFocus()
+{
+ if ( mnButtonState & BUTTON_DRAW_PRESSED )
+ {
+ mnButtonState &= ~BUTTON_DRAW_PRESSED;
+ ImplDrawCheckBoxState();
+ }
+
+ HideFocus();
+ Button::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::StateChanged( StateChangedType nType )
+{
+ Button::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_STATE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ if ( HasPaintEvent() )
+ Invalidate( maStateRect );
+ else
+ ImplDrawCheckBoxState();
+ }
+ Toggle();
+ }
+ else if ( (nType == STATE_CHANGE_ENABLE) ||
+ (nType == STATE_CHANGE_TEXT) ||
+ (nType == STATE_CHANGE_IMAGE) ||
+ (nType == STATE_CHANGE_DATA) ||
+ (nType == STATE_CHANGE_UPDATEMODE) )
+ {
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
+
+ if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) !=
+ (GetStyle() & CHECKBOX_VIEW_STYLE) )
+ {
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Button::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::Toggle()
+{
+ maToggleHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::SetState( TriState eState )
+{
+ if ( !mbTriState && (eState == STATE_DONTKNOW) )
+ eState = STATE_NOCHECK;
+
+ if ( meState != eState )
+ {
+ meState = eState;
+ StateChanged( STATE_CHANGE_STATE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void CheckBox::EnableTriState( BOOL bTriState )
+{
+ if ( mbTriState != bTriState )
+ {
+ mbTriState = bTriState;
+
+ if ( !bTriState && (meState == STATE_DONTKNOW) )
+ SetState( STATE_NOCHECK );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image CheckBox::GetCheckImage( const AllSettings& rSettings, USHORT nFlags )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
+ USHORT nStyle = rStyleSettings.GetCheckBoxStyle() & STYLE_CHECKBOX_STYLE;
+
+ if ( !pSVData->maCtrlData.mpCheckImgList ||
+ (pSVData->maCtrlData.mnCheckStyle != nStyle) ||
+ (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor().GetColor()) ||
+ (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor().GetColor()) ||
+ (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor().GetColor()) )
+ {
+ if ( pSVData->maCtrlData.mpCheckImgList )
+ delete pSVData->maCtrlData.mpCheckImgList;
+
+ pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor().GetColor();
+ pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor().GetColor();
+ pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor().GetColor();
+
+ long aTempAry1[(6*sizeof(Color))/sizeof(long)];
+ long aTempAry2[(6*sizeof(Color))/sizeof(long)];
+ Color* pColorAry1 = (Color*)aTempAry1;
+ Color* pColorAry2 = (Color*)aTempAry2;
+ pColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
+ pColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
+ pColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
+ pColorAry1[3] = Color( 0x80, 0x80, 0x80 );
+ pColorAry1[4] = Color( 0x00, 0x00, 0x00 );
+ pColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
+ pColorAry2[0] = rStyleSettings.GetFaceColor();
+ pColorAry2[1] = rStyleSettings.GetWindowColor();
+ pColorAry2[2] = rStyleSettings.GetLightColor();
+ pColorAry2[3] = rStyleSettings.GetShadowColor();
+ pColorAry2[4] = rStyleSettings.GetDarkShadowColor();
+ pColorAry2[5] = rStyleSettings.GetWindowTextColor();
+
+ Bitmap aBmp( ResId( SV_RESID_BITMAP_CHECK+nStyle, ImplGetResMgr() ) );
+ aBmp.Replace( pColorAry1, pColorAry2, 6, NULL );
+ pSVData->maCtrlData.mpCheckImgList = new ImageList( aBmp, 9 );
+ pSVData->maCtrlData.mnCheckStyle = nStyle;
+ }
+
+ USHORT nId;
+ if ( nFlags & BUTTON_DRAW_DISABLED )
+ {
+ if ( nFlags & BUTTON_DRAW_DONTKNOW )
+ nId = 9;
+ else if ( nFlags & BUTTON_DRAW_CHECKED )
+ nId = 6;
+ else
+ nId = 5;
+ }
+ else if ( nFlags & BUTTON_DRAW_PRESSED )
+ {
+ if ( nFlags & BUTTON_DRAW_DONTKNOW )
+ nId = 8;
+ else if ( nFlags & BUTTON_DRAW_CHECKED )
+ nId = 4;
+ else
+ nId = 3;
+ }
+ else
+ {
+ if ( nFlags & BUTTON_DRAW_DONTKNOW )
+ nId = 7;
+ else if ( nFlags & BUTTON_DRAW_CHECKED )
+ nId = 2;
+ else
+ nId = 1;
+ }
+ return pSVData->maCtrlData.mpCheckImgList->GetImage( nId );
+}
+
+// -----------------------------------------------------------------------
+
+Size CheckBox::CalcMinimumSize( long nMaxWidth ) const
+{
+ Size aSize = GetCheckImage( GetSettings(), 0 ).GetSizePixel();
+
+ XubString aText = GetText();
+ if ( aText.Len() )
+ {
+ Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
+ aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
+ aSize.Width() += IMPL_SEP_BUTTON_IMAGE;
+ aSize.Width() += aTextSize.Width();
+ if ( aSize.Height() < aTextSize.Height() )
+ aSize.Height() = aTextSize.Height();
+ }
+ else
+ {
+/* da ansonsten im Writer die Control zu weit oben haengen
+ aSize.Width() += 2;
+ aSize.Height() += 2;
+*/
+ }
+
+ return CalcWindowSize( aSize );
+}
+
+// =======================================================================
+
+ImageButton::ImageButton( WindowType nType ) :
+ PushButton( nType )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ImageButton::ImageButton( Window* pParent, WinBits nStyle ) :
+ PushButton( pParent, nStyle )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ImageButton::ImageButton( Window* pParent, const ResId& rResId ) :
+ PushButton( pParent, rResId.SetRT( RSC_IMAGEBUTTON ) )
+{
+ USHORT nObjMask = ReadShortRes();
+
+ if ( RSC_IMAGEBUTTON_IMAGE & nObjMask )
+ {
+ SetImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes() ) ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+
+ if ( RSC_IMAGEBUTTON_SYMBOL & nObjMask )
+ SetSymbol( (SymbolType)ReadShortRes() );
+
+ if ( RSC_IMAGEBUTTON_STATE & nObjMask )
+ SetState( (TriState)ReadShortRes() );
+}
+
+// -----------------------------------------------------------------------
+
+ImageButton::~ImageButton()
+{
+}
+
+// =======================================================================
+
+ImageRadioButton::ImageRadioButton( Window* pParent, WinBits nStyle ) :
+ RadioButton( pParent, nStyle )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ImageRadioButton::ImageRadioButton( Window* pParent, const ResId& rResId ) :
+ RadioButton( pParent, rResId.SetRT( RSC_IMAGERADIOBUTTON ) )
+{
+ USHORT nObjMask = ReadShortRes();
+
+ if ( RSC_IMAGERADIOBUTTON_IMAGE & nObjMask )
+ {
+ SetImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes() ) ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ImageRadioButton::~ImageRadioButton()
+{
+}
+
+// =======================================================================
+
+TriStateBox::TriStateBox( Window* pParent, WinBits nStyle ) :
+ CheckBox( pParent, nStyle )
+{
+ EnableTriState( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+TriStateBox::TriStateBox( Window* pParent, const ResId& rResId ) :
+ CheckBox( pParent, rResId.SetRT( RSC_TRISTATEBOX ) )
+{
+ EnableTriState( TRUE );
+
+ USHORT nTriState = ReadShortRes();
+ USHORT bDisableTriState = ReadShortRes();
+ //anderer Wert als Default ?
+ if ( (TriState)nTriState != STATE_NOCHECK )
+ SetState( (TriState)nTriState );
+ if ( bDisableTriState )
+ EnableTriState( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+TriStateBox::~TriStateBox()
+{
+}
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
new file mode 100644
index 000000000000..1d5ab2dd8eab
--- /dev/null
+++ b/vcl/source/control/combobox.cxx
@@ -0,0 +1,1242 @@
+/*************************************************************************
+ *
+ * $RCSfile: combobox.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_COMBOBOX_CXX
+
+#ifndef _TOOLS_TABLE_HXX
+#include <tools/table.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_ILSTBOX_HXX
+#include <ilstbox.hxx>
+#endif
+#ifndef _SV_LSTBOX_H
+#include <lstbox.h>
+#endif
+#ifndef _SV_BUTTON_HXX
+#include <button.hxx>
+#endif
+#ifndef _SV_SUBEDIT_HXX
+#include <subedit.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_COMBOBOX_HXX
+#include <combobox.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+inline ULONG ImplCreateKey( USHORT nPos )
+{
+ // Key = Pos+1, wegen Pos 0
+ return nPos+1;
+}
+
+// -----------------------------------------------------------------------
+
+static void lcl_GetSelectedEntries( Table& rSelectedPos, const XubString& rText, xub_Unicode cTokenSep, const ImplEntryList* pEntryList )
+{
+ for( xub_StrLen n = rText.GetTokenCount( cTokenSep ); n; )
+ {
+ XubString aToken = rText.GetToken( --n, cTokenSep );
+ aToken.EraseLeadingAndTrailingChars( ' ' );
+ USHORT nPos = pEntryList->FindEntry( aToken );
+ if ( nPos != LISTBOX_ENTRY_NOTFOUND )
+ rSelectedPos.Insert( ImplCreateKey( nPos ), (void*)1L );
+ }
+}
+
+// =======================================================================
+
+ComboBox::ComboBox( WindowType nType ) :
+ Edit( nType )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+ComboBox::ComboBox( Window* pParent, WinBits nStyle ) :
+ Edit( WINDOW_COMBOBOX )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+ComboBox::ComboBox( Window* pParent, const ResId& rResId ) :
+ Edit( WINDOW_COMBOBOX )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_COMBOBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+ComboBox::~ComboBox()
+{
+ SetSubEdit( NULL );
+ delete mpSubEdit;
+
+ delete mpImplLB;
+ mpImplLB = NULL;
+
+ delete mpFloatWin;
+ delete mpBtn;
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::ImplInitData()
+{
+ mpSubEdit = NULL;
+ mpBtn = NULL;
+ mpImplLB = NULL;
+ mpFloatWin = NULL;
+
+ mnDDHeight = 0;
+ mbDDAutoSize = TRUE;
+ mbSyntheticModify = FALSE;
+ mbMatchCase = FALSE;
+ mcMultiSep = ';';
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::ImplCalcEditHeight()
+{
+ long nLeft, nTop, nRight, nBottom;
+ GetBorder( nLeft, nTop, nRight, nBottom );
+ mnDDHeight = (USHORT)(mpSubEdit->GetTextHeight() + nTop + nBottom + 4);
+ if ( !IsDropDownBox() )
+ mnDDHeight += 4;
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::ImplInit( Window* pParent, WinBits nStyle )
+{
+ ImplInitStyle( nStyle );
+
+ BOOL bNoBorder = ( nStyle & WB_NOBORDER ) ? TRUE : FALSE;
+ if ( !(nStyle & WB_DROPDOWN) )
+ {
+ nStyle &= ~WB_BORDER;
+ nStyle |= WB_NOBORDER;
+ }
+ else
+ {
+ if ( !bNoBorder )
+ nStyle |= WB_BORDER;
+ }
+
+ Edit::ImplInit( pParent, nStyle );
+ SetBackground();
+
+ // DropDown ?
+ WinBits nEditStyle = 0;
+ WinBits nListStyle = nStyle;
+ if( nStyle & WB_DROPDOWN )
+ {
+ mpFloatWin = new ImplListBoxFloatingWindow( this );
+ mpFloatWin->SetAutoWidth( TRUE );
+ mpFloatWin->SetPopupModeEndHdl( LINK( this, ComboBox, ImplPopupModeEndHdl ) );
+
+ mpBtn = new ImplBtn( this, WB_NOLIGHTBORDER | WB_RECTSTYLE );
+ ImplInitDropDownButton( mpBtn );
+ mpBtn->SetMBDownHdl( LINK( this, ComboBox, ImplClickBtnHdl ) );
+ mpBtn->Show();
+
+ nEditStyle |= WB_NOBORDER;
+ nListStyle &= ~WB_BORDER;
+ nListStyle |= WB_NOBORDER;
+ }
+ else
+ {
+ if ( !bNoBorder )
+ {
+ nEditStyle |= WB_BORDER;
+ nListStyle &= ~WB_NOBORDER;
+ nListStyle |= WB_BORDER;
+ }
+ }
+
+ mpSubEdit = new Edit( this, nEditStyle );
+ SetSubEdit( mpSubEdit );
+ mpSubEdit->SetPosPixel( Point() );
+ EnableAutocomplete( TRUE );
+ mpSubEdit->Show();
+
+ Window* pLBParent = this;
+ if ( mpFloatWin )
+ pLBParent = mpFloatWin;
+ mpImplLB = new ImplListBox( pLBParent, nListStyle|WB_SIMPLEMODE );
+ mpImplLB->SetPosPixel( Point() );
+ mpImplLB->SetSelectHdl( LINK( this, ComboBox, ImplSelectHdl ) );
+ mpImplLB->SetCancelHdl( LINK( this, ComboBox, ImplCancelHdl ) );
+ mpImplLB->SetDoubleClickHdl( LINK( this, ComboBox, ImplDoubleClickHdl ) );
+ mpImplLB->SetUserDrawHdl( LINK( this, ComboBox, ImplUserDrawHdl ) );
+ mpImplLB->SetSelectionChangedHdl( LINK( this, ComboBox, ImplSelectionChangedHdl ) );
+ mpImplLB->Show();
+
+ if ( mpFloatWin )
+ mpFloatWin->SetImplListBox( mpImplLB );
+// else
+// mpImplLB->GetMainWindow()->AllowGrabFocus( TRUE );
+
+ ImplCalcEditHeight();
+
+ SetCompoundControl( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits ComboBox::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOTABSTOP) )
+ nStyle |= WB_TABSTOP;
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::ImplLoadRes( const ResId& rResId )
+{
+ Edit::ImplLoadRes( rResId );
+
+ USHORT nNumber = ReadShortRes();
+
+ if( nNumber )
+ {
+ for( USHORT i = 0; i < nNumber; i++ )
+ {
+ InsertEntry( ReadStringRes(), LISTBOX_APPEND );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::EnableAutocomplete( BOOL bEnable, BOOL bMatchCase )
+{
+ mbMatchCase = bMatchCase;
+
+ if ( bEnable )
+ mpSubEdit->SetAutocompleteHdl( LINK( this, ComboBox, ImplAutocompleteHdl ) );
+ else
+ mpSubEdit->SetAutocompleteHdl( Link() );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ComboBox::IsAutocompleteEnabled() const
+{
+ return mpSubEdit->GetAutocompleteHdl().IsSet();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ComboBox, ImplClickBtnHdl, void*, EMPTYARG )
+{
+ mpSubEdit->GrabFocus();
+ if ( !mpImplLB->GetEntryList()->GetMRUCount() )
+ ImplUpdateFloatSelection();
+ else
+ mpImplLB->SelectEntry( 0 , TRUE );
+ mpBtn->SetPressed( TRUE );
+ mpFloatWin->StartFloat( TRUE );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ComboBox, ImplPopupModeEndHdl, void*, p )
+{
+ mpBtn->SetPressed( FALSE );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ComboBox, ImplAutocompleteHdl, Edit*, pEdit )
+{
+ Selection aSel = pEdit->GetSelection();
+ AutocompleteAction eAction = pEdit->GetAutocompleteAction();
+
+ // Wenn keine Selection vorhanden ist, wird bei Tab/Shift+Tab auch
+ // keine AutoCompletion durchgefuehrt, da man ansonsten nicht in
+ // das naechste Feld kommt und der Text wieder mit etwas AutoExpandiert
+ // wird, was man nicht haben moechte.
+ if ( aSel.Len() ||
+ ((eAction != AUTOCOMPLETE_TABFORWARD) && (eAction != AUTOCOMPLETE_TABBACKWARD)) )
+ {
+ XubString aFullText = pEdit->GetText();
+ XubString aStartText = aFullText.Copy( 0, (xub_StrLen)aSel.Max() );
+ USHORT nStart = mpImplLB->GetCurrentPos();
+
+ if ( nStart == LISTBOX_ENTRY_NOTFOUND )
+ nStart = 0;
+
+ BOOL bForward = TRUE;
+ if ( eAction == AUTOCOMPLETE_TABFORWARD )
+ nStart++;
+ else if ( eAction == AUTOCOMPLETE_TABBACKWARD )
+ {
+ bForward = FALSE;
+ nStart = nStart ? (nStart--) : mpImplLB->GetEntryList()->GetEntryCount()-1;
+ }
+ MatchMode eMatchMode = mbMatchCase ? MATCH_CASE : MATCH_BEST;
+ USHORT nPos = mpImplLB->GetEntryList()->FindEntry( aStartText, eMatchMode, aStartText.Len(), nStart, bForward );
+ if ( nPos == LISTBOX_ENTRY_NOTFOUND )
+ nPos = mpImplLB->GetEntryList()->FindEntry( aStartText, eMatchMode, aStartText.Len(), bForward ? 0 : (mpImplLB->GetEntryList()->GetEntryCount()-1), bForward );
+
+ if ( nPos != LISTBOX_ENTRY_NOTFOUND )
+ {
+ XubString aText = mpImplLB->GetEntryList()->GetEntryText( nPos );
+ Selection aSel( aText.Len(), aStartText.Len() );
+ pEdit->SetText( aText, aSel );
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ComboBox, ImplSelectHdl, void*, EMPTYARG )
+{
+ BOOL bPopup = IsInDropDown();
+ if ( bPopup && !mpImplLB->IsTravelSelect() &&
+ ( !IsMultiSelectionEnabled() || !mpImplLB->GetSelectModifier() ) )
+ {
+ mpFloatWin->EndPopupMode();
+ GrabFocus();
+ }
+
+ if ( mpImplLB->IsSelectionChanged() || bPopup )
+ {
+ XubString aText;
+ if ( IsMultiSelectionEnabled() )
+ {
+ aText = mpSubEdit->GetText();
+
+ // Alle Eintraege entfernen, zu denen es einen Entry gibt, der aber nicht selektiert ist.
+ xub_StrLen nIndex = 0;
+ while ( nIndex != STRING_NOTFOUND )
+ {
+ xub_StrLen nPrevIndex = nIndex;
+ XubString aToken = aText.GetToken( 0, mcMultiSep, nIndex );
+ xub_StrLen nTokenLen = aToken.Len();
+ aToken.EraseLeadingAndTrailingChars( ' ' );
+ USHORT nP = mpImplLB->GetEntryList()->FindEntry( aToken );
+ if ( (nP != LISTBOX_ENTRY_NOTFOUND) && (!mpImplLB->GetEntryList()->IsEntryPosSelected( nP )) )
+ {
+ aText.Erase( nPrevIndex, nTokenLen );
+ nIndex -= nTokenLen;
+ if ( (nPrevIndex < aText.Len()) && (aText.GetChar( nPrevIndex ) == mcMultiSep) )
+ {
+ aText.Erase( nPrevIndex, 1 );
+ nIndex--;
+ }
+ }
+ aText.EraseLeadingAndTrailingChars( ' ' );
+ }
+
+ // Fehlende Eintraege anhaengen...
+ Table aSelInText;
+ lcl_GetSelectedEntries( aSelInText, aText, mcMultiSep, mpImplLB->GetEntryList() );
+ USHORT nSelectedEntries = mpImplLB->GetEntryList()->GetSelectEntryCount();
+ for ( USHORT n = 0; n < nSelectedEntries; n++ )
+ {
+ USHORT nP = mpImplLB->GetEntryList()->GetSelectEntryPos( n );
+ if ( !aSelInText.IsKeyValid( ImplCreateKey( nP ) ) )
+ {
+ if ( aText.Len() && (aText.GetChar( aText.Len()-1 ) != mcMultiSep) )
+ aText += mcMultiSep;
+ if ( aText.Len() )
+ aText += ' '; // etwas auflockern
+ aText += mpImplLB->GetEntryList()->GetEntryText( nP );
+ aText += mcMultiSep;
+ }
+ }
+ if ( aText.Len() && (aText.GetChar( aText.Len()-1 ) == mcMultiSep) )
+ aText.Erase( aText.Len()-1, 1 );
+ }
+ else
+ {
+ aText = mpImplLB->GetEntryList()->GetSelectEntry( 0 );
+ }
+
+ mpSubEdit->SetText( aText );
+
+ Selection aNewSelection( 0, aText.Len() );
+ if ( IsMultiSelectionEnabled() )
+ aNewSelection.Min() = aText.Len();
+ mpSubEdit->SetSelection( aNewSelection );
+
+ mpSubEdit->SetModifyFlag();
+ mbSyntheticModify = TRUE;
+ Modify();
+ mbSyntheticModify = FALSE;
+ Select();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ComboBox, ImplCancelHdl, void*, EMPTYARG )
+{
+ if( IsInDropDown() )
+ mpFloatWin->EndPopupMode();
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ComboBox, ImplSelectionChangedHdl, void*, n )
+{
+ if ( !mpImplLB->IsTrackingSelect() )
+ {
+ USHORT nChanged = (USHORT)(ULONG)n;
+ if ( !mpSubEdit->IsReadOnly() && mpImplLB->GetEntryList()->IsEntryPosSelected( nChanged ) )
+ mpSubEdit->SetText( mpImplLB->GetEntryList()->GetEntryText( nChanged ) );
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ComboBox, ImplDoubleClickHdl, void*, EMPTYARG )
+{
+ DoubleClick();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::EnableAutoSize( BOOL bAuto )
+{
+ mbDDAutoSize = bAuto;
+ if ( mpFloatWin )
+ {
+ if ( bAuto && !mpFloatWin->GetDropDownLineCount() )
+ mpFloatWin->SetDropDownLineCount( 5 );
+ else if ( !bAuto )
+ mpFloatWin->SetDropDownLineCount( 0 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetDropDownLineCount( USHORT nLines )
+{
+ if ( mpFloatWin )
+ mpFloatWin->SetDropDownLineCount( nLines );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ComboBox::GetDropDownLineCount() const
+{
+ USHORT nLines = 0;
+ if ( mpFloatWin )
+ nLines = mpFloatWin->GetDropDownLineCount();
+ return nLines;
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetPosSizePixel( long nX, long nY, long nWidth, long nHeight,
+ USHORT nFlags )
+{
+ if( IsDropDownBox() && ( nFlags & WINDOW_POSSIZE_SIZE ) )
+ {
+ Size aPrefSz = mpFloatWin->GetPrefSize();
+ if ( ( nFlags & WINDOW_POSSIZE_HEIGHT ) && ( nHeight > mnDDHeight ) )
+ aPrefSz.Height() = nHeight-mnDDHeight;
+ if ( nFlags & WINDOW_POSSIZE_WIDTH )
+ aPrefSz.Width() = nWidth;
+ mpFloatWin->SetPrefSize( aPrefSz );
+
+ if ( IsAutoSizeEnabled() )
+ nHeight = mnDDHeight;
+ }
+
+ Edit::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::Resize()
+{
+ Size aOutSz = GetOutputSizePixel();
+ if( IsDropDownBox() )
+ {
+ long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
+ nSBWidth = CalcZoom( nSBWidth );
+ mpSubEdit->SetSizePixel( Size( aOutSz.Width() - nSBWidth, aOutSz.Height() ) );
+ mpBtn->SetPosSizePixel( aOutSz.Width() - nSBWidth, 0, nSBWidth, aOutSz.Height() );
+ }
+ else
+ {
+ mpSubEdit->SetSizePixel( Size( aOutSz.Width(), mnDDHeight ) );
+ mpImplLB->SetPosSizePixel( 0, mnDDHeight, aOutSz.Width(), aOutSz.Height() - mnDDHeight );
+ if ( GetText().Len() )
+ ImplUpdateFloatSelection();
+ }
+
+ // FloatingWindow-Groesse auch im unsichtbare Zustand auf Stand halten,
+ // weil KEY_PGUP/DOWN ausgewertet wird...
+ if ( mpFloatWin )
+ mpFloatWin->SetSizePixel( mpFloatWin->CalcFloatSize() );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::StateChanged( StateChangedType nType )
+{
+ Edit::StateChanged( nType );
+
+ if ( ( nType == STATE_CHANGE_ENABLE ) || ( nType == STATE_CHANGE_READONLY ) )
+ {
+ mpImplLB->SetReadOnly( IsReadOnly() );
+ if ( mpBtn )
+ mpBtn->Enable( IsEnabled() && !IsReadOnly() );
+ }
+ else if ( nType == STATE_CHANGE_ENABLE )
+ {
+ mpSubEdit->Enable( IsEnabled() );
+ mpImplLB->Enable( IsEnabled() && !IsReadOnly() );
+ if ( mpBtn )
+ mpBtn->Enable( IsEnabled() && !IsReadOnly() );
+ Invalidate();
+ }
+ else if( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ mpImplLB->SetUpdateMode( IsUpdateMode() );
+ }
+ else if ( nType == STATE_CHANGE_ZOOM )
+ {
+ mpImplLB->SetZoom( GetZoom() );
+ mpSubEdit->SetZoom( GetZoom() );
+ ImplCalcEditHeight();
+ Resize();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ mpImplLB->SetControlFont( GetControlFont() );
+ mpSubEdit->SetControlFont( GetControlFont() );
+ ImplCalcEditHeight();
+ Resize();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ mpImplLB->SetControlForeground( GetControlForeground() );
+ mpSubEdit->SetControlForeground( GetControlForeground() );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ mpImplLB->SetControlBackground( GetControlBackground() );
+ mpSubEdit->SetControlBackground( GetControlBackground() );
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ mpImplLB->GetMainWindow()->EnableSort( ( GetStyle() & WB_SORT ) ? TRUE : FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ if ( mpBtn )
+ {
+ mpBtn->SetSettings( GetSettings() );
+ ImplInitDropDownButton( mpBtn );
+ }
+ Resize();
+ mpImplLB->Resize(); // Wird nicht durch ComboBox::Resize() gerufen, wenn sich die ImplLB nicht aendert.
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ComboBox::PreNotify( NotifyEvent& rNEvt )
+{
+ long nDone = 0;
+
+ if( ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN ) && ( rNEvt.GetWindow() == mpImplLB->GetMainWindow() ) )
+ {
+ mpSubEdit->GrabFocus();
+ }
+
+ return nDone ? nDone : Edit::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long ComboBox::Notify( NotifyEvent& rNEvt )
+{
+ long nDone = 0;
+ if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( rNEvt.GetWindow() == mpSubEdit )
+ && !IsReadOnly() )
+ {
+ KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
+ USHORT nKeyCode = aKeyEvt.GetKeyCode().GetCode();
+ switch( nKeyCode )
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ {
+ ImplUpdateFloatSelection();
+ if( ( nKeyCode == KEY_DOWN ) && mpFloatWin && !mpFloatWin->IsInPopupMode() && aKeyEvt.GetKeyCode().IsMod2() )
+ {
+ mpBtn->SetPressed( TRUE );
+ if ( mpImplLB->GetEntryList()->GetMRUCount() )
+ mpImplLB->SelectEntry( 0 , TRUE );
+ mpFloatWin->StartFloat( FALSE );
+ nDone = 1;
+ }
+ else if( ( nKeyCode == KEY_UP ) && mpFloatWin && mpFloatWin->IsInPopupMode() && aKeyEvt.GetKeyCode().IsMod2() )
+ {
+ mpFloatWin->EndPopupMode();
+ nDone = 1;
+ }
+ else
+ nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
+ }
+ break;
+
+ case KEY_RETURN:
+ {
+ if( ( rNEvt.GetWindow() == mpSubEdit ) && IsInDropDown() )
+ {
+ mpImplLB->ProcessKeyInput( aKeyEvt );
+ nDone = 1;
+ }
+ }
+ break;
+ }
+ }
+ else if ( (rNEvt.GetType() == EVENT_LOSEFOCUS) && mpFloatWin )
+ {
+ if( mpFloatWin->HasChildPathFocus() )
+ mpSubEdit->GrabFocus();
+ else if ( mpFloatWin->IsInPopupMode() && !HasChildPathFocus( TRUE ) )
+ mpFloatWin->EndPopupMode();
+ }
+ else if( (rNEvt.GetType() == EVENT_COMMAND) &&
+ (rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL) &&
+ (rNEvt.GetWindow() == mpSubEdit) )
+ {
+ nDone = mpImplLB->HandleWheelAsCursorTravel( *rNEvt.GetCommandEvent() );
+ }
+
+ return nDone ? nDone : Edit::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetText( const XubString& rStr )
+{
+ Edit::SetText( rStr );
+ ImplUpdateFloatSelection();
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetText( const XubString& rStr, const Selection& rNewSelection )
+{
+ Edit::SetText( rStr, rNewSelection );
+ ImplUpdateFloatSelection();
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::Modify()
+{
+ if ( !mbSyntheticModify )
+ ImplUpdateFloatSelection();
+
+ Edit::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::ImplUpdateFloatSelection()
+{
+ // Text in der ListBox in den sichtbaren Bereich bringen
+ mpImplLB->SetCallSelectionChangedHdl( FALSE );
+ if ( !IsMultiSelectionEnabled() )
+ {
+ XubString aSearchStr( mpSubEdit->GetText() );
+ USHORT nSelect = LISTBOX_ENTRY_NOTFOUND;
+ BOOL bSelect = TRUE;
+
+ if ( mpImplLB->GetCurrentPos() != LISTBOX_ENTRY_NOTFOUND )
+ {
+ XubString aCurrent = mpImplLB->GetEntryList()->GetEntryText( mpImplLB->GetCurrentPos() );
+ if ( aCurrent == aSearchStr )
+ nSelect = mpImplLB->GetCurrentPos();
+ }
+
+ if ( nSelect == LISTBOX_ENTRY_NOTFOUND )
+ nSelect = mpImplLB->GetEntryList()->FindEntry( aSearchStr, MATCH_CASE, STRING_LEN );
+ if ( nSelect == LISTBOX_ENTRY_NOTFOUND )
+ {
+ nSelect = mpImplLB->GetEntryList()->FindEntry( aSearchStr, MATCH_BEST, aSearchStr.Len() );
+ bSelect = FALSE;
+ }
+
+ if( nSelect != LISTBOX_ENTRY_NOTFOUND )
+ {
+ if ( !mpImplLB->IsVisible( nSelect ) )
+ mpImplLB->SetTopEntry( nSelect );
+ mpImplLB->SelectEntry( nSelect, bSelect );
+ }
+ else
+ {
+ nSelect = mpImplLB->GetEntryList()->GetSelectEntryPos( 0 );
+ if( nSelect != LISTBOX_ENTRY_NOTFOUND )
+ mpImplLB->SelectEntry( nSelect, FALSE );
+ mpImplLB->SetTopEntry( 0 );
+ mpImplLB->ResetCurrentPos();
+ }
+ }
+ else
+ {
+ Table aSelInText;
+ lcl_GetSelectedEntries( aSelInText, mpSubEdit->GetText(), mcMultiSep, mpImplLB->GetEntryList() );
+ for ( USHORT n = 0; n < mpImplLB->GetEntryList()->GetEntryCount(); n++ )
+ mpImplLB->SelectEntry( n, aSelInText.IsKeyValid( ImplCreateKey( n ) ) );
+ }
+ mpImplLB->SetCallSelectionChangedHdl( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ComboBox::InsertEntry( const XubString& rStr, USHORT nPos )
+{
+ USHORT nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr );
+ nRealPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ return nRealPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ComboBox::InsertEntry( const XubString& rStr, const Image& rImage, USHORT nPos )
+{
+ USHORT nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr, rImage );
+ nRealPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ return nRealPos;
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::RemoveEntry( const XubString& rStr )
+{
+ RemoveEntry( GetEntryPos( rStr ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::RemoveEntry( USHORT nPos )
+{
+ mpImplLB->RemoveEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::Clear()
+{
+ mpImplLB->Clear();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ComboBox::GetEntryPos( const XubString& rStr ) const
+{
+ USHORT nPos = mpImplLB->GetEntryList()->FindEntry( rStr, MATCH_CASE, STRING_LEN, mpImplLB->GetEntryList()->GetMRUCount() );
+ if ( nPos != LISTBOX_ENTRY_NOTFOUND )
+ nPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ComboBox::GetEntryPos( const void* pData ) const
+{
+ USHORT nPos = mpImplLB->GetEntryList()->FindEntry( pData );
+ if ( nPos != LISTBOX_ENTRY_NOTFOUND )
+ nPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+XubString ComboBox::GetEntry( USHORT nPos ) const
+{
+ return mpImplLB->GetEntryList()->GetEntryText( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ComboBox::GetEntryCount() const
+{
+ return mpImplLB->GetEntryList()->GetEntryCount() - mpImplLB->GetEntryList()->GetMRUCount();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ComboBox::IsTravelSelect() const
+{
+ return mpImplLB->IsTravelSelect();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ComboBox::IsInDropDown() const
+{
+ return mpFloatWin && mpFloatWin->IsInPopupMode();
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::EnableMultiSelection( BOOL bMulti )
+{
+ mpImplLB->EnableMultiSelection( bMulti );
+ mpImplLB->SetMultiSelectionSimpleMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ComboBox::IsMultiSelectionEnabled() const
+{
+ return mpImplLB->IsMultiSelectionEnabled();
+}
+
+// -----------------------------------------------------------------------
+
+long ComboBox::CalcWindowSizePixel( USHORT nLines ) const
+{
+ return mpImplLB->GetEntryHeight() * nLines;
+}
+
+// -----------------------------------------------------------------------
+
+Size ComboBox::CalcMinimumSize() const
+{
+ Size aSz;
+ if ( !IsDropDownBox() )
+ {
+ aSz = mpImplLB->CalcSize( mpImplLB->GetEntryList()->GetEntryCount() );
+ aSz.Height() += mnDDHeight;
+ }
+ else
+ {
+ aSz.Height() = mpImplLB->CalcSize( 1 ).Height();
+ aSz.Width() = mpImplLB->GetMaxEntryWidth();
+ aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
+ }
+
+ aSz = CalcWindowSize( aSz );
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+Size ComboBox::CalcAdjustedSize( const Size& rPrefSize ) const
+{
+ Size aSz = rPrefSize;
+ long nLeft, nTop, nRight, nBottom;
+ ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
+ aSz.Height() -= nTop+nBottom;
+ if ( !IsDropDownBox() )
+ {
+ long nEntryHeight = CalcSize( 1, 1 ).Height();
+ long nLines = aSz.Height() / nEntryHeight;
+ if ( nLines < 1 )
+ nLines = 1;
+ aSz.Height() = nLines * nEntryHeight;
+ aSz.Height() += mnDDHeight;
+ }
+ else
+ {
+ aSz.Height() = mnDDHeight;
+ }
+ aSz.Height() += nTop+nBottom;
+
+ aSz = CalcWindowSize( aSz );
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+Size ComboBox::CalcSize( USHORT nColumns, USHORT nLines ) const
+{
+ // ggf. werden ScrollBars eingeblendet
+ Size aMinSz = CalcMinimumSize();
+ Size aSz;
+
+ // Hoehe
+ if ( nLines )
+ {
+ if ( !IsDropDownBox() )
+ aSz.Height() = mpImplLB->CalcSize( nLines ).Height() + mnDDHeight;
+ else
+ aSz.Height() = mnDDHeight;
+ }
+ else
+ aSz.Height() = aMinSz.Height();
+
+ // Breite
+ if ( nColumns )
+ aSz.Width() = nColumns * GetTextWidth( UniString( 'X' ) );
+ else
+ aSz.Width() = aMinSz.Width();
+
+ if ( IsDropDownBox() )
+ aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
+
+ if ( !IsDropDownBox() )
+ {
+ if ( aSz.Width() < aMinSz.Width() )
+ aSz.Height() += GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( aSz.Height() < aMinSz.Height() )
+ aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
+ }
+
+ aSz = CalcWindowSize( aSz );
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::GetMaxVisColumnsAndLines( USHORT& rnCols, USHORT& rnLines ) const
+{
+ long nCharWidth = GetTextWidth( UniString( 'x' ) );
+ if ( !IsDropDownBox() )
+ {
+ Size aOutSz = mpImplLB->GetMainWindow()->GetOutputSizePixel();
+ rnCols = (USHORT)(aOutSz.Width()/nCharWidth);
+ rnLines = (USHORT)(aOutSz.Height()/mpImplLB->GetEntryHeight());
+ }
+ else
+ {
+ Size aOutSz = mpSubEdit->GetOutputSizePixel();
+ rnCols = (USHORT)(aOutSz.Width()/nCharWidth);
+ rnLines = 1;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
+{
+ mpImplLB->GetMainWindow()->ImplInitSettings( TRUE, TRUE, TRUE );
+
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Font aFont = mpImplLB->GetMainWindow()->GetDrawPixelFont( pDev );
+ OutDevType eOutDevType = pDev->GetOutDevType();
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ pDev->SetTextFillColor();
+
+ // Border/Background
+ pDev->SetLineColor();
+ pDev->SetFillColor();
+ BOOL bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
+ BOOL bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
+ if ( bBorder || bBackground )
+ {
+ Rectangle aRect( aPos, aSize );
+ // aRect.Top() += nEditHeight;
+ if ( bBorder )
+ {
+ DecorationView aDecoView( pDev );
+ aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
+ }
+ if ( bBackground )
+ {
+ pDev->SetFillColor( GetControlBackground() );
+ pDev->DrawRect( aRect );
+ }
+ }
+
+ // Inhalt
+ if ( IsDropDownBox() )
+ {
+ mpSubEdit->Draw( pDev, aPos, aSize, nFlags );
+ // DD-Button ?
+ }
+ else
+ {
+ long nOnePixel = GetDrawPixel( pDev, 1 );
+ long nTextHeight = pDev->GetTextHeight();
+ long nEditHeight = nTextHeight + 6*nOnePixel;
+
+ mpSubEdit->Draw( pDev, aPos, Size( aSize.Width(), nEditHeight ), nFlags );
+
+ if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
+ {
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ }
+ else
+ {
+ if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ pDev->SetTextColor( rStyleSettings.GetDisableColor() );
+ }
+ else
+ {
+ pDev->SetTextColor( GetTextColor() );
+ }
+ }
+
+ Rectangle aClip( aPos, aSize );
+ pDev->IntersectClipRegion( aClip );
+ USHORT nLines = (USHORT) ( (aSize.Height()-nEditHeight) / nTextHeight );
+ if ( !nLines )
+ nLines = 1;
+ USHORT nTEntry = IsReallyVisible() ? mpImplLB->GetTopEntry() : 0;
+ for ( USHORT n = 0; n < nLines; n++ )
+ pDev->DrawText( Point( aPos.X() + 3*nOnePixel, aPos.Y() + n*nTextHeight + nEditHeight + nOnePixel ), mpImplLB->GetEntryList()->GetEntryText( n+nTEntry ) );
+ }
+
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ComboBox, ImplUserDrawHdl, UserDrawEvent*, pEvent )
+{
+ UserDraw( *pEvent );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::UserDraw( const UserDrawEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetUserItemSize( const Size& rSz )
+{
+ mpImplLB->GetMainWindow()->SetUserItemSize( rSz );
+}
+
+// -----------------------------------------------------------------------
+
+const Size& ComboBox::GetUserItemSize() const
+{
+ return mpImplLB->GetMainWindow()->GetUserItemSize();
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::EnableUserDraw( BOOL bUserDraw )
+{
+ mpImplLB->GetMainWindow()->EnableUserDraw( bUserDraw );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ComboBox::IsUserDrawEnabled() const
+{
+ return mpImplLB->GetMainWindow()->IsUserDrawEnabled();
+}
+
+// -----------------------------------------------------------------------
+
+#if SUPD < 593
+void ComboBox::DrawEntry( const UserDrawEvent& rEvt, BOOL bDrawImage, BOOL bDrawText )
+{
+ DBG_ASSERT( rEvt.GetDevice() == mpImplLB->GetMainWindow(), "DrawEntry?!" );
+ mpImplLB->GetMainWindow()->DrawEntry( rEvt.GetItemId(), bDrawImage, bDrawText );
+}
+#endif
+
+void ComboBox::DrawEntry( const UserDrawEvent& rEvt, BOOL bDrawImage, BOOL bDrawText, BOOL bDrawTextAtImagePos )
+{
+ DBG_ASSERT( rEvt.GetDevice() == mpImplLB->GetMainWindow(), "DrawEntry?!" );
+ mpImplLB->GetMainWindow()->DrawEntry( rEvt.GetItemId(), bDrawImage, bDrawText, bDrawTextAtImagePos );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetSeparatorPos( USHORT n )
+{
+ mpImplLB->SetSeparatorPos( n );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetSeparatorPos()
+{
+ mpImplLB->SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ComboBox::GetSeparatorPos() const
+{
+ return mpImplLB->GetSeparatorPos();
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetMRUEntries( const XubString& rEntries, xub_Unicode cSep )
+{
+ mpImplLB->SetMRUEntries( rEntries, cSep );
+}
+
+// -----------------------------------------------------------------------
+
+XubString ComboBox::GetMRUEntries( xub_Unicode cSep ) const
+{
+ return mpImplLB->GetMRUEntries( cSep );
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetMaxMRUCount( USHORT n )
+{
+ mpImplLB->SetMaxMRUCount( n );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ComboBox::GetMaxMRUCount() const
+{
+ return mpImplLB->GetMaxMRUCount();
+}
+
+// -----------------------------------------------------------------------
+
+void ComboBox::SetEntryData( USHORT nPos, void* pNewData )
+{
+ mpImplLB->SetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount(), pNewData );
+}
+
+// -----------------------------------------------------------------------
+
+void* ComboBox::GetEntryData( USHORT nPos ) const
+{
+ return mpImplLB->GetEntryList()->GetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
new file mode 100644
index 000000000000..b325b75451bf
--- /dev/null
+++ b/vcl/source/control/ctrl.cxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * $RCSfile: ctrl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_CTRL_CXX
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_CTRL_HXX
+#include <ctrl.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+void Control::ImplInitData()
+{
+ mbHasFocus = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Control::Control( WindowType nType ) :
+ Window( nType )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+Control::Control( Window* pParent, WinBits nStyle ) :
+ Window( WINDOW_CONTROL )
+{
+ ImplInitData();
+ Window::ImplInit( pParent, nStyle, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+Control::Control( Window* pParent, const ResId& rResId ) :
+ Window( WINDOW_CONTROL )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_CONTROL );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle, NULL );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void Control::GetFocus()
+{
+ Window::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void Control::LoseFocus()
+{
+ Window::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+long Control::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ {
+ if ( !mbHasFocus )
+ {
+ mbHasFocus = TRUE;
+ maGetFocusHdl.Call( this );
+ }
+ }
+ else
+ {
+ if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ Window* pFocusWin = Application::GetFocusWindow();
+ if ( !pFocusWin || !ImplIsWindowOrChild( pFocusWin ) )
+ {
+ mbHasFocus = FALSE;
+ maLoseFocusHdl.Call( this );
+ }
+ }
+ }
+
+ return Window::Notify( rNEvt );
+}
diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx
new file mode 100644
index 000000000000..a93ef960b91b
--- /dev/null
+++ b/vcl/source/control/edit.cxx
@@ -0,0 +1,2200 @@
+/*************************************************************************
+ *
+ * $RCSfile: edit.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_EDIT_CXX
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_CURSOR_HXX
+#include <cursor.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_CLIP_HXX
+#include <clip.hxx>
+#endif
+#ifndef _SV_DRAG_HXX
+#include <drag.hxx>
+#endif
+#ifndef _SV_TRANSFER_HXX
+#include <transfer.hxx>
+#endif
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+#ifndef _SV_MENU_HXX
+#include <menu.hxx>
+#endif
+#ifndef _VCL_CMDEVT_H
+#include <cmdevt.h>
+#endif
+#ifndef _SV_SUBEDIT_HXX
+#include <subedit.hxx>
+#endif
+#ifndef _SV_EDIT_HXX
+#include <edit.hxx>
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_XBREAKITERATOR_HPP_
+#include <com/sun/star/text/XBreakIterator.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_CHARACTERITERATORMODE_HPP_
+#include <com/sun/star/text/CharacterIteratorMode.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_WORDTYPE_HPP_
+#include <com/sun/star/text/WordType.hpp>
+#endif
+
+#include <unohelp.hxx>
+
+
+#pragma hdrstop
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::rtl;
+
+// - Redo
+// - Bei Tracking-Cancel DefaultSelection wieder herstellen
+
+// =======================================================================
+
+static FncGetSpecialChars pImplFncGetSpecialChars = NULL;
+
+// =======================================================================
+
+#define EDIT_ALIGN_LEFT 1
+#define EDIT_ALIGN_CENTER 2
+#define EDIT_ALIGN_RIGHT 3
+
+#define EDIT_DEL_LEFT 1
+#define EDIT_DEL_RIGHT 2
+
+#define EDIT_DELMODE_SIMPLE 11
+#define EDIT_DELMODE_RESTOFWORD 12
+#define EDIT_DELMODE_RESTOFCONTENT 13
+
+// =======================================================================
+
+uno::Reference < text::XBreakIterator > ImplGetBreakIterator()
+{
+ static uno::Reference < text::XBreakIterator > xB;
+ if ( !xB.is() )
+ xB = vcl::unohelper::CreateBreakIterator();
+ return xB;
+}
+
+// =======================================================================
+
+struct DDInfo
+{
+ Cursor aCursor;
+ xub_StrLen nDropPos;
+ BOOL bStarterOfDD;
+ BOOL bDroppedInMe;
+ BOOL bVisCursor;
+
+ DDInfo()
+ {
+ aCursor.SetStyle( CURSOR_SHADOW );
+ nDropPos = 0;
+ bStarterOfDD = FALSE;
+ bDroppedInMe = FALSE;
+ bVisCursor = FALSE;
+ }
+};
+
+// =======================================================================
+
+struct Impl_IMEInfos
+{
+ USHORT* pAttribs;
+ xub_StrLen nPos;
+ xub_StrLen nLen;
+ BOOL bCursor;
+
+ Impl_IMEInfos( xub_StrLen nPos );
+ ~Impl_IMEInfos();
+
+ void CopyAttribs( const xub_StrLen* pA, xub_StrLen nL );
+ void DestroyAttribs();
+};
+
+// -----------------------------------------------------------------------
+
+Impl_IMEInfos::Impl_IMEInfos( xub_StrLen nP )
+{
+ nPos = nP;
+ nLen = 0;
+ bCursor = TRUE;
+ pAttribs = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+Impl_IMEInfos::~Impl_IMEInfos()
+{
+ delete pAttribs;
+}
+
+// -----------------------------------------------------------------------
+
+void Impl_IMEInfos::CopyAttribs( const xub_StrLen* pA, xub_StrLen nL )
+{
+ nLen = nL;
+ delete pAttribs;
+ pAttribs = new USHORT[ nL ];
+ memcpy( pAttribs, pA, nL*sizeof(USHORT) );
+}
+
+// -----------------------------------------------------------------------
+
+void Impl_IMEInfos::DestroyAttribs()
+{
+ delete pAttribs;
+ pAttribs = NULL;
+}
+
+// =======================================================================
+
+Edit::Edit( WindowType nType ) :
+ Control( nType )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+Edit::Edit( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_EDIT )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+Edit::Edit( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_EDIT )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_EDIT );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+Edit::~Edit()
+{
+ delete mpDDInfo;
+ Cursor* pCursor = GetCursor();
+ if ( pCursor )
+ {
+ SetCursor( NULL );
+ delete pCursor;
+ }
+
+ delete mpIMEInfos;
+
+ if ( mpUpdateDataTimer )
+ delete mpUpdateDataTimer;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplInitData()
+{
+ mpSubEdit = NULL;
+ mpUpdateDataTimer = NULL;
+ mnXOffset = 0;
+ mnAlign = EDIT_ALIGN_LEFT;
+ mnMaxTextLen = EDIT_NOLIMIT;
+ meAutocompleteAction = AUTOCOMPLETE_KEYINPUT;
+ mbModified = FALSE;
+ mbInternModified = FALSE;
+ mbReadOnly = FALSE;
+ mbInsertMode = TRUE;
+ mbClickedInSelection = FALSE;
+ mbActivePopup = FALSE;
+ mbIsSubEdit = FALSE;
+ mbInMBDown = FALSE;
+ mpDDInfo = NULL;
+ mpIMEInfos = NULL;
+ mcEchoChar = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( nStyle );
+ if ( !(nStyle & (WB_CENTER | WB_RIGHT)) )
+ nStyle |= WB_LEFT;
+
+ Control::ImplInit( pParent, nStyle, NULL );
+
+ mbReadOnly = (nStyle & WB_READONLY) != 0;
+
+ mnAlign = EDIT_ALIGN_LEFT;
+ if ( nStyle & WB_RIGHT )
+ mnAlign = EDIT_ALIGN_RIGHT;
+ else if ( nStyle & WB_CENTER )
+ mnAlign = EDIT_ALIGN_CENTER;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
+ SetFillColor( rStyleSettings.GetFieldColor() );
+ SetCursor( new Cursor );
+
+ SetPointer( Pointer( POINTER_TEXT ) );
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits Edit::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOTABSTOP) )
+ nStyle |= WB_TABSTOP;
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Edit::IsCharInput( const KeyEvent& rKeyEvent )
+{
+ // In the future we must use new Unicode functions for this
+ xub_Unicode cCharCode = rKeyEvent.GetCharCode();
+ return ((cCharCode >= 32) && (cCharCode != 127) &&
+ !rKeyEvent.GetKeyCode().IsControlMod());
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplModified()
+{
+ mbModified = TRUE;
+ Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplInitSettings( BOOL bFont, BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetFieldFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bFont || bForeground )
+ {
+ Color aTextColor = rStyleSettings.GetFieldTextColor();
+ if ( IsControlForeground() )
+ aTextColor = GetControlForeground();
+ SetTextColor( aTextColor );
+ }
+
+ if ( bBackground )
+ {
+ if( IsControlBackground() )
+ {
+ SetBackground( GetControlBackground() );
+ SetFillColor( GetControlBackground() );
+ }
+ else
+ {
+ SetBackground( rStyleSettings.GetFieldColor() );
+ SetFillColor( rStyleSettings.GetFieldColor() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString Edit::ImplGetText() const
+{
+ if ( mcEchoChar || (GetStyle() & WB_PASSWORD) )
+ {
+ XubString aText;
+ xub_Unicode cEchoChar;
+ if ( mcEchoChar )
+ cEchoChar = mcEchoChar;
+ else
+ cEchoChar = '*';
+ aText.Fill( maText.Len(), cEchoChar );
+ return aText;
+ }
+ else
+ return maText;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplRepaint( xub_StrLen nStart, xub_StrLen nEnd )
+{
+ if ( !IsReallyVisible() )
+ return;
+
+ XubString aText = ImplGetText();
+ if ( nStart >= aText.Len() )
+ return;
+
+ if ( nEnd > aText.Len() )
+ nEnd = aText.Len();
+
+ Cursor* pCursor = GetCursor();
+ BOOL bVisCursor = pCursor ? pCursor->IsVisible() : FALSE;
+ if ( pCursor )
+ pCursor->Hide();
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if ( IsEnabled() )
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ else
+ SetTextColor( rStyleSettings.GetDisableColor() );
+
+ SetTextFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() );
+
+ // In der Hoehe zentrieren
+ long nH = GetOutputSize().Height();
+ long nTH = GetTextHeight();
+ Point aPos( mnXOffset, (nH-nTH)/2 );
+
+ BOOL bDrawSelection = maSelection.Len() && ( HasFocus() || ( GetStyle() & WB_NOHIDESELECTION ) || mbActivePopup );
+
+ if ( !bDrawSelection && !mpIMEInfos )
+ {
+ aPos.X() = GetTextWidth( aText, 0, nStart ) + mnXOffset;
+ DrawText( aPos, aText, nStart, nEnd - nStart );
+ }
+ else
+ {
+ Selection aTmpSel( maSelection );
+ aTmpSel.Justify();
+
+ xub_StrLen nIndex = nStart;
+ while ( nIndex < nEnd )
+ {
+ xub_StrLen nTmpEnd = nEnd;
+ USHORT nAttr = 0;
+ if ( mpIMEInfos && mpIMEInfos->pAttribs )
+ {
+ xub_StrLen nIMEEnd = mpIMEInfos->nPos+mpIMEInfos->nLen;
+ if ( (nIndex < mpIMEInfos->nPos) && (nTmpEnd > mpIMEInfos->nPos) )
+ {
+ nTmpEnd = mpIMEInfos->nPos;
+ }
+ else if ( (nIndex >= mpIMEInfos->nPos) && (nIndex < nIMEEnd) )
+ {
+ // Attributweise ausgeben...
+ nTmpEnd = nIndex + 1;
+ if ( (nIndex >= mpIMEInfos->nPos) && (nIndex < (mpIMEInfos->nPos+mpIMEInfos->nLen)) )
+ {
+ nAttr = mpIMEInfos->pAttribs[nIndex-mpIMEInfos->nPos];
+ xub_StrLen nMax = mpIMEInfos->nPos+mpIMEInfos->nLen;
+ while ( ( nTmpEnd < nMax ) && ( mpIMEInfos->pAttribs[ nTmpEnd - mpIMEInfos->nPos ] == nAttr ) )
+ nTmpEnd++;
+ }
+ }
+ }
+ else if ( bDrawSelection )
+ {
+ if ( ( nIndex < aTmpSel.Min() ) && ( nTmpEnd > aTmpSel.Min() ) )
+ nTmpEnd = (xub_StrLen)aTmpSel.Min();
+ else if ( ( nIndex >= aTmpSel.Min() ) && ( nIndex < aTmpSel.Max() ) && ( nTmpEnd > aTmpSel.Max() ) )
+ nTmpEnd = (xub_StrLen)aTmpSel.Max();
+ }
+
+ aPos.X() = GetTextWidth( aText, 0, nIndex ) + mnXOffset;
+ ImplInitSettings( mpIMEInfos ? TRUE : FALSE, TRUE, FALSE );
+ BOOL bSelected = bDrawSelection && ((xub_StrLen)aTmpSel.Min() <= nIndex ) && ((xub_StrLen)aTmpSel.Max() > nIndex );
+ if ( bSelected || ( nAttr & EXTTEXTINPUT_ATTR_HIGHLIGHT) )
+ {
+ SetTextColor( rStyleSettings.GetHighlightTextColor() );
+ SetTextFillColor( rStyleSettings.GetHighlightColor() );
+ }
+ else
+ {
+ SetTextFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() );
+ }
+
+ if ( nAttr )
+ {
+ Font aFont = GetFont();
+ if ( nAttr & EXTTEXTINPUT_ATTR_UNDERLINE )
+ aFont.SetUnderline( UNDERLINE_SINGLE );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_BOLDUNDERLINE )
+ aFont.SetUnderline( UNDERLINE_BOLD );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE )
+ aFont.SetUnderline( UNDERLINE_DOTTED );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE )
+ aFont.SetUnderline( UNDERLINE_DOTTED );
+ else if ( nAttr & EXTTEXTINPUT_ATTR_GRAYWAVELINE )
+ {
+ aFont.SetUnderline( UNDERLINE_WAVE );
+ SetTextLineColor( Color( COL_LIGHTGRAY ) );
+ }
+ SetFont( aFont );
+
+ if ( nAttr & EXTTEXTINPUT_ATTR_REDTEXT )
+ SetTextColor( Color( COL_RED ) );
+ }
+ DrawText( aPos, aText, nIndex, nTmpEnd - nIndex );
+ nIndex = nTmpEnd;
+ }
+ }
+
+ if ( bVisCursor && ( !mpIMEInfos || mpIMEInfos->bCursor ) )
+ pCursor->Show();
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplDelete( const Selection& rSelection, BYTE nDirection, BYTE nMode )
+{
+ XubString aText = ImplGetText();
+
+ // loeschen moeglich?
+ if ( !rSelection.Len() &&
+ (((rSelection.Min() == 0) && (nDirection == EDIT_DEL_LEFT)) ||
+ ((rSelection.Max() == aText.Len()) && (nDirection == EDIT_DEL_RIGHT))) )
+ return;
+
+ long nOldWidth = GetTextWidth( aText );
+ Selection aSelection( rSelection );
+ aSelection.Justify();
+
+ if ( !aSelection.Len() )
+ {
+ uno::Reference < text::XBreakIterator > xBI = ImplGetBreakIterator();
+ if ( nDirection == EDIT_DEL_LEFT )
+ {
+ if ( nMode == EDIT_DELMODE_RESTOFWORD )
+ {
+ text::Boundary aBoundary = xBI->getWordBoundary( maText, aSelection.Min(), GetSettings().GetLocale(), text::WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
+ if ( aBoundary.startPos == aSelection.Min() )
+ aBoundary = xBI->previousWord( maText, aSelection.Min(), GetSettings().GetLocale(), text::WordType::ANYWORD_IGNOREWHITESPACES );
+ aSelection.Min() = aBoundary.startPos;
+ }
+ else if ( nMode == EDIT_DELMODE_RESTOFCONTENT )
+ {
+ aSelection.Min() = 0;
+ }
+ else
+ {
+ sal_Int32 nCount = 1;
+ aSelection.Min() = xBI->previousCharacters( maText, aSelection.Min(), GetSettings().GetLocale(), text::CharacterIteratorMode::SKIPCHARACTER, nCount, nCount );
+ }
+ }
+ else
+ {
+ if ( nMode == EDIT_DELMODE_RESTOFWORD )
+ {
+ text::Boundary aBoundary = xBI->nextWord( maText, aSelection.Max(), GetSettings().GetLocale(), text::WordType::ANYWORD_IGNOREWHITESPACES );
+ aSelection.Max() = aBoundary.startPos;
+ }
+ else if ( nMode == EDIT_DELMODE_RESTOFCONTENT )
+ {
+ aSelection.Max() = aText.Len();
+ }
+ else
+ {
+ sal_Int32 nCount = 1;
+ aSelection.Max() = xBI->nextCharacters( maText, aSelection.Max(), GetSettings().GetLocale(), text::CharacterIteratorMode::SKIPCHARACTER, nCount, nCount );;
+ }
+ }
+ }
+
+ maText.Erase( (xub_StrLen)aSelection.Min(), (xub_StrLen)aSelection.Len() );
+ maSelection.Min() = aSelection.Min();
+ maSelection.Max() = aSelection.Min();
+ ImplAlignAndPaint( (xub_StrLen)aSelection.Min(), nOldWidth );
+ mbInternModified = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplInsertText( const XubString& rStr, const Selection* pNewSel )
+{
+ Selection aSelection( maSelection );
+ aSelection.Justify();
+
+ XubString aNewText( rStr );
+ aNewText.EraseAllChars( _LF );
+ aNewText.EraseAllChars( _CR );
+ aNewText.SearchAndReplaceAll( '\t', ' ' );
+
+ if ( (maText.Len() + aNewText.Len() - aSelection.Len()) > mnMaxTextLen )
+ return;
+
+ long nOldWidth = GetTextWidth( ImplGetText() );
+
+ if ( aSelection.Len() )
+ maText.Erase( (xub_StrLen)aSelection.Min(), (xub_StrLen)aSelection.Len() );
+ else if ( !mbInsertMode && (aSelection.Max() < maText.Len()) )
+ maText.Erase( (xub_StrLen)aSelection.Max(), 1 );
+
+ if ( aNewText.Len() )
+ maText.Insert( aNewText, (xub_StrLen)aSelection.Min() );
+
+ if ( !pNewSel )
+ {
+ maSelection.Min() = aSelection.Min() + aNewText.Len();
+ maSelection.Max() = maSelection.Min();
+ }
+ else
+ {
+ maSelection = *pNewSel;
+ if ( maSelection.Min() > maText.Len() )
+ maSelection.Min() = maText.Len();
+ if ( maSelection.Max() > maText.Len() )
+ maSelection.Max() = maText.Len();
+ }
+
+ ImplAlignAndPaint( (xub_StrLen)aSelection.Min(), nOldWidth );
+ mbInternModified = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplSetText( const XubString& rText, const Selection* pNewSelection )
+{
+ // Der Text wird dadurch geloescht das der alte Text komplett 'selektiert'
+ // wird, dann InsertText, damit flackerfrei.
+ if ( (rText != maText) || (pNewSelection && (*pNewSelection != maSelection)) )
+ {
+ maSelection.Min() = 0;
+ maSelection.Max() = maText.Len();
+ if ( mnXOffset || HasPaintEvent() )
+ {
+ mnXOffset = 0;
+ maText = rText;
+
+ if ( pNewSelection )
+ ImplSetSelection( *pNewSelection, FALSE );
+
+ if ( mnXOffset && !pNewSelection )
+ maSelection.Max() = 0;
+
+ ImplAlign();
+ Invalidate();
+ }
+ else
+ ImplInsertText( rText, pNewSelection );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplClearBackground( long nXStart, long nXEnd )
+{
+ Point aTmpPoint;
+ Rectangle aRect( aTmpPoint, GetOutputSizePixel() );
+ aRect.Left() = nXStart;
+ aRect.Right() = nXEnd;
+
+ Cursor* pCursor = HasFocus() ? GetCursor() : NULL;
+
+ if ( pCursor )
+ pCursor->Hide();
+
+ Erase( aRect );
+
+ if ( pCursor )
+ pCursor->Show();
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplShowCursor( BOOL bOnlyIfVisible )
+{
+ if ( !IsUpdateMode() || ( bOnlyIfVisible && !IsReallyVisible() ) )
+ return;
+
+ Cursor* pCursor = GetCursor();
+ XubString aText = ImplGetText();
+ long nTextWidth = GetTextWidth( aText, 0, (xub_StrLen)maSelection.Max() );
+
+ long nCursorWidth = 0;
+ if ( !mbInsertMode && !maSelection.Len() && (maSelection.Max() < aText.Len()) )
+ nCursorWidth = GetTextWidth( aText, (xub_StrLen)maSelection.Max(), 1 );
+ long nCursorPosX = nTextWidth + mnXOffset;
+
+ // Cursor muss im sichtbaren Bereich landen:
+ Size aOutSize = GetOutputSizePixel();
+ if ( (nCursorPosX < 0) || (nCursorPosX >= aOutSize.Width()) )
+ {
+ long nOldXOffset = mnXOffset;
+
+ if ( nCursorPosX < 0 )
+ {
+ mnXOffset = - nTextWidth;
+ long nMaxX = 0;
+ mnXOffset += aOutSize.Width() / 5;
+ if ( mnXOffset > nMaxX )
+ mnXOffset = nMaxX;
+ }
+ else
+ {
+ mnXOffset = aOutSize.Width() - nTextWidth;
+ // Etwas mehr?
+ if ( aOutSize.Width() < nTextWidth )
+ {
+ long nMaxNegX = aOutSize.Width() - GetTextWidth( aText );
+ mnXOffset -= aOutSize.Width() / 5;
+ if ( mnXOffset < nMaxNegX ) // beides negativ...
+ mnXOffset = nMaxNegX;
+ }
+ }
+
+ nCursorPosX = nTextWidth + mnXOffset;
+ if ( nCursorPosX == aOutSize.Width() ) // dann nicht sichtbar...
+ nCursorPosX--;
+
+ if ( mnXOffset != nOldXOffset )
+ ImplRepaint();
+ }
+
+ long nTextHeight = GetTextHeight();
+ long nCursorPosY = (aOutSize.Height()-nTextHeight) / 2;
+ pCursor->SetPos( Point( nCursorPosX, nCursorPosY ) );
+ pCursor->SetSize( Size( nCursorWidth, nTextHeight ) );
+ pCursor->Show();
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplAlign()
+{
+ if ( mnAlign == EDIT_ALIGN_LEFT )
+ return;
+
+ long nTextWidth = GetTextWidth( ImplGetText() );
+ long nOutWidth = GetOutputSizePixel().Width();
+
+ if ( mnAlign == EDIT_ALIGN_RIGHT )
+ {
+ long nMinXOffset = nOutWidth - nTextWidth;
+ if ( mnXOffset < nMinXOffset )
+ mnXOffset = nMinXOffset;
+ }
+ else if( mnAlign == EDIT_ALIGN_CENTER )
+ {
+ // Mit Abfrage schoener, wenn gescrollt, dann aber nicht zentriert im gescrollten Zustand...
+// if ( nTextWidth < nOutWidth )
+ mnXOffset = (nOutWidth - nTextWidth) / 2;
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplAlignAndPaint( xub_StrLen nChangedFrom, long nOldWidth )
+{
+ long nNewWidth = GetTextWidth( ImplGetText() );
+ xub_StrLen nPaintStart = nChangedFrom;
+
+ ImplAlign();
+ if ( mnAlign == EDIT_ALIGN_LEFT )
+ {
+ if ( nOldWidth > nNewWidth )
+ ImplClearBackground( nNewWidth+mnXOffset, nOldWidth+mnXOffset );
+ }
+ else if ( mnAlign == EDIT_ALIGN_RIGHT )
+ {
+ nPaintStart = 0;
+ ImplClearBackground( GetOutputSizePixel().Width()-Max( nOldWidth, nNewWidth )-1, mnXOffset+1 );
+ }
+ else // EDIT_ALIGN_CENTER
+ {
+ nPaintStart = 0;
+ ImplClearBackground( 0, mnXOffset + 1 );
+ ImplClearBackground( mnXOffset+nNewWidth-1, GetOutputSizePixel().Width() );
+ }
+
+ ImplRepaint( nPaintStart, STRING_LEN );
+ ImplShowCursor();
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen Edit::ImplGetCharPos( const Point& rWindowPos )
+{
+ return GetTextBreak( ImplGetText(), rWindowPos.X() - mnXOffset );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplSetCursorPos( xub_StrLen nChar, BOOL bSelect )
+{
+ Selection aSelection( maSelection );
+ aSelection.Max() = nChar;
+ if ( !bSelect )
+ aSelection.Min() = aSelection.Max();
+ ImplSetSelection( aSelection );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplLoadRes( const ResId& rResId )
+{
+ Control::ImplLoadRes( rResId );
+
+ xub_StrLen nTextLength = ReadShortRes();
+ if ( nTextLength )
+ SetMaxTextLen( nTextLength );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( mpSubEdit )
+ {
+ Control::MouseButtonDown( rMEvt );
+ return;
+ }
+
+ xub_StrLen nChar = ImplGetCharPos( rMEvt.GetPosPixel() );
+ Selection aSelection( maSelection );
+ aSelection.Justify();
+
+ if ( rMEvt.GetClicks() < 4 )
+ {
+ mbClickedInSelection = FALSE;
+ if ( rMEvt.GetClicks() == 3 )
+ ImplSetSelection( Selection( 0, 0xFFFF ) );
+ else if ( rMEvt.GetClicks() == 2 )
+ {
+ uno::Reference < text::XBreakIterator > xBI = ImplGetBreakIterator();
+ text::Boundary aBoundary = xBI->getWordBoundary( maText, aSelection.Max(), GetSettings().GetLocale(), text::WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
+ ImplSetSelection( Selection( aBoundary.startPos, aBoundary.endPos ) );
+ }
+ else if ( !rMEvt.IsShift() && HasFocus() && aSelection.IsInside( nChar ) )
+ mbClickedInSelection = TRUE;
+ else if ( rMEvt.IsLeft() )
+ ImplSetCursorPos( nChar, rMEvt.IsShift() );
+
+ if ( !mbClickedInSelection && rMEvt.IsLeft() && ( rMEvt.GetClicks() == 1 ) )
+ StartTracking( STARTTRACK_SCROLLREPEAT );
+ }
+
+ mbInMBDown = TRUE; // Dann im GetFocus nicht alles selektieren
+ GrabFocus();
+ mbInMBDown = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( mbClickedInSelection && rMEvt.IsLeft() )
+ {
+ xub_StrLen nChar = ImplGetCharPos( rMEvt.GetPosPixel() );
+ ImplSetCursorPos( nChar, FALSE );
+ mbClickedInSelection = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( mbClickedInSelection )
+ {
+ xub_StrLen nChar = ImplGetCharPos( rTEvt.GetMouseEvent().GetPosPixel() );
+ ImplSetCursorPos( nChar, FALSE );
+ mbClickedInSelection = FALSE;
+ }
+ }
+ else
+ {
+ if( !mbClickedInSelection )
+ {
+ xub_StrLen nChar = ImplGetCharPos( rTEvt.GetMouseEvent().GetPosPixel() );
+ ImplSetCursorPos( nChar, TRUE );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Edit::ImplHandleKeyEvent( const KeyEvent& rKEvt )
+{
+ BOOL bDone = FALSE;
+ USHORT nCode = rKEvt.GetKeyCode().GetCode();
+ KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
+
+ mbInternModified = FALSE;
+
+ if ( eFunc != KEYFUNC_DONTKNOW )
+ {
+ switch ( eFunc )
+ {
+ case KEYFUNC_CUT:
+ {
+ if ( !mbReadOnly && maSelection.Len() && !(GetStyle() & WB_PASSWORD) )
+ {
+ Cut();
+ ImplModified();
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEYFUNC_COPY:
+ {
+ if ( !(GetStyle() & WB_PASSWORD) )
+ {
+ Copy();
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEYFUNC_PASTE:
+ {
+ if ( !mbReadOnly )
+ {
+ Paste();
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEYFUNC_UNDO:
+ {
+ if ( !mbReadOnly )
+ {
+ Undo();
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ default: // wird dann evtl. unten bearbeitet.
+ eFunc = KEYFUNC_DONTKNOW;
+ }
+ }
+
+ if ( eFunc == KEYFUNC_DONTKNOW )
+ {
+ switch ( nCode )
+ {
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ case KEY_HOME:
+ case KEY_END:
+ {
+ if ( !rKEvt.GetKeyCode().IsMod2() )
+ {
+ uno::Reference < text::XBreakIterator > xBI = ImplGetBreakIterator();
+
+ Selection aSel( maSelection );
+ BOOL bWord = rKEvt.GetKeyCode().IsMod1();
+ // Range wird in ImplSetSelection geprueft...
+ if ( ( nCode == KEY_LEFT ) && aSel.Max() )
+ {
+ if ( bWord )
+ {
+ text::Boundary aBoundary = xBI->getWordBoundary( maText, aSel.Max(), GetSettings().GetLocale(), text::WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
+ if ( aBoundary.startPos == aSel.Max() )
+ aBoundary = xBI->previousWord( maText, aSel.Max(), GetSettings().GetLocale(), text::WordType::ANYWORD_IGNOREWHITESPACES );
+ aSel.Max() = aBoundary.startPos;
+ }
+ else
+ {
+ sal_Int32 nCount = 1;
+ aSel.Max() = xBI->previousCharacters( maText, aSel.Max(), GetSettings().GetLocale(), text::CharacterIteratorMode::SKIPCHARACTER, nCount, nCount );
+ }
+ }
+ else if ( ( nCode == KEY_RIGHT ) && ( aSel.Max() < maText.Len() ) )
+ {
+ if ( bWord )
+ {
+ text::Boundary aBoundary = xBI->nextWord( maText, aSel.Max(), GetSettings().GetLocale(), text::WordType::ANYWORD_IGNOREWHITESPACES );
+ aSel.Max() = aBoundary.startPos;
+ }
+ else
+ {
+ sal_Int32 nCount = 1;
+ aSel.Max() = xBI->nextCharacters( maText, aSel.Max(), GetSettings().GetLocale(), text::CharacterIteratorMode::SKIPCHARACTER, nCount, nCount );
+ }
+ }
+ else if ( nCode == KEY_HOME )
+ aSel.Max() = 0;
+ else if ( nCode == KEY_END )
+ aSel.Max() = 0xFFFF;
+
+ if ( !rKEvt.GetKeyCode().IsShift() )
+ aSel.Min() = aSel.Max();
+
+ ImplSetSelection( aSel );
+
+ if ( (nCode == KEY_END) && maAutocompleteHdl.IsSet() && !rKEvt.GetKeyCode().GetModifier() )
+ {
+ if ( (maSelection.Min() == maSelection.Max()) && (maSelection.Min() == maText.Len()) )
+ {
+ meAutocompleteAction = AUTOCOMPLETE_KEYINPUT;
+ maAutocompleteHdl.Call( this );
+ }
+ }
+
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_BACKSPACE:
+ case KEY_DELETE:
+ {
+ if ( !mbReadOnly && !rKEvt.GetKeyCode().IsMod2() )
+ {
+ BYTE nDel = (nCode == KEY_DELETE) ? EDIT_DEL_RIGHT : EDIT_DEL_LEFT;
+ BYTE nMode = rKEvt.GetKeyCode().IsMod1() ? EDIT_DELMODE_RESTOFWORD : EDIT_DELMODE_SIMPLE;
+ if ( (nMode == EDIT_DELMODE_RESTOFWORD) && rKEvt.GetKeyCode().IsShift() )
+ nMode = EDIT_DELMODE_RESTOFCONTENT;
+ xub_StrLen nOldLen = maText.Len();
+ ImplDelete( maSelection, nDel, nMode );
+ if ( maText.Len() != nOldLen )
+ ImplModified();
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_INSERT:
+ {
+ if ( !mbReadOnly && !rKEvt.GetKeyCode().IsMod2() )
+ {
+ SetInsertMode( !mbInsertMode );
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_TAB:
+ {
+ if ( !mbReadOnly && maAutocompleteHdl.IsSet() &&
+ maSelection.Min() && (maSelection.Min() == maText.Len()) &&
+ !rKEvt.GetKeyCode().IsMod1() && !rKEvt.GetKeyCode().IsMod2() )
+ {
+ // Kein Autocomplete wenn alles Selektiert oder Edit leer, weil dann
+ // keine vernuenftige Tab-Steuerung!
+ if ( rKEvt.GetKeyCode().IsShift() )
+ meAutocompleteAction = AUTOCOMPLETE_TABBACKWARD;
+ else
+ meAutocompleteAction = AUTOCOMPLETE_TABFORWARD;
+
+ maAutocompleteHdl.Call( this );
+
+ // Wurde nichts veraendert, dann TAB fuer DialogControl
+ if ( GetSelection().Len() )
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ default:
+ {
+ if ( IsCharInput( rKEvt ) )
+ {
+ bDone = TRUE; // Auch bei ReadOnly die Zeichen schlucken.
+ if ( !mbReadOnly )
+ {
+ ImplInsertText( rKEvt.GetCharCode() );
+ if ( maAutocompleteHdl.IsSet() )
+ {
+ if ( (maSelection.Min() == maSelection.Max()) && (maSelection.Min() == maText.Len()) )
+ {
+ meAutocompleteAction = AUTOCOMPLETE_KEYINPUT;
+ maAutocompleteHdl.Call( this );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( !bDone && rKEvt.GetKeyCode().IsMod1() )
+ {
+ if ( nCode == KEY_A )
+ {
+ ImplSetSelection( Selection( 0, maText.Len() ) );
+ bDone = TRUE;
+ }
+ else if ( rKEvt.GetKeyCode().IsShift() && (nCode == KEY_S) )
+ {
+ if ( pImplFncGetSpecialChars )
+ {
+ Selection aSaveSel = GetSelection(); // Falls jemand in Get/LoseFocus die Selektion verbiegt, z.B. URL-Zeile...
+ XubString aChars = pImplFncGetSpecialChars( this, GetFont() );
+ SetSelection( aSaveSel );
+ if ( aChars.Len() )
+ {
+ ImplInsertText( aChars );
+ ImplModified();
+ }
+ bDone = TRUE;
+ }
+ }
+ }
+
+ if ( mbInternModified )
+ ImplModified();
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::KeyInput( const KeyEvent& rKEvt )
+{
+ if ( mpSubEdit || !ImplHandleKeyEvent( rKEvt ) )
+ Control::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Paint( const Rectangle& )
+{
+ if ( !mpSubEdit )
+ ImplRepaint();
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Resize()
+{
+ if ( !mpSubEdit && IsReallyVisible() )
+ {
+ // Wegen vertikaler Zentrierung...
+ mnXOffset = 0;
+ ImplAlign();
+ Invalidate();
+ ImplShowCursor();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
+{
+ ImplInitSettings( TRUE, TRUE, TRUE );
+
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Font aFont = GetDrawPixelFont( pDev );
+ OutDevType eOutDevType = pDev->GetOutDevType();
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ pDev->SetTextFillColor();
+
+ // Border/Background
+ pDev->SetLineColor();
+ pDev->SetFillColor();
+ BOOL bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
+ BOOL bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
+ if ( bBorder || bBackground )
+ {
+ Rectangle aRect( aPos, aSize );
+ if ( bBorder )
+ {
+ DecorationView aDecoView( pDev );
+ aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
+ }
+ if ( bBackground )
+ {
+ pDev->SetFillColor( GetControlBackground() );
+ pDev->DrawRect( aRect );
+ }
+ }
+
+ // Inhalt
+ if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ else
+ {
+ if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ pDev->SetTextColor( rStyleSettings.GetDisableColor() );
+ }
+ else
+ {
+ pDev->SetTextColor( GetTextColor() );
+ }
+ }
+
+ XubString aText = ImplGetText();
+ long nTextHeight = pDev->GetTextHeight();
+ long nTextWidth = pDev->GetTextWidth( aText );
+ long nOnePixel = GetDrawPixel( pDev, 1 );
+ long nOffX = 3*nOnePixel;
+ long nOffY = (aSize.Height() - nTextHeight) / 2;
+
+ if ( GetStyle() & WB_CENTER )
+ {
+ aPos.X() += (aSize.Width() - nTextWidth) / 2;
+ nOffX = 0;
+ }
+ else if ( GetStyle() & WB_RIGHT )
+ {
+ aPos.X() += aSize.Width() - nTextWidth;
+ nOffX = -nOffX;
+ }
+
+ // Clipping?
+ if ( (nOffY < 0) ||
+ ((nOffY+nTextHeight) > aSize.Height()) ||
+ ((nOffX+nTextWidth) > aSize.Width()) )
+ {
+ Rectangle aClip( aPos, aSize );
+ if ( nTextHeight > aSize.Height() )
+ aClip.Bottom() += nTextHeight-aSize.Height()+1; // Damit HP-Drucker nicht 'weg-optimieren'
+ pDev->IntersectClipRegion( aClip );
+ }
+
+ pDev->DrawText( Point( aPos.X() + nOffX, aPos.Y() + nOffY ), aText );
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::GetFocus()
+{
+ if ( mpSubEdit )
+ mpSubEdit->ImplGrabFocus( GetGetFocusFlags() );
+ else if ( !mbActivePopup )
+ {
+ maUndoText = maText;
+
+ ULONG nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions();
+ if ( !( GetStyle() & (WB_NOHIDESELECTION|WB_READONLY) )
+ && ( GetGetFocusFlags() & (GETFOCUS_INIT|GETFOCUS_TAB|GETFOCUS_CURSOR|GETFOCUS_MNEMONIC) ) )
+ {
+ if ( nSelOptions & SELECTION_OPTION_SHOWFIRST )
+ {
+ maSelection.Min() = maText.Len();
+ maSelection.Max() = 0;
+ }
+ else
+ {
+ maSelection.Min() = 0;
+ maSelection.Max() = maText.Len();
+ }
+ }
+
+ ImplShowCursor();
+
+ if ( maSelection.Len() )
+ {
+ // Selektion malen
+ if ( !HasPaintEvent() )
+ ImplRepaint();
+ else
+ Invalidate();
+ }
+
+ SetInputContext( InputContext( GetFont(), TRUE ) );
+ }
+
+ Control::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::LoseFocus()
+{
+ if ( !mpSubEdit )
+ {
+ if ( !mbActivePopup && !( GetStyle() & WB_NOHIDESELECTION ) && maSelection.Len() )
+ ImplRepaint(); // Selektion malen
+ }
+
+ Control::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Command( const CommandEvent& rCEvt )
+{
+ if ( (rCEvt.GetCommand() == COMMAND_STARTDRAG) &&
+ !IsTracking() && maSelection.Len() &&
+ !(GetStyle() & WB_PASSWORD) &&
+ (!mpDDInfo || mpDDInfo->bStarterOfDD == FALSE) ) // Kein Mehrfach D&D
+ {
+ Selection aSel( maSelection );
+ aSel.Justify();
+
+ // Nur wenn Maus in der Selektion...
+ xub_StrLen nChar = ImplGetCharPos( rCEvt.GetMousePosPixel() );
+ if ( (nChar >= aSel.Min()) && (nChar < aSel.Max()) )
+ {
+ if ( !mpDDInfo )
+ mpDDInfo = new DDInfo;
+
+ mpDDInfo->bStarterOfDD = TRUE;
+
+ Region* pDDRegion = NULL;
+ Cursor* pCursor = GetCursor();
+ if ( pCursor )
+ pCursor->Hide();
+
+ SotDataObjectRef xData = new StringDataObject( GetSelected() );
+ if ( IsTracking() )
+ EndTracking(); // Vor D&D Tracking ausschalten
+ DropAction aAction = DragManager::ExecuteDrag( xData, DRAG_ALL );
+
+ if ( aAction == DROP_MOVE )
+ {
+ if ( mpDDInfo->bDroppedInMe )
+ {
+ if ( aSel.Max() > mpDDInfo->nDropPos )
+ {
+ long nLen = aSel.Len();
+ aSel.Min() += nLen;
+ aSel.Max() += nLen;
+ }
+ }
+ ImplDelete( aSel, EDIT_DEL_RIGHT, EDIT_DELMODE_SIMPLE );
+ ImplModified();
+ }
+
+ ImplHideDDCursor();
+ delete mpDDInfo;
+ mpDDInfo = 0;
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ PopupMenu* pPopup = Edit::CreatePopupMenu();
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_HIDEDISABLED )
+ pPopup->SetMenuFlags( MENU_FLAG_HIDEDISABLEDENTRIES );
+
+ if ( !maSelection.Len() )
+ {
+ pPopup->EnableItem( SV_MENU_EDIT_CUT, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_COPY, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_DELETE, FALSE );
+ }
+
+ if ( IsReadOnly() )
+ {
+ pPopup->EnableItem( SV_MENU_EDIT_CUT, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_PASTE, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_DELETE, FALSE );
+ pPopup->EnableItem( SV_MENU_EDIT_INSERTSYMBOL, FALSE );
+ }
+ else
+ {
+ // Paste nur, wenn Text im Clipboard
+ if ( !VclClipboard::HasFormat( FORMAT_STRING ) )
+ pPopup->EnableItem( SV_MENU_EDIT_PASTE, FALSE );
+ }
+
+ if ( maUndoText == maText )
+ pPopup->EnableItem( SV_MENU_EDIT_UNDO, FALSE );
+ if ( ( maSelection.Min() == 0 ) && ( maSelection.Max() == maText.Len() ) )
+ pPopup->EnableItem( SV_MENU_EDIT_SELECTALL, FALSE );
+ if ( !pImplFncGetSpecialChars )
+ {
+ USHORT nPos = pPopup->GetItemPos( SV_MENU_EDIT_INSERTSYMBOL );
+ pPopup->RemoveItem( nPos );
+ pPopup->RemoveItem( nPos-1 );
+ }
+
+ mbActivePopup = TRUE;
+ Selection aSaveSel = GetSelection(); // Falls jemand in Get/LoseFocus die Selektion verbiegt, z.B. URL-Zeile...
+ Point aPos = rCEvt.GetMousePosPixel();
+ if ( !rCEvt.IsMouseEvent() )
+ {
+ // !!! Irgendwann einmal Menu zentriert in der Selektion anzeigen !!!
+ Size aSize = GetOutputSizePixel();
+ aPos = Point( aSize.Width()/2, aSize.Height()/2 );
+ }
+ USHORT n = pPopup->Execute( this, aPos );
+ Edit::DeletePopupMenu( pPopup );
+ SetSelection( aSaveSel );
+ switch ( n )
+ {
+ case SV_MENU_EDIT_UNDO:
+ Undo();
+ ImplModified();
+ break;
+ case SV_MENU_EDIT_CUT:
+ Cut();
+ ImplModified();
+ break;
+ case SV_MENU_EDIT_COPY:
+ Copy();
+ break;
+ case SV_MENU_EDIT_PASTE:
+ Paste();
+ ImplModified();
+ break;
+ case SV_MENU_EDIT_DELETE:
+ DeleteSelected();
+ ImplModified();
+ break;
+ case SV_MENU_EDIT_SELECTALL:
+ ImplSetSelection( Selection( 0, maText.Len() ) );
+ break;
+ case SV_MENU_EDIT_INSERTSYMBOL:
+ {
+ XubString aChars = pImplFncGetSpecialChars( this, GetFont() );
+ SetSelection( aSaveSel );
+ if ( aChars.Len() )
+ {
+ ImplInsertText( aChars );
+ ImplModified();
+ }
+ }
+ break;
+ }
+ mbActivePopup = FALSE;
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_VOICE )
+ {
+ const CommandVoiceData* pData = rCEvt.GetVoiceData();
+ if ( pData->GetType() == VOICECOMMANDTYPE_DICTATION )
+ {
+ switch ( pData->GetCommand() )
+ {
+ case DICTATIONCOMMAND_UNKNOWN:
+ {
+ ReplaceSelected( pData->GetText() );
+ }
+ break;
+ case DICTATIONCOMMAND_LEFT:
+ {
+ ImplHandleKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT, KEY_MOD1 ) ) );
+ }
+ break;
+ case DICTATIONCOMMAND_RIGHT:
+ {
+ ImplHandleKeyEvent( KeyEvent( 0, KeyCode( KEY_RIGHT, KEY_MOD1 ) ) );
+ }
+ break;
+ case DICTATIONCOMMAND_UNDO:
+ {
+ Undo();
+ }
+ break;
+ case DICTATIONCOMMAND_DEL:
+ {
+ ImplHandleKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT, KEY_MOD1|KEY_SHIFT ) ) );
+ DeleteSelected();
+ }
+ break;
+ }
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT )
+ {
+ DeleteSelected();
+ delete mpIMEInfos;
+ mpIMEInfos = new Impl_IMEInfos( (xub_StrLen)maSelection.Max() );
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT )
+ {
+ delete mpIMEInfos;
+ mpIMEInfos = NULL;
+ // Font wieder ohne Attribute einstellen, wird jetzt im Repaint nicht
+ // mehr neu initialisiert
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUT )
+ {
+ const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData();
+
+ maText.Erase( mpIMEInfos->nPos, mpIMEInfos->nLen );
+ maText.Insert( pData->GetText(), mpIMEInfos->nPos );
+
+ if ( pData->GetTextAttr() )
+ {
+ mpIMEInfos->CopyAttribs( pData->GetTextAttr(), pData->GetText().Len() );
+ mpIMEInfos->bCursor = pData->IsCursorVisible();
+ }
+ else
+ {
+ mpIMEInfos->DestroyAttribs();
+ }
+
+ Invalidate(); // Erstmal einfach zum Testen
+ xub_StrLen nCursorPos = mpIMEInfos->nPos + pData->GetCursorPos();
+ SetSelection( Selection( nCursorPos, nCursorPos ) );
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUTPOS )
+ {
+ XubString aText( maText, mpIMEInfos->nPos, mpIMEInfos->nLen );
+ if ( aText.Len() )
+ {
+ const CommandExtTextInputPosData* pData = rCEvt.GetExtTextInputPosData();
+
+ xub_StrLen nChars = aText.Len();
+ Rectangle* pRects = new Rectangle[nChars];
+ long* pDXArr = new long[nChars];
+ long nTextHeight = GetTextHeight();
+ long nTop = (GetOutputSize().Height()-nTextHeight)/2;
+ long nBottom = nTop + nTextHeight;
+ long nX = mnXOffset;
+
+ GetTextArray( aText, pDXArr );
+ if ( mpIMEInfos->nPos )
+ nX += GetTextWidth( XubString( maText, 0, mpIMEInfos->nPos ) );
+
+ for ( xub_StrLen n = 0; n < nChars; n++ )
+ {
+ pRects[n].Top() = nTop;
+ pRects[n].Bottom() = nBottom;
+ pRects[n].Left() = nX + (n ? pDXArr[ n-1 ] : 0);
+ pRects[n].Right() = nX + pDXArr[n];
+ }
+ SetExtTextInputPos( 0, nChars, pRects );
+ delete pRects;
+ delete pDXArr;
+ }
+ else
+ SetExtTextInputPos( 0, 0, NULL );
+ }
+ else
+ Control::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if ( !mpSubEdit )
+ {
+ mnXOffset = 0; // Falls vorher GrabFocus, als Groesse noch falsch.
+ ImplAlign();
+ if ( !mpSubEdit )
+ ImplShowCursor( FALSE );
+ }
+ }
+ else if ( nType == STATE_CHANGE_ENABLE )
+ {
+ if ( !mpSubEdit )
+ {
+ // Es aendert sich nur die Textfarbe...
+ ImplRepaint( 0, 0xFFFF );
+ }
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ WinBits nStyle = ImplInitStyle( GetStyle() );
+ SetStyle( nStyle );
+
+ USHORT nOldAlign = mnAlign;
+ mnAlign = EDIT_ALIGN_LEFT;
+ if ( nStyle & WB_RIGHT )
+ mnAlign = EDIT_ALIGN_RIGHT;
+ else if ( nStyle & WB_CENTER )
+ mnAlign = EDIT_ALIGN_CENTER;
+ if ( maText.Len() && ( mnAlign != nOldAlign ) )
+ {
+ ImplAlign();
+ Invalidate();
+ }
+
+ }
+ else if ( nType == STATE_CHANGE_ZOOM )
+ {
+ if ( !mpSubEdit )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ ImplShowCursor( TRUE );
+ Invalidate();
+ }
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ if ( !mpSubEdit )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ ImplShowCursor();
+ Invalidate();
+ }
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ if ( !mpSubEdit )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ if ( !mpSubEdit )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+ }
+
+ Control::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ if ( !mpSubEdit )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ ImplShowCursor( TRUE );
+ Invalidate();
+ }
+ }
+
+ Control::DataChanged( rDCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplShowDDCursor()
+{
+ if ( !mpDDInfo->bVisCursor )
+ {
+ long nTextWidth = GetTextWidth( maText, 0, mpDDInfo->nDropPos );
+ long nTextHeight = GetTextHeight();
+ Rectangle aCursorRect( Point( nTextWidth + mnXOffset, (GetOutputSize().Height()-nTextHeight)/2 ), Size( 2, nTextHeight ) );
+ mpDDInfo->aCursor.SetWindow( this );
+ mpDDInfo->aCursor.SetPos( aCursorRect.TopLeft() );
+ mpDDInfo->aCursor.SetSize( aCursorRect.GetSize() );
+ mpDDInfo->aCursor.Show();
+ mpDDInfo->bVisCursor = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplHideDDCursor()
+{
+ if ( mpDDInfo && mpDDInfo->bVisCursor )
+ {
+ mpDDInfo->aCursor.Hide();
+ mpDDInfo->bVisCursor = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Edit::QueryDrop( DropEvent& rDEvt )
+{
+ if ( rDEvt.IsLeaveWindow() )
+ {
+ ImplHideDDCursor();
+ return FALSE;
+ }
+
+ // Daten holen
+ SotDataObjectRef xDataObj = ((DropEvent&)rDEvt).GetData();
+ BOOL bString = xDataObj.Is() && NULL != xDataObj->GetTypeList().Get( FORMAT_STRING );
+
+ BOOL bDrop = FALSE;
+ if ( !mbReadOnly && bString &&
+ ( ( rDEvt.GetAction() == DROP_COPY ) || ( rDEvt.GetAction() == DROP_MOVE ) || ( rDEvt.GetAction() == DROP_LINK ) ) )
+ {
+ if ( !mpDDInfo )
+ mpDDInfo = new DDInfo;
+
+ Point aMousePos( rDEvt.GetPosPixel() );
+
+ xub_StrLen nPrevDropPos = mpDDInfo->nDropPos;
+ mpDDInfo->nDropPos = ImplGetCharPos( aMousePos );
+
+ Size aOutSize = GetOutputSizePixel();
+ if ( ( aMousePos.X() < 0 ) || ( aMousePos.X() > aOutSize.Width() ) )
+ {
+ // Scrollen ?
+ }
+
+ Selection aSel( maSelection );
+ aSel.Justify();
+
+ // Nicht in Selektion droppen:
+ if ( aSel.IsInside( mpDDInfo->nDropPos ) )
+ {
+ ImplHideDDCursor();
+ return FALSE;
+ }
+
+ // Alten Cursor wegzeichnen...
+ if ( !mpDDInfo->bVisCursor || ( nPrevDropPos != mpDDInfo->nDropPos ) )
+ {
+ ImplHideDDCursor();
+ ImplShowDDCursor();
+ }
+ bDrop = TRUE;
+ }
+
+ return bDrop;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Edit::Drop( const DropEvent& rDEvt )
+{
+ mbInternModified = FALSE;
+
+ BOOL bDone = TRUE;
+ if ( !mbReadOnly && mpDDInfo )
+ {
+ ImplHideDDCursor();
+ Point aMousePos( rDEvt.GetPosPixel() );
+
+ Selection aSel( maSelection );
+ aSel.Justify();
+
+ if ( aSel.Len() && !mpDDInfo->bStarterOfDD )
+ ImplDelete( aSel, EDIT_DEL_RIGHT, EDIT_DELMODE_SIMPLE );
+
+ mpDDInfo->bDroppedInMe = TRUE;
+
+ aSel.Min() = mpDDInfo->nDropPos;
+ aSel.Max() = mpDDInfo->nDropPos;
+ ImplSetSelection( aSel );
+
+ // Daten holen
+ SotDataObjectRef xDataObj = ((DropEvent&)rDEvt).GetData();
+ SvData aData( FORMAT_STRING );
+ if( xDataObj->GetData( &aData ) )
+ {
+ XubString aStr;
+ aData.GetData( aStr );
+ ImplInsertText( aStr );
+ }
+
+ if ( !mpDDInfo->bStarterOfDD )
+ {
+ delete mpDDInfo;
+ mpDDInfo = 0;
+ }
+ }
+
+ if ( mbInternModified )
+ ImplModified();
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Modify()
+{
+ if ( mbIsSubEdit )
+ {
+ ((Edit*)GetParent())->Modify();
+ }
+ else
+ {
+ if ( mpUpdateDataTimer )
+ mpUpdateDataTimer->Start();
+
+ maModifyHdl.Call( this );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::UpdateData()
+{
+ maUpdateDataHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Edit, ImplUpdateDataHdl, Timer*, EMPTYARG )
+{
+ UpdateData();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::EnableUpdateData( ULONG nTimeout )
+{
+ if ( !nTimeout )
+ DisableUpdateData();
+ else
+ {
+ if ( !mpUpdateDataTimer )
+ {
+ mpUpdateDataTimer = new Timer;
+ mpUpdateDataTimer->SetTimeoutHdl( LINK( this, Edit, ImplUpdateDataHdl ) );
+ }
+
+ mpUpdateDataTimer->SetTimeout( nTimeout );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetEchoChar( xub_Unicode c )
+{
+ mcEchoChar = c;
+ if ( mpSubEdit )
+ mpSubEdit->SetEchoChar( c );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetReadOnly( BOOL bReadOnly )
+{
+ if ( mbReadOnly != bReadOnly )
+ {
+ mbReadOnly = bReadOnly;
+ if ( mpSubEdit )
+ mpSubEdit->SetReadOnly( bReadOnly );
+
+ StateChanged( STATE_CHANGE_READONLY );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetAutocompleteHdl( const Link& rHdl )
+{
+ maAutocompleteHdl = rHdl;
+ if ( mpSubEdit )
+ mpSubEdit->SetAutocompleteHdl( rHdl );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetInsertMode( BOOL bInsert )
+{
+ if ( bInsert != mbInsertMode )
+ {
+ mbInsertMode = bInsert;
+ if ( mpSubEdit )
+ mpSubEdit->SetInsertMode( bInsert );
+ else
+ ImplShowCursor();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Edit::IsInsertMode() const
+{
+ if ( mpSubEdit )
+ return mpSubEdit->IsInsertMode();
+ else
+ return mbInsertMode;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetMaxTextLen( xub_StrLen nMaxLen )
+{
+ mnMaxTextLen = nMaxLen ? nMaxLen : EDIT_NOLIMIT;
+
+ if ( mpSubEdit )
+ mpSubEdit->SetMaxTextLen( nMaxLen );
+ else
+ {
+ if ( maText.Len() > nMaxLen )
+ ImplDelete( Selection( nMaxLen, maText.Len() ), EDIT_DEL_RIGHT, EDIT_DELMODE_SIMPLE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetSelection( const Selection& rSelection )
+{
+ // Wenn von aussen z.B. im MouseButtonDown die Selektion geaendert wird,
+ // soll nicht gleich ein Tracking() zuschlagen und die Selektion aendern.
+ if ( IsTracking() )
+ EndTracking();
+ else if ( mpSubEdit && mpSubEdit->IsTracking() )
+ mpSubEdit->EndTracking();
+
+ ImplSetSelection( rSelection );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ImplSetSelection( const Selection& rSelection, BOOL bPaint )
+{
+ if ( mpSubEdit )
+ mpSubEdit->ImplSetSelection( rSelection );
+ else
+ {
+ if ( rSelection != maSelection )
+ {
+ Selection aOld( maSelection );
+ Selection aNew( rSelection );
+
+ if ( aNew.Min() > maText.Len() )
+ aNew.Min() = maText.Len();
+ if ( aNew.Max() > maText.Len() )
+ aNew.Max() = maText.Len();
+ if ( aNew.Min() < 0 )
+ aNew.Min() = 0;
+ if ( aNew.Max() < 0 )
+ aNew.Max() = 0;
+
+ if ( aNew != maSelection )
+ {
+ maSelection = aNew;
+
+ if ( bPaint && ( aOld.Len() || aNew.Len() ) )
+ {
+ aOld.Justify();
+ aNew.Justify();
+ xub_StrLen nStart = (xub_StrLen)Min( aOld.Min(), aNew.Min() );
+ xub_StrLen nEnd = (xub_StrLen)Max( aOld.Max(), aNew.Max() );
+ ImplRepaint( nStart, nEnd );
+ }
+ ImplShowCursor();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+const Selection& Edit::GetSelection() const
+{
+ if ( mpSubEdit )
+ return mpSubEdit->GetSelection();
+ else
+ return maSelection;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ReplaceSelected( const XubString& rStr )
+{
+ if ( mpSubEdit )
+ mpSubEdit->ReplaceSelected( rStr );
+ else
+ ImplInsertText( rStr );
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::DeleteSelected()
+{
+ if ( mpSubEdit )
+ mpSubEdit->DeleteSelected();
+ else
+ {
+ if ( maSelection.Len() )
+ ImplDelete( maSelection, EDIT_DEL_RIGHT, EDIT_DELMODE_SIMPLE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString Edit::GetSelected() const
+{
+ if ( mpSubEdit )
+ return mpSubEdit->GetSelected();
+ else
+ {
+ Selection aSelection( maSelection );
+ aSelection.Justify();
+ return maText.Copy( (xub_StrLen)aSelection.Min(), (xub_StrLen)aSelection.Len() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Cut()
+{
+ if ( !(GetStyle() & WB_PASSWORD ) )
+ {
+ Copy();
+ ReplaceSelected( ImplGetSVEmptyStr() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Copy()
+{
+ if ( !(GetStyle() & WB_PASSWORD ) )
+ {
+ SotDataObjectRef xData = new StringDataObject( GetSelected() );
+ VclClipboard::Copy( xData );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Paste()
+{
+ // Daten holen
+ SotDataObjectRef xDataObj = VclClipboard::Paste();
+ SvData aData( FORMAT_STRING );
+ if( xDataObj.Is() && xDataObj->GetData( &aData ) )
+ {
+ XubString aStr;
+ aData.GetData( aStr );
+ ReplaceSelected( aStr );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::Undo()
+{
+ if ( mpSubEdit )
+ mpSubEdit->Undo();
+ else
+ {
+ XubString aText( maText );
+ ImplDelete( Selection( 0, aText.Len() ), EDIT_DEL_RIGHT, EDIT_DELMODE_SIMPLE );
+ ImplInsertText( maUndoText );
+ ImplSetSelection( Selection( 0, maUndoText.Len() ) );
+ maUndoText = aText;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetText( const XubString& rStr )
+{
+ if ( mpSubEdit )
+ mpSubEdit->SetText( rStr ); // Nicht direkt ImplSetText, falls SetText ueberladen
+ else
+ {
+ Selection aNewSel( 0, 0 ); // Damit nicht gescrollt wird
+ ImplSetText( rStr, &aNewSel );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetText( const XubString& rStr, const Selection& rSelection )
+{
+ if ( mpSubEdit )
+ mpSubEdit->SetText( rStr, rSelection );
+ else
+ ImplSetText( rStr, &rSelection );
+}
+
+// -----------------------------------------------------------------------
+
+XubString Edit::GetText() const
+{
+ if ( mpSubEdit )
+ return mpSubEdit->GetText();
+ else
+ return maText;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetModifyFlag()
+{
+ if ( mpSubEdit )
+ mpSubEdit->mbModified = TRUE;
+ else
+ mbModified = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::ClearModifyFlag()
+{
+ if ( mpSubEdit )
+ mpSubEdit->mbModified = FALSE;
+ else
+ mbModified = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetSubEdit( Edit* pEdit )
+{
+ mpSubEdit = pEdit;
+ if ( mpSubEdit )
+ {
+ SetPointer( POINTER_ARROW ); // Nur das SubEdit hat den BEAM...
+ mpSubEdit->mbIsSubEdit = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size Edit::CalcMinimumSize() const
+{
+ Size aSz( GetTextWidth( GetText() ), GetTextHeight() );
+ aSz = CalcWindowSize( aSz );
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+Size Edit::CalcSize( xub_StrLen nChars ) const
+{
+ // Breite fuer n Zeichen, unabhaengig vom Inhalt.
+ // Funktioniert nur bei FixedFont richtig, sonst Mittelwert.
+ Size aSz( GetTextWidth( XubString( 'x' ) ), GetTextHeight() );
+ aSz.Width() *= nChars;
+ aSz = CalcWindowSize( aSz );
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen Edit::GetMaxVisChars() const
+{
+ const Window* pW = mpSubEdit ? mpSubEdit : this;
+ long nOutWidth = pW->GetOutputSizePixel().Width();
+ long nCharWidth = GetTextWidth( XubString( 'x' ) );
+ return nCharWidth ? (xub_StrLen)(nOutWidth/nCharWidth) : 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::SetGetSpecialCharsFunction( FncGetSpecialChars fn )
+{
+ pImplFncGetSpecialChars = fn;
+}
+
+// -----------------------------------------------------------------------
+
+FncGetSpecialChars Edit::GetGetSpecialCharsFunction()
+{
+ return pImplFncGetSpecialChars;
+}
+
+// -----------------------------------------------------------------------
+
+PopupMenu* Edit::CreatePopupMenu()
+{
+ PopupMenu* pPopup = new PopupMenu( ResId( SV_RESID_MENU_EDIT, ImplGetResMgr() ) );
+ pPopup->SetAccelKey( SV_MENU_EDIT_UNDO, KeyCode( KEYFUNC_UNDO ) );
+ pPopup->SetAccelKey( SV_MENU_EDIT_CUT, KeyCode( KEYFUNC_CUT ) );
+ pPopup->SetAccelKey( SV_MENU_EDIT_COPY, KeyCode( KEYFUNC_COPY ) );
+ pPopup->SetAccelKey( SV_MENU_EDIT_PASTE, KeyCode( KEYFUNC_PASTE ) );
+ pPopup->SetAccelKey( SV_MENU_EDIT_DELETE, KeyCode( KEYFUNC_DELETE ) );
+ pPopup->SetAccelKey( SV_MENU_EDIT_SELECTALL, KeyCode( KEY_A, FALSE, TRUE, FALSE ) );
+ pPopup->SetAccelKey( SV_MENU_EDIT_INSERTSYMBOL, KeyCode( KEY_S, TRUE, TRUE, FALSE ) );
+ return pPopup;
+}
+
+// -----------------------------------------------------------------------
+
+void Edit::DeletePopupMenu( PopupMenu* pMenu )
+{
+ delete pMenu;
+}
+
+ImplSubEdit::ImplSubEdit( Edit* pParent, WinBits nStyle ) :
+ Edit( pParent, nStyle )
+{
+ pParent->SetSubEdit( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSubEdit::Modify()
+{
+ GetParent()->Modify();
+}
diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx
new file mode 100644
index 000000000000..42a30ffd1b5f
--- /dev/null
+++ b/vcl/source/control/field.cxx
@@ -0,0 +1,2330 @@
+/*************************************************************************
+ *
+ * $RCSfile: field.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _TOOLS_BIGINT
+#define _SV_FIELD_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _BIGINT_HXX
+#include <tools/bigint.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+
+#include <field.hxx>
+#include <event.hxx>
+#include <svapp.hxx>
+#include <svdata.hxx>
+
+#pragma hdrstop
+
+// -----------------------------------------------------------------------
+
+#define FORMAT_NUMERIC 1
+#define FORMAT_METRIC 2
+#define FORMAT_CURRENCY 3
+
+// -----------------------------------------------------------------------
+
+static long ImplPower10( USHORT n )
+{
+ USHORT i;
+ long nValue = 1;
+
+ for ( i=0; i < n; i++ )
+ nValue *= 10;
+
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplNumericProcessKeyInput( Edit*, const KeyEvent& rKEvt,
+ BOOL bStrictFormat,
+ const International& rInter )
+{
+ if ( !bStrictFormat )
+ return FALSE;
+ else
+ {
+ xub_Unicode cChar = rKEvt.GetCharCode();
+ USHORT nGroup = rKEvt.GetKeyCode().GetGroup();
+
+ if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
+ (nGroup == KEYGROUP_MISC) ||
+ ((cChar >= '0') && (cChar <= '9')) ||
+ (rInter.IsNumThousandSep() && (cChar == rInter.GetNumThousandSep())) ||
+ (cChar == rInter.GetNumDecimalSep()) ||
+ (cChar == '-') )
+ return FALSE;
+ else
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplNumericGetValue( const XubString& rStr, double& rValue,
+ USHORT nDecDigits, const International& rInter,
+ BOOL bCurrency = FALSE )
+{
+ XubString aStr = rStr;
+ XubString aStr1;
+ XubString aStr2;
+ BOOL bNegative = FALSE;
+ xub_StrLen nDecPos;
+ xub_StrLen i;
+
+ // Reaktion auf leeren String
+ if ( !rStr.Len() )
+ return FALSE;
+
+ // Fuehrende und nachfolgende Leerzeichen entfernen
+ aStr.EraseLeadingAndTrailingChars( ' ' );
+
+ // Position des Dezimalpunktes suchen
+ nDecPos = aStr.Search( rInter.GetNumDecimalSep() );
+ if ( nDecPos != STRING_NOTFOUND )
+ {
+ aStr1 = aStr.Copy( 0, nDecPos );
+ aStr2 = aStr.Copy( nDecPos+1 );
+ }
+ else
+ aStr1 = aStr;
+
+ // Negativ ?
+ if ( bCurrency )
+ {
+ if ( (aStr.GetChar( 0 ) == '(') && (aStr.GetChar( aStr.Len()-1 ) == ')') )
+ bNegative = TRUE;
+ if ( !bNegative )
+ {
+ for ( i=0; i < aStr.Len(); i++ )
+ {
+ if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
+ break;
+ else if ( aStr.GetChar( i ) == '-' )
+ {
+ bNegative = TRUE;
+ break;
+ }
+ }
+ }
+ if ( !bNegative && bCurrency && aStr.Len() )
+ {
+ USHORT nFormat = rInter.GetCurrNegativeFormat();
+ if ( (nFormat == 3) || (nFormat == 6) ||
+ (nFormat == 7) || (nFormat == 10) )
+ {
+ for ( i = (xub_StrLen)(aStr.Len()-1); i > 0; i++ )
+ {
+ if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
+ break;
+ else if ( aStr.GetChar( i ) == '-' )
+ {
+ bNegative = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( aStr1.GetChar( 0 ) == '-' )
+ bNegative = TRUE;
+ }
+
+ // Alle unerwuenschten Zeichen rauswerfen
+ for ( i=0; i < aStr1.Len(); )
+ {
+ if ( (aStr1.GetChar( i ) >= '0') && (aStr1.GetChar( i ) <= '9') )
+ i++;
+ else
+ aStr1.Erase( i, 1 );
+ }
+ for ( i=0; i < aStr2.Len(); )
+ {
+ if ( (aStr2.GetChar( i ) >= '0') && (aStr2.GetChar( i ) <= '9') )
+ i++;
+ else
+ aStr2.Erase( i, 1 );
+ }
+
+ if ( !aStr1.Len() && !aStr2.Len() )
+ return FALSE;
+
+ if ( !aStr1.Len() )
+ aStr1.Insert( '0' );
+ if ( bNegative )
+ aStr1.Insert( '-', 0 );
+
+ // Nachkommateil zurechtstutzen und dabei runden
+ BOOL bRound = FALSE;
+ if ( aStr2.Len() > nDecDigits )
+ {
+ if ( aStr2.GetChar( nDecDigits ) >= '5' )
+ bRound = TRUE;
+ aStr2.Erase( nDecDigits );
+ }
+ if ( aStr2.Len() < nDecDigits )
+ aStr2.Expand( nDecDigits, '0' );
+
+ aStr = aStr1;
+ aStr += aStr2;
+
+ // Bereichsueberpruefung
+ double nValue = aStr.ToDouble();
+ if ( bRound )
+ {
+ if ( !bNegative )
+ nValue++;
+ else
+ nValue--;
+ }
+
+ rValue = nValue;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+FormatterBase::FormatterBase( Edit* pField )
+{
+ mpField = pField;
+ mpInternational = NULL;
+ mbReformat = FALSE;
+ mbStrictFormat = FALSE;
+ mbEmptyFieldValue = FALSE;
+ mbEmptyFieldValueEnabled = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+FormatterBase::~FormatterBase()
+{
+ delete mpInternational;
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::Reformat()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::ReformatAll()
+{
+ Reformat();
+};
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::SetStrictFormat( BOOL bStrict )
+{
+ if ( bStrict != mbStrictFormat )
+ {
+ mbStrictFormat = bStrict;
+ if ( mbStrictFormat )
+ ReformatAll();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::SetInternational( const International& rInternational )
+{
+ delete mpInternational;
+ mpInternational = new International( rInternational );
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+const International& FormatterBase::GetInternational() const
+{
+ if ( !mpInternational )
+ {
+ if ( mpField )
+ return mpField->GetSettings().GetInternational();
+ else
+ return Application::GetSettings().GetInternational();
+ }
+
+ return *mpInternational;
+}
+
+// -----------------------------------------------------------------------
+
+const AllSettings& FormatterBase::GetFieldSettings() const
+{
+ if ( mpField )
+ return mpField->GetSettings();
+ else
+ return Application::GetSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::SetFieldText( const XubString& rText, BOOL bKeepSelection )
+{
+ if ( mpField )
+ {
+ Selection aNewSelection( 0xFFFF, 0xFFFF );
+ if ( bKeepSelection )
+ aNewSelection = mpField->GetSelection();
+
+ ImplSetText( rText, &aNewSelection );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::ImplSetText( const XubString& rText, Selection* pNewSelection )
+{
+ if ( mpField )
+ {
+ // !!! TH-18.2.99: Wenn wir Zeit haben sollte mal geklaert werden,
+ // !!! warum SetText() intern bei gleichem Text nicht ImplSetSelection
+ // !!! aufruft, sondern etwas anders macht, denn sehr haeufig kommt
+ // !!! hier der gleiche Text an.
+
+ // ggf. bleibt der Text gleich, aber die Selektion wird geaendert...
+ BOOL bTextChanged = (mpField->GetText() != rText);
+
+ if ( pNewSelection )
+ mpField->SetText( rText, *pNewSelection );
+ else
+ {
+ Selection aSel = mpField->GetSelection();
+ aSel.Min() = aSel.Max();
+ mpField->SetText( rText, aSel );
+ }
+
+ // !!! TH-18.2.99: Wenn wir Zeit haben sollte mal geklaert werden,
+ // !!! warum hier der Modify-Handler gerufen wird !!!
+
+ // !!! MT-8.7.99: Erstmal auskommentiert, koentest recht haben,
+ // !!! Modify wird zu oft gerufen.
+// if ( MustBeReformatted() && bTextChanged )
+// mpField->Edit::Modify(); // Nur damit Modify-Hdl gerufen wird.
+
+ MarkToBeReformatted( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::SetEmptyFieldValue()
+{
+ if ( mpField )
+ mpField->SetText( ImplGetSVEmptyStr() );
+ mbEmptyFieldValue = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FormatterBase::IsEmptyFieldValue() const
+{
+ return (!mpField || !mpField->GetText().Len());
+}
+
+// -----------------------------------------------------------------------
+
+BOOL NumericFormatter::ImplNumericReformat( const XubString& rStr, double& rValue,
+ XubString& rOutStr )
+{
+ if ( !ImplNumericGetValue( rStr, rValue, GetDecimalDigits(), GetInternational() ) )
+ return TRUE;
+ else
+ {
+ double nTempVal = rValue;
+ if ( nTempVal > mnMax )
+ nTempVal = mnMax;
+ else if ( nTempVal < mnMin )
+ nTempVal = mnMin;
+
+ if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
+ {
+ mnCorrectedValue = (long)nTempVal;
+ if ( !GetErrorHdl().Call( this ) )
+ {
+ mnCorrectedValue = 0;
+ return FALSE;
+ }
+ else
+ mnCorrectedValue = 0;
+ }
+
+ rOutStr = CreateFieldText( (long)nTempVal );
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::ImplInit()
+{
+ mnFieldValue = 0;
+ mnLastValue = 0;
+ mnMin = 0;
+ mnMax = 0x7FFFFFFF;
+ mnCorrectedValue = 0;
+ mnType = FORMAT_NUMERIC;
+
+ // Fuer Felder...
+ mnSpinSize = 1;
+ mnFirst = mnMin;
+ mnLast = mnMax;
+
+ SetDecimalDigits( 0 );
+}
+
+// -----------------------------------------------------------------------
+
+NumericFormatter::NumericFormatter()
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::ImplLoadRes( const ResId& rResId )
+{
+ ResMgr* pMgr = Resource::GetResManager();
+ USHORT nMask;
+
+ nMask = pMgr->ReadShort();
+
+ if ( NUMERICFORMATTER_MIN & nMask )
+ mnMin = pMgr->ReadLong();
+
+ if ( NUMERICFORMATTER_MAX & nMask )
+ mnMax = pMgr->ReadLong();
+
+ if ( NUMERICFORMATTER_STRICTFORMAT & nMask )
+ SetStrictFormat( (BOOL)pMgr->ReadShort() );
+
+ if ( NUMERICFORMATTER_I12 & nMask )
+ {
+ SetInternational( International( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) ) );
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ }
+ if ( NUMERICFORMATTER_DECIMALDIGITS & nMask )
+ SetDecimalDigits( pMgr->ReadShort() );
+
+ if ( NUMERICFORMATTER_VALUE & nMask )
+ {
+ mnFieldValue = pMgr->ReadLong();
+ if ( mnFieldValue > mnMax )
+ mnFieldValue = mnMax;
+ else if ( mnFieldValue < mnMin )
+ mnFieldValue = mnMin;
+ mnLastValue = mnFieldValue;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+NumericFormatter::~NumericFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetMin( long nNewMin )
+{
+ mnMin = nNewMin;
+ if ( !IsEmptyFieldValue() )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetMax( long nNewMax )
+{
+ mnMax = nNewMax;
+ if ( !IsEmptyFieldValue() )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetDecimalDigits( USHORT nDigits )
+{
+ International aInter( GetInternational() );
+ aInter.SetCurrDigits( nDigits );
+ SetInternational( aInter );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT NumericFormatter::GetDecimalDigits() const
+{
+ return GetInternational().GetCurrDigits();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetValue( long nNewValue )
+{
+ SetUserValue( nNewValue );
+ mnFieldValue = mnLastValue;
+ ImplGetEmptyFieldValue() = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString NumericFormatter::CreateFieldText( long nValue ) const
+{
+ return GetInternational().GetNum( nValue, GetDecimalDigits() );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::ImplSetUserValue( long nNewValue, Selection* pNewSelection )
+{
+ if ( nNewValue > mnMax )
+ nNewValue = mnMax;
+ else if ( nNewValue < mnMin )
+ nNewValue = mnMin;
+ mnLastValue = nNewValue;
+
+ if ( GetField() )
+ ImplSetText( CreateFieldText( nNewValue ), pNewSelection );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetUserValue( long nNewValue )
+{
+ ImplSetUserValue( nNewValue );
+}
+
+// -----------------------------------------------------------------------
+
+long NumericFormatter::GetValue() const
+{
+ if ( !GetField() )
+ return 0;
+
+ double nTempValue;
+
+ if ( ImplNumericGetValue( GetField()->GetText(), nTempValue,
+ GetDecimalDigits(), GetInternational() ) )
+ {
+ if ( nTempValue > mnMax )
+ nTempValue = mnMax;
+ else if ( nTempValue < mnMin )
+ nTempValue = mnMin;
+ return (long)nTempValue;
+ }
+ else
+ return mnLastValue;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL NumericFormatter::IsValueModified() const
+{
+ if ( ImplGetEmptyFieldValue() )
+ return !IsEmptyFieldValue();
+ else if ( GetValue() != mnFieldValue )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Fraction NumericFormatter::ConvertToFraction( long nValue )
+{
+ return Fraction( nValue, ImplPower10( GetDecimalDigits() ) );
+}
+
+// -----------------------------------------------------------------------
+
+long NumericFormatter::ConvertToLong( const Fraction& rValue )
+{
+ Fraction aFract = rValue;
+ aFract *= Fraction( ImplPower10( GetDecimalDigits() ) );
+ return (long)aFract;
+}
+
+// -----------------------------------------------------------------------
+
+long NumericFormatter::Normalize( long nValue ) const
+{
+ return (nValue * ImplPower10( GetDecimalDigits() ) );
+}
+
+// -----------------------------------------------------------------------
+
+long NumericFormatter::Denormalize( long nValue ) const
+{
+ long nFactor = ImplPower10( GetDecimalDigits() );
+ if( nValue < 0 )
+ return ((nValue-(nFactor/2)) / nFactor );
+ else
+ return ((nValue+(nFactor/2)) / nFactor );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::Reformat()
+{
+ if ( !GetField() )
+ return;
+
+ if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
+ return;
+
+ XubString aStr;
+ double nTemp = mnLastValue;
+ BOOL bOK = ImplNumericReformat( GetField()->GetText(), nTemp, aStr );
+ mnLastValue = (long)nTemp;
+ if ( !bOK )
+ return;
+
+ if ( aStr.Len() )
+ ImplSetText( aStr );
+ else
+ SetValue( mnLastValue );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::FieldUp()
+{
+ long nValue = GetValue();
+ nValue += mnSpinSize;
+ if ( nValue > mnMax )
+ nValue = mnMax;
+
+ ImplNewFieldValue( nValue );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::FieldDown()
+{
+ long nValue = GetValue();
+ nValue -= mnSpinSize;
+ if ( nValue < mnMin )
+ nValue = mnMin;
+
+ ImplNewFieldValue( nValue );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::FieldFirst()
+{
+ ImplNewFieldValue( mnFirst );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::FieldLast()
+{
+ ImplNewFieldValue( mnLast );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::ImplNewFieldValue( long nNewValue )
+{
+ if ( GetField() )
+ {
+ // !!! TH-18.2.99: Wenn wir Zeit haben sollte mal geklaert werden,
+ // !!! warum nicht bei ImplSetUserValue() geprueft wird, ob
+ // !!! sich der Wert aendert. Denn auch hier muesste dieses
+ // !!! gemacht werden, da ansonsten der Modify-Aufruf
+ // !!! nicht gemacht werden duerfte. Jedenfalls sollten die
+ // !!! Wege von ImplNewFieldValue, ImplSetUserValue und
+ // !!! ImplSetText ueberprueft und klarer gestalltet (mit Kommentar)
+ // !!! werden, damit wir mal wissen, was dort ablaeuft!!!
+
+ Selection aSelection = GetField()->GetSelection();
+ aSelection.Justify();
+ XubString aText = GetField()->GetText();
+ // Wenn bis ans Ende selektiert war, soll das auch so bleiben...
+ if ( (xub_StrLen)aSelection.Max() == aText.Len() )
+ {
+ if ( !aSelection.Len() )
+ aSelection.Min() = SELECTION_MAX;
+ aSelection.Max() = SELECTION_MAX;
+ }
+
+ long nOldLastValue = mnLastValue;
+ ImplSetUserValue( nNewValue, &aSelection );
+ mnLastValue = nOldLastValue;
+
+ // Modify am Edit wird nur bei KeyInput gesetzt...
+ if ( GetField()->GetText() != aText )
+ {
+ GetField()->SetModifyFlag();
+ GetField()->Modify();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+NumericField::NumericField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+NumericField::NumericField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_NUMERICFIELD )
+{
+ rResId.SetRT( RSC_NUMERICFIELD );
+ WinBits nStyle = ImplInitRes( rResId ) ;
+ SpinField::ImplInit( pParent, nStyle );
+ SetField( this );
+ ImplLoadRes( rResId );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::ImplLoadRes( const ResId& rResId )
+{
+ SpinField::ImplLoadRes( rResId );
+ NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+
+ USHORT nMask = ReadShortRes();
+
+ if ( NUMERICFIELD_FIRST & nMask )
+ mnFirst = ReadLongRes();
+
+ if ( NUMERICFIELD_LAST & nMask )
+ mnLast = ReadLongRes();
+
+ if ( NUMERICFIELD_SPINSIZE & nMask )
+ mnSpinSize = ReadLongRes();
+}
+
+// -----------------------------------------------------------------------
+
+NumericField::~NumericField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long NumericField::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), GetInternational() ) )
+ return 1;
+ }
+
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long NumericField::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SpinField::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_INTERNATIONAL) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::Up()
+{
+ FieldUp();
+ SpinField::Up();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::Down()
+{
+ FieldDown();
+ SpinField::Down();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::First()
+{
+ FieldFirst();
+ SpinField::First();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::Last()
+{
+ FieldLast();
+ SpinField::Last();
+}
+
+// -----------------------------------------------------------------------
+
+NumericBox::NumericBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+NumericBox::NumericBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_NUMERICBOX )
+{
+ rResId.SetRT( RSC_NUMERICBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ComboBox::ImplInit( pParent, nStyle );
+ SetField( this );
+ ComboBox::ImplLoadRes( rResId );
+ NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+NumericBox::~NumericBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long NumericBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), GetInternational() ) )
+ return 1;
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long NumericBox::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ComboBox::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_INTERNATIONAL) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::ReformatAll()
+{
+ double nValue;
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ ImplNumericReformat( GetEntry( i ), nValue, aStr );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ NumericFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::InsertValue( long nValue, USHORT nPos )
+{
+ ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::RemoveValue( long nValue )
+{
+ ComboBox::RemoveEntry( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+long NumericBox::GetValue( USHORT nPos ) const
+{
+ double nValue = 0;
+ ImplNumericGetValue( ComboBox::GetEntry( nPos ), nValue,
+ GetDecimalDigits(), GetInternational() );
+ return (long)nValue;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT NumericBox::GetValuePos( long nValue ) const
+{
+ return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplMetricProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
+ BOOL, const International& rInter )
+{
+ // Es gibt hier kein sinnvolles StrictFormat, also alle
+ // Zeichen erlauben
+ return ImplNumericProcessKeyInput( pEdit, rKEvt, FALSE, rInter );
+}
+
+// -----------------------------------------------------------------------
+
+static XubString ImplMetricGetUnitText( const XubString& rStr )
+{
+ // Einheitentext holen
+ XubString aStr;
+ for ( short i = rStr.Len()-1; i >= 0; i-- )
+ {
+ xub_Unicode c = rStr.GetChar( i );
+ if ( ((c >= 'A') && (c <= 'Z')) ||
+ ((c >= 'a') && (c <= 'z')) ||
+ (c == '\'') || (c == '\"') || (c == '%' ) )
+ aStr.Insert( c, 0 );
+ else
+ {
+ if ( aStr.Len() )
+ break;
+ }
+ }
+
+ return aStr;
+}
+
+// -----------------------------------------------------------------------
+
+static FieldUnit ImplMetricGetUnit( const XubString& rStr )
+{
+ XubString aStr = ImplMetricGetUnitText( rStr );
+ aStr.ToLowerAscii();
+
+ if ( aStr.EqualsAscii( "mm" ) ) // Milimeter
+ return FUNIT_MM;
+ else if ( aStr.EqualsAscii( "cm" ) ) // Centimeter
+ return FUNIT_CM;
+ else if ( aStr.EqualsAscii( "m" ) ) // Meter
+ return FUNIT_M;
+ else if ( aStr.EqualsAscii( "km" ) ) // Km
+ return FUNIT_KM;
+ else if ( aStr.EqualsAscii( "twip" ) ) // Twips
+ return FUNIT_TWIP;
+ else if ( aStr.EqualsAscii( "twips" ) ) // Twips
+ return FUNIT_TWIP;
+ else if ( aStr.EqualsAscii( "pt" ) ) // Point
+ return FUNIT_POINT;
+ else if ( aStr.EqualsAscii( "pi" ) ) // Pica
+ return FUNIT_PICA;
+ else if ( aStr.EqualsAscii( "\"" ) ) // Inch
+ return FUNIT_INCH;
+ else if ( aStr.EqualsAscii( "in" ) ) // Inch
+ return FUNIT_INCH;
+ else if ( aStr.EqualsAscii( "inch" ) ) // Inch
+ return FUNIT_INCH;
+ else if ( aStr.EqualsAscii( "'" ) ) // Foot
+ return FUNIT_FOOT;
+ else if ( aStr.EqualsAscii( "ft" ) ) // Foot
+ return FUNIT_FOOT;
+ else if ( aStr.EqualsAscii( "foot" ) ) // Foot
+ return FUNIT_FOOT;
+ else if ( aStr.EqualsAscii( "feet" ) ) // Foot
+ return FUNIT_FOOT;
+ else if ( aStr.EqualsAscii( "mile" ) ) // Mile
+ return FUNIT_MILE;
+ else if ( aStr.EqualsAscii( "miles" ) ) // Mile
+ return FUNIT_MILE;
+ else if ( aStr.EqualsAscii( "%" ) ) // Percent
+ return FUNIT_PERCENT;
+ else
+ return FUNIT_NONE;
+}
+
+#define K *1000L
+#define M *1000000L
+#define X *5280L
+
+static const long aImplFactor[FUNIT_MILE+1][FUNIT_MILE+1] =
+{ /*
+mm/100 mm cm m km twip point pica inch foot mile */
+{ 1, 100, 1 K, 100 K, 100 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X },
+{ 1, 1, 10, 1 K, 1 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X },
+{ 1, 1, 1, 100, 100 K, 254, 254, 254, 254, 254*12, 254*12 X },
+{ 1, 1, 1, 1, 1 K, 254, 254, 254, 254, 254*12, 254*12 X },
+{ 1, 1, 1, 1, 1, 0, 254, 254, 254, 254*12, 254*12 X },
+{ 1440,144 K,144 K,14400 K, 0, 1, 20, 240, 1440,1440*12,1440*12 X },
+{ 72, 7200, 7200, 720 K, 720 M, 1, 1, 12, 72, 72*12, 72*12 X },
+{ 6, 600, 600, 60 K, 60 M, 1, 1, 1, 6, 6*12, 6*12 X },
+{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 12, 12 X },
+{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 X },
+{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 }
+};
+
+#undef X
+#undef M
+#undef K
+// twip in km 254/14400 M
+
+static FieldUnit eDefaultUnit = FUNIT_NONE;
+
+FieldUnit MetricField::GetDefaultUnit() { return eDefaultUnit; }
+void MetricField::SetDefaultUnit( FieldUnit meUnit ) { eDefaultUnit = meUnit; }
+
+static FieldUnit ImplMap2FieldUnit( MapUnit meUnit, long& nDecDigits )
+{
+ switch( meUnit )
+ {
+ case MAP_100TH_MM :
+ nDecDigits -= 2;
+ return FUNIT_MM;
+ case MAP_10TH_MM :
+ nDecDigits -= 1;
+ return FUNIT_MM;
+ case MAP_MM :
+ return FUNIT_MM;
+ case MAP_CM :
+ return FUNIT_CM;
+ case MAP_1000TH_INCH :
+ nDecDigits -= 3;
+ return FUNIT_INCH;
+ case MAP_100TH_INCH :
+ nDecDigits -= 2;
+ return FUNIT_INCH;
+ case MAP_10TH_INCH :
+ nDecDigits -= 1;
+ return FUNIT_INCH;
+ case MAP_INCH :
+ return FUNIT_INCH;
+ case MAP_POINT :
+ return FUNIT_POINT;
+ case MAP_TWIP :
+ return FUNIT_TWIP;
+ default:
+ DBG_ERROR( "default eInUnit" );
+ break;
+ }
+ return FUNIT_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+long MetricField::ConvertValue( long nValue, long mnBaseValue, USHORT nDecDigits,
+ FieldUnit eInUnit, FieldUnit eOutUnit )
+{
+ return (long)ConvertDoubleValue( nValue, mnBaseValue, nDecDigits,
+ eInUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricField::ConvertValue( long nValue, USHORT nDigits,
+ MapUnit eInUnit, FieldUnit eOutUnit )
+{
+ return (long)ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricField::ConvertValue( long nValue, USHORT nDigits,
+ FieldUnit eInUnit, MapUnit eOutUnit )
+{
+ return (long)ConvertValue( nValue, nDigits, eInUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+double MetricField::ConvertDoubleValue( double nValue, long mnBaseValue, USHORT nDecDigits,
+ FieldUnit eInUnit, FieldUnit eOutUnit )
+{
+ if ( eInUnit != eOutUnit )
+ {
+ long nMult, nDiv;
+
+ if ( eInUnit == FUNIT_PERCENT )
+ {
+ if ( (mnBaseValue <= 0) || (nValue <= 0) )
+ return nValue;
+ nDiv = 100;
+ for ( USHORT i=0; i < nDecDigits; i++ )
+ nDiv *= 10;
+
+ nMult = mnBaseValue;
+ }
+ else if ( eOutUnit == FUNIT_PERCENT ||
+ eOutUnit == FUNIT_CUSTOM ||
+ eOutUnit == FUNIT_NONE ||
+ eInUnit == FUNIT_CUSTOM ||
+ eInUnit == FUNIT_NONE )
+ return nValue;
+ else
+ {
+ if ( eOutUnit == FUNIT_100TH_MM )
+ eOutUnit = FUNIT_NONE;
+ if ( eInUnit == FUNIT_100TH_MM )
+ eInUnit = FUNIT_NONE;
+
+ nDiv = aImplFactor[eInUnit][eOutUnit];
+ nMult = aImplFactor[eOutUnit][eInUnit];
+
+ DBG_ASSERT( nMult > 0, "illegal *" );
+ DBG_ASSERT( nDiv > 0, "illegal /" );
+ }
+
+ if ( nMult != 1 )
+ nValue *= nMult;
+ if ( nDiv != 1 )
+ {
+ nValue += ( nValue < 0 ) ? (-nDiv/2) : (nDiv/2);
+ nValue /= nDiv;
+ }
+ }
+
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+double MetricField::ConvertDoubleValue( double nValue, USHORT nDigits,
+ MapUnit eInUnit, FieldUnit eOutUnit )
+{
+ if ( eOutUnit == FUNIT_PERCENT ||
+ eOutUnit == FUNIT_CUSTOM ||
+ eOutUnit == FUNIT_NONE ||
+ eInUnit == MAP_PIXEL ||
+ eInUnit == MAP_SYSFONT ||
+ eInUnit == MAP_APPFONT ||
+ eInUnit == MAP_RELATIVE )
+ {
+ DBG_ERROR( "invalid parameters" );
+ return nValue;
+ }
+
+ long nDecDigits = nDigits;
+ FieldUnit eFieldUnit = ImplMap2FieldUnit( eInUnit, nDecDigits );
+
+ if ( (long)nDecDigits < 0 )
+ {
+ while ( nDecDigits )
+ {
+ nValue += 5;
+ nValue /= 10;
+ nDecDigits++;
+ }
+ }
+ else
+ {
+ while ( nDecDigits )
+ {
+ nValue *= 10;
+ nDecDigits--;
+ }
+ }
+
+ if ( eFieldUnit != eOutUnit )
+ {
+ long nDiv = aImplFactor[eFieldUnit][eOutUnit];
+ long nMult = aImplFactor[eOutUnit][eFieldUnit];
+
+ if ( nMult != 1 )
+ nValue *= nMult;
+ if ( nDiv != 1 )
+ {
+ nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
+ nValue /= nDiv;
+ }
+ }
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+double MetricField::ConvertDoubleValue( double nValue, USHORT nDigits,
+ FieldUnit eInUnit, MapUnit eOutUnit )
+{
+ if ( eInUnit == FUNIT_PERCENT ||
+ eInUnit == FUNIT_CUSTOM ||
+ eInUnit == FUNIT_NONE ||
+ eOutUnit == MAP_PIXEL ||
+ eOutUnit == MAP_SYSFONT ||
+ eOutUnit == MAP_APPFONT ||
+ eOutUnit == MAP_RELATIVE )
+ {
+ DBG_ERROR( "invalid parameters" );
+ return nValue;
+ }
+
+ long nDecDigits = nDigits;
+ FieldUnit eFieldUnit = ImplMap2FieldUnit( eOutUnit, nDecDigits );
+
+ if ( (long)nDecDigits < 0 )
+ {
+ while ( nDecDigits )
+ {
+ nValue *= 10;
+ nDecDigits++;
+ }
+ }
+ else
+ {
+ while ( nDecDigits )
+ {
+ nValue += 5;
+ nValue /= 10;
+ nDecDigits--;
+ }
+ }
+
+ if ( eFieldUnit != eInUnit )
+ {
+ long nDiv = aImplFactor[eInUnit][eFieldUnit];
+ long nMult = aImplFactor[eFieldUnit][eInUnit];
+
+ if( nMult != 1 )
+ nValue *= nMult;
+ if( nDiv != 1 )
+ {
+ nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
+ nValue /= nDiv;
+ }
+ }
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplMetricGetValue( const XubString& rStr, double& rValue, long nBaseValue,
+ USHORT nDecDigits,
+ const International& rInter, FieldUnit eUnit )
+{
+ // Zahlenwert holen
+ if ( !ImplNumericGetValue( rStr, rValue, nDecDigits, rInter ) )
+ return FALSE;
+
+ // Einheit rausfinden
+ FieldUnit eEntryUnit = ImplMetricGetUnit( rStr );
+
+ // Einheiten umrechnen
+ rValue = MetricField::ConvertDoubleValue( rValue, nBaseValue, nDecDigits, eEntryUnit, eUnit );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MetricFormatter::ImplMetricReformat( const XubString& rStr, double& rValue, XubString& rOutStr )
+{
+ if ( !ImplMetricGetValue( rStr, rValue, mnBaseValue, GetDecimalDigits(), GetInternational(), meUnit ) )
+ return TRUE;
+ else
+ {
+ double nTempVal = rValue;
+ if ( nTempVal > GetMax() )
+ nTempVal = GetMax();
+ else if ( nTempVal < GetMin())
+ nTempVal = GetMin();
+
+ if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
+ {
+ mnCorrectedValue = (long)nTempVal;
+ if ( !GetErrorHdl().Call( this ) )
+ {
+ mnCorrectedValue = 0;
+ return FALSE;
+ }
+ else
+ mnCorrectedValue = 0;
+ }
+
+ rOutStr = CreateFieldText( (long)nTempVal );
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline void MetricFormatter::ImplInit()
+{
+ mnBaseValue = 0;
+ meUnit = MetricField::GetDefaultUnit();
+ mnType = FORMAT_METRIC;
+}
+
+// -----------------------------------------------------------------------
+
+MetricFormatter::MetricFormatter()
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::ImplLoadRes( const ResId& rResId )
+{
+ NumericFormatter::ImplLoadRes( rResId );
+
+ ResMgr* pMgr = Resource::GetResManager();
+ USHORT nMask = pMgr->ReadShort();
+
+ if ( METRICFORMATTER_UNIT & nMask )
+ meUnit = (FieldUnit)pMgr->ReadShort();
+
+ if ( METRICFORMATTER_CUSTOMUNITTEXT & nMask )
+ maCustomUnitText = pMgr->ReadString();
+}
+
+// -----------------------------------------------------------------------
+
+MetricFormatter::~MetricFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetUnit( FieldUnit eNewUnit )
+{
+ if ( eNewUnit == FUNIT_100TH_MM )
+ {
+ SetDecimalDigits( GetDecimalDigits() + 2 );
+ meUnit = FUNIT_MM;
+ }
+ else
+ meUnit = eNewUnit;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetCustomUnitText( const XubString& rStr )
+{
+ maCustomUnitText = rStr;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetValue( long nNewValue, FieldUnit eInUnit )
+{
+ SetUserValue( nNewValue, eInUnit );
+ mnFieldValue = mnLastValue;
+}
+
+// -----------------------------------------------------------------------
+
+XubString MetricFormatter::CreateFieldText( long nValue ) const
+{
+ XubString aStr = NumericFormatter::CreateFieldText( nValue );
+
+ // Einheit dranhaengen
+ switch ( meUnit )
+ {
+ case FUNIT_MM:
+ aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "mm" ) );
+ break;
+ case FUNIT_CM:
+ aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "cm" ) );
+ break;
+ case FUNIT_M:
+ aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "m" ) );
+ break;
+ case FUNIT_KM:
+ aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "km" ) );
+ break;
+ case FUNIT_TWIP:
+ aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "twips" ) );
+ break;
+ case FUNIT_POINT:
+ aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "pt" ) );
+ break;
+ case FUNIT_PICA:
+ aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "pi" ) );
+ break;
+ case FUNIT_INCH:
+ aStr.Append( '"' );
+ break;
+ case FUNIT_FOOT:
+ aStr.Append( '\'' );
+ break;
+ case FUNIT_MILE:
+ aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "miles" ) );
+ break;
+ case FUNIT_CUSTOM:
+ aStr += maCustomUnitText;
+ break;
+ default:
+ break;
+ }
+
+ return aStr;
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetUserValue( long nNewValue, FieldUnit eInUnit )
+{
+ // Umrechnen auf eingestellte Einheiten
+ nNewValue = MetricField::ConvertValue( nNewValue, mnBaseValue, GetDecimalDigits(), eInUnit, meUnit );
+ NumericFormatter::SetUserValue( nNewValue );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricFormatter::GetValue( FieldUnit eOutUnit ) const
+{
+ if ( !GetField() )
+ return 0;
+
+ double nTempValue;
+ if ( !ImplMetricGetValue( GetField()->GetText(), nTempValue, mnBaseValue, GetDecimalDigits(),
+ GetInternational(), meUnit ) )
+ nTempValue = mnLastValue;
+
+ if ( nTempValue > mnMax )
+ nTempValue = mnMax;
+ else if ( nTempValue < mnMin )
+ nTempValue = mnMin;
+
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( (long)nTempValue, mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetMin( long nNewMin, FieldUnit eInUnit )
+{
+ // Umrechnen auf gewuenschte Einheiten
+ NumericFormatter::SetMin( MetricField::ConvertValue( nNewMin, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit ) );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricFormatter::GetMin( FieldUnit eOutUnit ) const
+{
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( NumericFormatter::GetMin(), mnBaseValue,
+ GetDecimalDigits(), meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetMax( long nNewMax, FieldUnit eInUnit )
+{
+ // Umrechnen auf gewuenschte Einheiten
+ NumericFormatter::SetMax( MetricField::ConvertValue( nNewMax, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit ) );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricFormatter::GetMax( FieldUnit eOutUnit ) const
+{
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( NumericFormatter::GetMax(), mnBaseValue,
+ GetDecimalDigits(), meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetBaseValue( long nNewBase, FieldUnit eInUnit )
+{
+ mnBaseValue = MetricField::ConvertValue( nNewBase, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricFormatter::GetBaseValue( FieldUnit eOutUnit ) const
+{
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( mnBaseValue, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::Reformat()
+{
+ if ( !GetField() )
+ return;
+
+ XubString aText = GetField()->GetText();
+ if ( meUnit == FUNIT_CUSTOM )
+ maCurUnitText = ImplMetricGetUnitText( aText );
+
+ XubString aStr;
+ double nTemp = mnLastValue;
+ BOOL bOK = ImplMetricReformat( aText, nTemp, aStr );
+ mnLastValue = (long)nTemp;
+
+ if ( !bOK )
+ return;
+
+ if ( aStr.Len() )
+ {
+ ImplSetText( aStr );
+ if ( meUnit == FUNIT_CUSTOM )
+ CustomConvert();
+ }
+ else
+ SetValue( mnLastValue );
+ maCurUnitText.Erase();
+}
+
+// -----------------------------------------------------------------------
+
+long MetricFormatter::GetCorrectedValue( FieldUnit eOutUnit ) const
+{
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( mnCorrectedValue, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+MetricField::MetricField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+MetricField::MetricField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_METRICFIELD )
+{
+ rResId.SetRT( RSC_METRICFIELD );
+ WinBits nStyle = ImplInitRes( rResId ) ;
+ SpinField::ImplInit( pParent, nStyle );
+ SetField( this );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::ImplLoadRes( const ResId& rResId )
+{
+ SpinField::ImplLoadRes( rResId );
+ MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+
+ USHORT nMask = ReadShortRes();
+
+ if ( METRICFIELD_FIRST & nMask )
+ mnFirst = ReadLongRes();
+
+ if ( METRICFIELD_LAST & nMask )
+ mnLast = ReadLongRes();
+
+ if ( METRICFIELD_SPINSIZE & nMask )
+ mnSpinSize = ReadLongRes();
+
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+MetricField::~MetricField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::SetFirst( long nNewFirst, FieldUnit eInUnit )
+{
+ // Umrechnen
+ nNewFirst = MetricField::ConvertValue( nNewFirst, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ mnFirst = nNewFirst;
+}
+
+// -----------------------------------------------------------------------
+
+long MetricField::GetFirst( FieldUnit eOutUnit ) const
+{
+ // Umrechnen
+ return MetricField::ConvertValue( mnFirst, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::SetLast( long nNewLast, FieldUnit eInUnit )
+{
+ // Umrechnen
+ nNewLast = MetricField::ConvertValue( nNewLast, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ mnLast = nNewLast;
+}
+
+// -----------------------------------------------------------------------
+
+long MetricField::GetLast( FieldUnit eOutUnit ) const
+{
+ // Umrechnen
+ return MetricField::ConvertValue( mnLast, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricField::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), GetInternational() ) )
+ return 1;
+ }
+
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricField::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SpinField::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_INTERNATIONAL) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::Up()
+{
+ FieldUp();
+ SpinField::Up();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::Down()
+{
+ FieldDown();
+ SpinField::Down();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::First()
+{
+ FieldFirst();
+ SpinField::First();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::Last()
+{
+ FieldLast();
+ SpinField::Last();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::CustomConvert()
+{
+ maCustomConvertLink.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+MetricBox::MetricBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+MetricBox::MetricBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_METRICBOX )
+{
+ rResId.SetRT( RSC_METRICBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ComboBox::ImplInit( pParent, nStyle );
+ SetField( this );
+ Reformat();
+ ComboBox::ImplLoadRes( rResId );
+ MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+MetricBox::~MetricBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long MetricBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), GetInternational() ) )
+ return 1;
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricBox::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ComboBox::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_INTERNATIONAL) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::ReformatAll()
+{
+ double nValue;
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ ImplMetricReformat( GetEntry( i ), nValue, aStr );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ MetricFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::CustomConvert()
+{
+ maCustomConvertLink.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::InsertValue( long nValue, FieldUnit eInUnit, USHORT nPos )
+{
+ // Umrechnen auf eingestellte Einheiten
+ nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::RemoveValue( long nValue, FieldUnit eInUnit )
+{
+ // Umrechnen auf eingestellte Einheiten
+ nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ ComboBox::RemoveEntry( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricBox::GetValue( USHORT nPos, FieldUnit eOutUnit ) const
+{
+ double nValue = 0;
+ ImplMetricGetValue( ComboBox::GetEntry( nPos ), nValue, mnBaseValue,
+ GetDecimalDigits(), GetInternational(), meUnit );
+
+ // Umrechnen auf eingestellte Einheiten
+ long nRetValue = MetricField::ConvertValue( (long)nValue, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+
+ return nRetValue;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT MetricBox::GetValuePos( long nValue, FieldUnit eInUnit ) const
+{
+ // Umrechnen auf eingestellte Einheiten
+ nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
+ BOOL, const International& rInter )
+{
+ // Es gibt hier kein sinnvolles StrictFormat, also alle
+ // Zeichen erlauben
+ return ImplNumericProcessKeyInput( pEdit, rKEvt, FALSE, rInter );
+}
+
+// -----------------------------------------------------------------------
+
+inline BOOL ImplCurrencyGetValue( const XubString& rStr, double& rValue,
+ USHORT nDecDigits, const International& rInter )
+{
+ // Zahlenwert holen
+ return ImplNumericGetValue( rStr, rValue, nDecDigits, rInter, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL CurrencyFormatter::ImplCurrencyReformat( const XubString& rStr,
+ XubString& rOutStr )
+{
+ double nValue;
+ if ( !ImplNumericGetValue( rStr, nValue, GetDecimalDigits(), GetInternational(), TRUE ) )
+ return TRUE;
+ else
+ {
+ double nTempVal = nValue;
+ if ( nTempVal > GetMax() )
+ nTempVal = GetMax();
+ else if ( nTempVal < GetMin())
+ nTempVal = GetMin();
+
+ if ( GetErrorHdl().IsSet() && (nValue != nTempVal) )
+ {
+ mnCorrectedValue = (long)nTempVal;
+ if ( !GetErrorHdl().Call( this ) )
+ {
+ mnCorrectedValue = 0;
+ return FALSE;
+ }
+ else
+ mnCorrectedValue = 0;
+ }
+
+ rOutStr = GetInternational().GetCurr( (long)nTempVal );
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline void CurrencyFormatter::ImplInit()
+{
+ mnType = FORMAT_CURRENCY;
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyFormatter::CurrencyFormatter()
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyFormatter::~CurrencyFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyFormatter::SetValue( long nNewValue )
+{
+ SetUserValue( nNewValue );
+ mnFieldValue = mnLastValue;
+ ImplGetEmptyFieldValue() = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString CurrencyFormatter::CreateFieldText( long nValue ) const
+{
+ return GetInternational().GetCurr( nValue, GetDecimalDigits() );
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyFormatter::GetValue() const
+{
+ if ( !GetField() )
+ return 0;
+
+ double nTempValue;
+ if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(),
+ GetInternational() ) )
+ {
+ if ( nTempValue > mnMax )
+ nTempValue = mnMax;
+ else if ( nTempValue < mnMin )
+ nTempValue = mnMin;
+ return (long)nTempValue;
+ }
+ else
+ return mnLastValue;
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyFormatter::Reformat()
+{
+ if ( !GetField() )
+ return;
+
+ XubString aStr;
+ BOOL bOK = ImplCurrencyReformat( GetField()->GetText(), aStr );
+ if ( !bOK )
+ return;
+
+ if ( aStr.Len() )
+ {
+ ImplSetText( aStr );
+ double nTemp = mnLastValue;
+ ImplCurrencyGetValue( aStr, nTemp, GetDecimalDigits(), GetInternational() );
+ mnLastValue = (long)nTemp;
+ }
+ else
+ SetValue( mnLastValue );
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyField::CurrencyField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyField::CurrencyField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_CURRENCYFIELD )
+{
+ rResId.SetRT( RSC_CURRENCYFIELD );
+ WinBits nStyle = ImplInitRes( rResId );
+ SpinField::ImplInit( pParent, nStyle);
+ SetField( this );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::ImplLoadRes( const ResId& rResId )
+{
+ SpinField::ImplLoadRes( rResId );
+ CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+
+ USHORT nMask = ReadShortRes();
+
+ if ( CURRENCYFIELD_FIRST & nMask )
+ mnFirst = ReadLongRes();
+
+ if ( CURRENCYFIELD_LAST & nMask )
+ mnLast = ReadLongRes();
+
+ if ( CURRENCYFIELD_SPINSIZE & nMask )
+ mnSpinSize = ReadLongRes();
+
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyField::~CurrencyField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyField::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), GetInternational() ) )
+ return 1;
+ }
+
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyField::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SpinField::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_INTERNATIONAL) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::Up()
+{
+ FieldUp();
+ SpinField::Up();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::Down()
+{
+ FieldDown();
+ SpinField::Down();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::First()
+{
+ FieldFirst();
+ SpinField::First();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::Last()
+{
+ FieldLast();
+ SpinField::Last();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyBox::CurrencyBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyBox::CurrencyBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_CURRENCYBOX )
+{
+ rResId.SetRT( RSC_CURRENCYBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ComboBox::ImplInit( pParent, nStyle );
+ CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ SetField( this );
+ ComboBox::ImplLoadRes( rResId );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyBox::~CurrencyBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), GetInternational() ) )
+ return 1;
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyBox::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ComboBox::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_INTERNATIONAL) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::ReformatAll()
+{
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ ImplCurrencyReformat( GetEntry( i ), aStr );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ CurrencyFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::InsertValue( long nValue, USHORT nPos )
+{
+ ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::RemoveValue( long nValue )
+{
+ ComboBox::RemoveEntry( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyBox::GetValue( USHORT nPos ) const
+{
+ double nValue = 0;
+ ImplCurrencyGetValue( ComboBox::GetEntry( nPos ), nValue,
+ GetDecimalDigits(), GetInternational() );
+ return (long)nValue;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT CurrencyBox::GetValuePos( long nValue ) const
+{
+ return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
+}
diff --git a/vcl/source/control/field2.cxx b/vcl/source/control/field2.cxx
new file mode 100644
index 000000000000..5a598c72e3cb
--- /dev/null
+++ b/vcl/source/control/field2.cxx
@@ -0,0 +1,3245 @@
+/*************************************************************************
+ *
+ * $RCSfile: field2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_FIELD2_CXX
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <field.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_SYSTEM_HXX
+#include <system.hxx>
+#endif
+#ifndef _SV_SOUND_HXX
+#include <sound.hxx>
+#endif
+#ifndef _SV_FIELD_HXX
+#include <field.hxx>
+#endif
+
+#ifndef _ISOLANG_HXX
+#include <tools/isolang.hxx>
+#endif
+
+#include <unohelp.hxx>
+
+#include <com/sun/star/lang/Locale.hpp>
+
+#ifndef _COM_SUN_STAR_LANG_XCHARACTERCLASSIFICATION_HPP_
+#include <com/sun/star/lang/XCharacterClassification.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_KCHARACTERTYPE_HPP_
+#include <com/sun/star/lang/KCharacterType.hpp>
+#endif
+
+#pragma hdrstop
+
+using namespace ::com::sun::star;
+
+// =======================================================================
+
+#define EDITMASK_LITERAL 'L'
+#define EDITMASK_ALPHA 'a'
+#define EDITMASK_UPPERALPHA 'A'
+#define EDITMASK_ALPHANUM 'c'
+#define EDITMASK_UPPERALPHANUM 'C'
+#define EDITMASK_NUM 'N'
+#define EDITMASK_NUMSPACE 'n'
+#define EDITMASK_ALLCHAR 'x'
+#define EDITMASK_UPPERALLCHAR 'X'
+
+
+
+const sal_Int32 nCharClassAlphaType =
+ ::com::sun::star::lang::KCharacterType::UPPER |
+ ::com::sun::star::lang::KCharacterType::LOWER |
+ ::com::sun::star::lang::KCharacterType::TITLE_CASE;
+
+const sal_Int32 nCharClassAlphaTypeMask =
+ nCharClassAlphaType |
+ ::com::sun::star::lang::KCharacterType::PRINTABLE |
+ ::com::sun::star::lang::KCharacterType::BASE_FORM;
+
+inline sal_Bool isAlphaType( sal_Int32 nType )
+{
+ return ((nType & nCharClassAlphaType) != 0) && (nType & ~(nCharClassAlphaTypeMask) == 0);
+}
+
+lang::Locale CreateLocale( const International& rInt )
+{
+ String aLanguage, aCountry;
+ ConvertLanguageToIsoNames( rInt.GetLanguage(), aLanguage, aCountry );
+ lang::Locale aLocale;
+ aLocale.Language = aLanguage;
+ aLocale.Country = aCountry;
+
+ return aLocale;
+}
+
+uno::Reference< lang::XCharacterClassification > ImplGetCharClass()
+{
+ static uno::Reference< lang::XCharacterClassification > xCharClass;
+ if ( !xCharClass.is() )
+ xCharClass = vcl::unohelper::CreateCharacterClassification();
+
+ return xCharClass;
+}
+
+
+// -----------------------------------------------------------------------
+
+static int ImplIsPatternChar( xub_Unicode cChar, sal_Char cEditMask )
+{
+ if ( (cEditMask == EDITMASK_ALPHA) || (cEditMask == EDITMASK_UPPERALPHA) )
+ {
+ if ( ((cChar < 'A') || (cChar > 'Z')) &&
+ ((cChar < 'a') || (cChar > 'z')) )
+ return FALSE;
+ }
+ else if ( (cEditMask == EDITMASK_ALPHANUM) || (cEditMask == EDITMASK_UPPERALPHANUM) )
+ {
+ if ( ((cChar < 'A') || (cChar > 'Z')) &&
+ ((cChar < 'a') || (cChar > 'z')) &&
+ ((cChar < '0') || (cChar > '9')) )
+ return FALSE;
+ }
+ else if ( (cEditMask == EDITMASK_ALLCHAR) || (cEditMask == EDITMASK_UPPERALLCHAR) )
+ {
+ if ( cChar < 32 )
+ return FALSE;
+ }
+ else if ( cEditMask == EDITMASK_NUM )
+ {
+ if ( (cChar < '0') || (cChar > '9') )
+ return FALSE;
+ }
+ else if ( cEditMask == EDITMASK_NUMSPACE )
+ {
+ if ( ((cChar < '0') || (cChar > '9')) && (cChar != ' ') )
+ return FALSE;
+ }
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+static xub_Unicode ImplPatternChar( xub_Unicode cChar, sal_Char cEditMask )
+{
+ if ( ImplIsPatternChar( cChar, cEditMask ) )
+ {
+ if ( (cEditMask == EDITMASK_UPPERALPHA) ||
+ (cEditMask == EDITMASK_UPPERALPHANUM) )
+ {
+ if ( (cChar >= 'a') && (cChar <= 'z') )
+ cChar = (cChar - 'a') + 'A';
+ }
+ else if ( cEditMask == EDITMASK_UPPERALLCHAR )
+ {
+ cChar = ImplGetCharClass()->toUpper( String(cChar),0,1,Application::GetSettings().GetLocale() )[0];
+ }
+
+ return cChar;
+ }
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplKommaPointCharEqual( xub_Unicode c1, xub_Unicode c2 )
+{
+ if ( c1 == c2 )
+ return TRUE;
+ else if ( ((c1 == '.') || (c1 == ',')) &&
+ ((c2 == '.') || (c2 == ',')) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static XubString ImplPatternReformat( const XubString& rStr,
+ const ByteString& rEditMask,
+ const XubString& rLiteralMask,
+ USHORT nFormatFlags )
+{
+ if ( !rEditMask.Len() )
+ return rStr;
+
+ XubString aStr = rStr;
+ XubString aOutStr = rLiteralMask;
+ xub_Unicode cTempChar;
+ xub_Unicode cChar;
+ xub_Unicode cLiteral;
+ sal_Char cMask;
+ xub_StrLen nStrIndex = 0;
+ xub_StrLen i = 0;
+ xub_StrLen n;
+
+ while ( i < rEditMask.Len() )
+ {
+ if ( nStrIndex >= aStr.Len() )
+ break;
+
+ cChar = aStr.GetChar(nStrIndex);
+ cLiteral = rLiteralMask.GetChar(i);
+ cMask = rEditMask.GetChar(i);
+
+ // Aktuelle Position ein Literal
+ if ( cMask == EDITMASK_LITERAL )
+ {
+ // Wenn es das Literal-Zeichen ist, uebernehmen, ansonsten
+ // ignorieren, da es das naechste gueltige Zeichen vom String
+ // sein kann
+ if ( ImplKommaPointCharEqual( cChar, cLiteral ) )
+ nStrIndex++;
+ else
+ {
+ // Ansonsten testen wir, ob es ein ungueltiges Zeichen ist.
+ // Dies ist dann der Fall, wenn es nicht in das Muster
+ // des naechsten nicht Literal-Zeichens passt
+ n = i+1;
+ while ( n < rEditMask.Len() )
+ {
+ if ( rEditMask.GetChar(n) != EDITMASK_LITERAL )
+ {
+ if ( !ImplIsPatternChar( cChar, rEditMask.GetChar(n) ) )
+ nStrIndex++;
+ break;
+ }
+
+ n++;
+ }
+ }
+ }
+ else
+ {
+ // Gueltiges Zeichen an der Stelle
+ cTempChar = ImplPatternChar( cChar, cMask );
+ if ( cTempChar )
+ {
+ // dann Zeichen uebernehmen
+ aOutStr.SetChar( i, cTempChar );
+ nStrIndex++;
+ }
+ else
+ {
+ // Wenn es das Literalzeichen ist, uebernehmen
+ if ( cLiteral == cChar )
+ nStrIndex++;
+ else
+ {
+ // Wenn das ungueltige Zeichen das naechste Literalzeichen
+ // sein kann, dann springen wir bis dahin vor, ansonten
+ // das Zeichen ignorieren
+ // Nur machen, wenn leere Literale erlaubt sind
+ if ( nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS )
+ {
+ n = i;
+ while ( n < rEditMask.Len() )
+ {
+ if ( rEditMask.GetChar( n ) == EDITMASK_LITERAL )
+ {
+ if ( ImplKommaPointCharEqual( cChar, rLiteralMask.GetChar( n ) ) )
+ i = n+1;
+
+ break;
+ }
+
+ n++;
+ }
+ }
+
+ nStrIndex++;
+ continue;
+ }
+ }
+ }
+
+ i++;
+ }
+
+ return aOutStr;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplPatternMaxPos( const XubString rStr, const ByteString& rEditMask,
+ USHORT nFormatFlags, BOOL bSameMask,
+ USHORT nCursorPos, USHORT& rPos )
+{
+
+ // Letzte Position darf nicht groesser als der enthaltene String sein
+ xub_StrLen nMaxPos = rStr.Len();
+
+ // Wenn keine leeren Literale erlaubt sind, auch Leerzeichen
+ // am Ende ignorieren
+ if ( bSameMask && !(nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS) )
+ {
+ while ( nMaxPos )
+ {
+ if ( (rEditMask.GetChar(nMaxPos-1) != EDITMASK_LITERAL) &&
+ (rStr.GetChar(nMaxPos-1) != ' ') )
+ break;
+ nMaxPos--;
+ }
+
+ // Wenn wir vor einem Literal stehen, dann solange weitersuchen,
+ // bis erste Stelle nach Literal
+ xub_StrLen nTempPos = nMaxPos;
+ while ( nTempPos < rEditMask.Len() )
+ {
+ if ( rEditMask.GetChar(nTempPos) != EDITMASK_LITERAL )
+ {
+ nMaxPos = nTempPos;
+ break;
+ }
+ nTempPos++;
+ }
+ }
+
+ if ( rPos > nMaxPos )
+ rPos = nMaxPos;
+ // Zeichen sollte nicht nach links wandern
+ if ( rPos < nCursorPos )
+ rPos = nCursorPos;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplPatternProcessStrictModify( Edit* pEdit,
+ const ByteString& rEditMask,
+ const XubString& rLiteralMask,
+ USHORT nFormatFlags, BOOL bSameMask )
+{
+ XubString aText = pEdit->GetText();
+
+ // Leerzeichen am Anfang entfernen
+ if ( bSameMask && !(nFormatFlags & PATTERN_FORMAT_EMPTYLITERALS) )
+ {
+ xub_StrLen i = 0;
+ xub_StrLen nMaxLen = aText.Len();
+ while ( i < nMaxLen )
+ {
+ if ( (rEditMask.GetChar( i ) != EDITMASK_LITERAL) &&
+ (aText.GetChar( i ) != ' ') )
+ break;
+
+ i++;
+ }
+ // Alle Literalzeichen beibehalten
+ while ( i && (rEditMask.GetChar( i ) == EDITMASK_LITERAL) )
+ i--;
+ aText.Erase( 0, i );
+ }
+
+ XubString aNewText = ImplPatternReformat( aText, rEditMask, rLiteralMask, nFormatFlags );
+ if ( aNewText != aText )
+ {
+ // Selection so anpassen, das diese wenn sie vorher am Ende
+ // stand, immer noch am Ende steht
+ Selection aSel = pEdit->GetSelection();
+ ULONG nMaxSel = Max( aSel.Min(), aSel.Max() );
+ if ( nMaxSel >= aText.Len() )
+ {
+ xub_StrLen nMaxPos = aNewText.Len();
+ ImplPatternMaxPos( aNewText, rEditMask, nFormatFlags, bSameMask, (xub_StrLen)nMaxSel, nMaxPos );
+ if ( aSel.Min() == aSel.Max() )
+ {
+ aSel.Min() = nMaxPos;
+ aSel.Max() = aSel.Min();
+ }
+ else if ( aSel.Min() > aSel.Max() )
+ aSel.Min() = nMaxPos;
+ else
+ aSel.Max() = nMaxPos;
+ }
+ pEdit->SetText( aNewText, aSel );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static xub_StrLen ImplPatternLeftPos( const ByteString& rEditMask, xub_StrLen nCursorPos )
+{
+ // Vorheriges Zeichen suchen, was kein Literal ist
+ xub_StrLen nNewPos = nCursorPos;
+ xub_StrLen nTempPos = nNewPos;
+ while ( nTempPos )
+ {
+ if ( rEditMask.GetChar(nTempPos-1) != EDITMASK_LITERAL )
+ {
+ nNewPos = nTempPos-1;
+ break;
+ }
+ nTempPos--;
+ }
+ return nNewPos;
+}
+
+// -----------------------------------------------------------------------
+
+static xub_StrLen ImplPatternRightPos( const XubString& rStr, const ByteString& rEditMask,
+ USHORT nFormatFlags, BOOL bSameMask,
+ xub_StrLen nCursorPos )
+{
+ // Naechstes Zeichen suchen, was kein Literal ist
+ xub_StrLen nNewPos = nCursorPos;
+ xub_StrLen nTempPos = nNewPos;
+ while ( nTempPos < rEditMask.Len() )
+ {
+ if ( rEditMask.GetChar(nTempPos+1) != EDITMASK_LITERAL )
+ {
+ nNewPos = nTempPos+1;
+ break;
+ }
+ nTempPos++;
+ }
+ ImplPatternMaxPos( rStr, rEditMask, nFormatFlags, bSameMask, nCursorPos, nNewPos );
+ return nNewPos;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplPatternProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
+ const ByteString& rEditMask,
+ const XubString& rLiteralMask,
+ BOOL bStrictFormat,
+ USHORT nFormatFlags,
+ BOOL bSameMask,
+ BOOL& rbInKeyInput )
+{
+ if ( !rEditMask.Len() || !bStrictFormat )
+ return FALSE;
+
+ Selection aOldSel = pEdit->GetSelection();
+ KeyCode aCode = rKEvt.GetKeyCode();
+ xub_Unicode cChar = rKEvt.GetCharCode();
+ USHORT nKeyCode = aCode.GetCode();
+ BOOL bShift = aCode.IsShift();
+ xub_StrLen nCursorPos = (xub_StrLen)aOldSel.Max();
+ xub_StrLen nNewPos;
+ xub_StrLen nTempPos;
+
+ if ( nKeyCode && !aCode.IsMod1() && !aCode.IsMod2() )
+ {
+ if ( nKeyCode == KEY_LEFT )
+ {
+ Selection aSel( ImplPatternLeftPos( rEditMask, nCursorPos ) );
+ if ( bShift )
+ aSel.Min() = aOldSel.Min();
+ pEdit->SetSelection( aSel );
+ return TRUE;
+ }
+ else if ( nKeyCode == KEY_RIGHT )
+ {
+ // Hier nehmen wir Selectionsanfang als minimum, da falls durch
+ // Focus alles selektiert ist, ist eine kleine Position schon
+ // erlaubt.
+ Selection aSel( aOldSel );
+ aSel.Justify();
+ nCursorPos = (xub_StrLen)aSel.Min();
+ aSel.Max() = ImplPatternRightPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nCursorPos );
+ if ( bShift )
+ aSel.Min() = aOldSel.Min();
+ else
+ aSel.Min() = aSel.Max();
+ pEdit->SetSelection( aSel );
+ return TRUE;
+ }
+ else if ( nKeyCode == KEY_HOME )
+ {
+ // Home ist Position des ersten nicht literalen Zeichens
+ nNewPos = 0;
+ while ( (nNewPos < rEditMask.Len()) &&
+ (rEditMask.GetChar(nNewPos) == EDITMASK_LITERAL) )
+ nNewPos++;
+ // Home sollte nicht nach rechts wandern
+ if ( nCursorPos < nNewPos )
+ nNewPos = nCursorPos;
+ Selection aSel( nNewPos );
+ if ( bShift )
+ aSel.Min() = aOldSel.Min();
+ pEdit->SetSelection( aSel );
+ return TRUE;
+ }
+ else if ( nKeyCode == KEY_END )
+ {
+ // End ist die Position des letzten nicht literalen Zeichens
+ nNewPos = rEditMask.Len();
+ while ( nNewPos &&
+ (rEditMask.GetChar(nNewPos-1) == EDITMASK_LITERAL) )
+ nNewPos--;
+ // Hier nehmen wir Selectionsanfang als minimum, da falls durch
+ // Focus alles selektiert ist, ist eine kleine Position schon
+ // erlaubt.
+ Selection aSel( aOldSel );
+ aSel.Justify();
+ nCursorPos = (xub_StrLen)aSel.Min();
+ ImplPatternMaxPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nCursorPos, nNewPos );
+ aSel.Max() = nNewPos;
+ if ( bShift )
+ aSel.Min() = aOldSel.Min();
+ else
+ aSel.Min() = aSel.Max();
+ pEdit->SetSelection( aSel );
+ return TRUE;
+ }
+ else if ( (nKeyCode == KEY_BACKSPACE) || (nKeyCode == KEY_DELETE) )
+ {
+ XubString aStr( pEdit->GetText() );
+ XubString aOldStr = aStr;
+ Selection aSel = aOldSel;
+
+ aSel.Justify();
+ nNewPos = (xub_StrLen)aSel.Min();
+
+ // Wenn Selection, dann diese Loeschen
+ if ( aSel.Len() )
+ {
+ if ( bSameMask )
+ aStr.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
+ else
+ {
+ XubString aRep = rLiteralMask.Copy( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
+ aStr.Replace( (xub_StrLen)aSel.Min(), aRep.Len(), aRep );
+ }
+ }
+ else
+ {
+ if ( nKeyCode == KEY_BACKSPACE )
+ {
+ nTempPos = nNewPos;
+ nNewPos = ImplPatternLeftPos( rEditMask, nTempPos );
+ }
+ else
+ nTempPos = ImplPatternRightPos( aStr, rEditMask, nFormatFlags, bSameMask, nNewPos );
+
+ if ( nNewPos != nTempPos )
+ {
+ if ( bSameMask )
+ {
+ if ( rEditMask.GetChar( nNewPos ) != EDITMASK_LITERAL )
+ aStr.Erase( nNewPos, 1 );
+ }
+ else
+ {
+ XubString aTempStr = rLiteralMask.Copy( nNewPos, 1 );
+ aStr.Replace( nNewPos, aTempStr.Len(), aTempStr );
+ }
+ }
+ }
+
+ if ( aOldStr != aStr )
+ {
+ if ( bSameMask )
+ aStr = ImplPatternReformat( aStr, rEditMask, rLiteralMask, nFormatFlags );
+ rbInKeyInput = TRUE;
+ pEdit->SetText( aStr, Selection( nNewPos ) );
+ pEdit->SetModifyFlag();
+ pEdit->Modify();
+ rbInKeyInput = FALSE;
+ }
+ else
+ pEdit->SetSelection( Selection( nNewPos ) );
+
+ return TRUE;
+ }
+ else if ( nKeyCode == KEY_INSERT )
+ {
+ // InsertModus kann man beim PatternField nur einstellen,
+ // wenn Maske an jeder Eingabeposition die gleiche
+ // ist
+ if ( !bSameMask )
+ {
+ Sound::Beep();
+ return TRUE;
+ }
+ }
+ }
+
+ if ( aCode.IsControlMod() || (cChar < 32) || (cChar == 127) )
+ return FALSE;
+
+ Selection aSel = aOldSel;
+ aSel.Justify();
+ nNewPos = (xub_StrLen)aSel.Min();
+
+ if ( nNewPos < rEditMask.Len() )
+ {
+ xub_Unicode cPattChar = ImplPatternChar( cChar, rEditMask.GetChar(nNewPos) );
+ if ( cPattChar )
+ cChar = cPattChar;
+ else
+ {
+ // Wenn kein gueltiges Zeichen, dann testen wir, ob der
+ // Anwender zum naechsten Literal springen wollte. Dies machen
+ // wir nur, wenn er hinter einem Zeichen steht, damit
+ // eingebene Literale die automatisch uebersprungenen wurden
+ // nicht dazu fuehren, das der Anwender dann da steht, wo
+ // er nicht stehen wollte.
+ if ( nNewPos &&
+ (rEditMask.GetChar(nNewPos-1) != EDITMASK_LITERAL) &&
+ !aSel.Len() )
+ {
+ // Naechstes Zeichen suchen, was kein Literal ist
+ nTempPos = nNewPos;
+ while ( nTempPos < rEditMask.Len() )
+ {
+ if ( rEditMask.GetChar(nTempPos) == EDITMASK_LITERAL )
+ {
+ // Gilt nur, wenn ein Literalzeichen vorhanden
+ if ( (rEditMask.GetChar(nTempPos+1) != EDITMASK_LITERAL ) &&
+ ImplKommaPointCharEqual( cChar, rLiteralMask.GetChar(nTempPos) ) )
+ {
+ nTempPos++;
+ ImplPatternMaxPos( pEdit->GetText(), rEditMask, nFormatFlags, bSameMask, nNewPos, nTempPos );
+ if ( nTempPos > nNewPos )
+ {
+ pEdit->SetSelection( Selection( nTempPos ) );
+ return TRUE;
+ }
+ }
+ break;
+ }
+ nTempPos++;
+ }
+ }
+
+ cChar = 0;
+ }
+ }
+ else
+ cChar = 0;
+ if ( cChar )
+ {
+ XubString aStr = pEdit->GetText();
+ BOOL bError = FALSE;
+ if ( bSameMask && pEdit->IsInsertMode() )
+ {
+ // Text um Spacezeichen und Literale am Ende kuerzen, bis zur
+ // aktuellen Position
+ xub_StrLen n = aStr.Len();
+ while ( n && (n > nNewPos) )
+ {
+ if ( (aStr.GetChar( n-1 ) != ' ') &&
+ ((n > rEditMask.Len()) || (rEditMask.GetChar(n-1) != EDITMASK_LITERAL)) )
+ break;
+
+ n--;
+ }
+ aStr.Erase( n );
+
+ if ( aSel.Len() )
+ aStr.Erase( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
+
+ if ( aStr.Len() < rEditMask.Len() )
+ {
+ // String evtl. noch bis Cursor-Position erweitern
+ if ( aStr.Len() < nNewPos )
+ aStr += rLiteralMask.Copy( aStr.Len(), nNewPos-aStr.Len() );
+ if ( nNewPos < aStr.Len() )
+ aStr.Insert( cChar, nNewPos );
+ else if ( nNewPos < rEditMask.Len() )
+ aStr += cChar;
+ aStr = ImplPatternReformat( aStr, rEditMask, rLiteralMask, nFormatFlags );
+ }
+ else
+ bError = TRUE;
+ }
+ else
+ {
+ if ( aSel.Len() )
+ {
+ // Selection loeschen
+ XubString aRep = rLiteralMask.Copy( (xub_StrLen)aSel.Min(), (xub_StrLen)aSel.Len() );
+ aStr.Replace( (xub_StrLen)aSel.Min(), aRep.Len(), aRep );
+ }
+
+ if ( nNewPos < aStr.Len() )
+ aStr.SetChar( nNewPos, cChar );
+ else if ( nNewPos < rEditMask.Len() )
+ aStr += cChar;
+ }
+
+ if ( bError )
+ Sound::Beep();
+ else
+ {
+ rbInKeyInput = TRUE;
+ Selection aNewSel( ImplPatternRightPos( aStr, rEditMask, nFormatFlags, bSameMask, nNewPos ) );
+ pEdit->SetText( aStr, aNewSel );
+ pEdit->SetModifyFlag();
+ pEdit->Modify();
+ rbInKeyInput = FALSE;
+ }
+ }
+ else
+ Sound::Beep();
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void PatternFormatter::ImplSetMask( const ByteString& rEditMask,
+ const XubString& rLiteralMask )
+{
+ maEditMask = rEditMask;
+ maLiteralMask = rLiteralMask;
+ mbSameMask = TRUE;
+
+ if ( maEditMask.Len() != maLiteralMask.Len() )
+ {
+ if ( maEditMask.Len() < maLiteralMask.Len() )
+ maLiteralMask.Erase( maEditMask.Len() );
+ else
+ maLiteralMask.Expand( maEditMask.Len(), ' ' );
+ }
+
+ // StrictModus erlaubt nur Input-Mode, wenn als Maske nur
+ // gleiche Zeichen zugelassen werden und als Vorgabe nur
+ // Spacezeichen vorgegeben werden, die durch die Maske
+ // nicht zugelassen sind
+ xub_StrLen i = 0;
+ sal_Char c = 0;
+ while ( i < rEditMask.Len() )
+ {
+ sal_Char cTemp = rEditMask.GetChar( i );
+ if ( cTemp != EDITMASK_LITERAL )
+ {
+ if ( (cTemp == EDITMASK_ALLCHAR) ||
+ (cTemp == EDITMASK_UPPERALLCHAR) ||
+ (cTemp == EDITMASK_NUMSPACE) )
+ {
+ mbSameMask = FALSE;
+ break;
+ }
+ if ( i < rLiteralMask.Len() )
+ {
+ if ( rLiteralMask.GetChar( i ) != ' ' )
+ {
+ mbSameMask = FALSE;
+ break;
+ }
+ }
+ if ( !c )
+ c = cTemp;
+ if ( cTemp != c )
+ {
+ mbSameMask = FALSE;
+ break;
+ }
+ }
+ i++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+PatternFormatter::PatternFormatter()
+{
+ mnFormatFlags = 0;
+ mbSameMask = TRUE;
+ mbInPattKeyInput = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void PatternFormatter::ImplLoadRes( const ResId& rResId )
+{
+ ByteString aEditMask;
+ XubString aLiteralMask;
+ ResMgr* pMgr = Resource::GetResManager();
+ USHORT nMask = pMgr->ReadShort();
+
+ if ( PATTERNFORMATTER_STRICTFORMAT & nMask )
+ SetStrictFormat( (BOOL)pMgr->ReadShort() );
+
+ if ( PATTERNFORMATTER_EDITMASK & nMask )
+ aEditMask = ByteString( pMgr->ReadString(), RTL_TEXTENCODING_ASCII_US );
+
+ if ( PATTERNFORMATTER_LITTERALMASK & nMask )
+ aLiteralMask = pMgr->ReadString();
+
+ if ( (PATTERNFORMATTER_EDITMASK | PATTERNFORMATTER_LITTERALMASK) & nMask )
+ ImplSetMask( aEditMask, aLiteralMask );
+}
+
+// -----------------------------------------------------------------------
+
+PatternFormatter::~PatternFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void PatternFormatter::SetMask( const ByteString& rEditMask,
+ const XubString& rLiteralMask )
+{
+ ImplSetMask( rEditMask, rLiteralMask );
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void PatternFormatter::SetString( const XubString& rStr )
+{
+ maFieldString = rStr;
+ if ( GetField() )
+ {
+ GetField()->SetText( rStr );
+ MarkToBeReformatted( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString PatternFormatter::GetString() const
+{
+ if ( !GetField() )
+ return ImplGetSVEmptyStr();
+ else
+ return ImplPatternReformat( GetField()->GetText(), maEditMask, maLiteralMask, mnFormatFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void PatternFormatter::Reformat()
+{
+ if ( GetField() )
+ {
+ ImplSetText( ImplPatternReformat( GetField()->GetText(), maEditMask, maLiteralMask, mnFormatFlags ) );
+ if ( !mbSameMask && IsStrictFormat() && !GetField()->IsReadOnly() )
+ GetField()->SetInsertMode( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void PatternFormatter::SelectFixedFont()
+{
+ if ( GetField() )
+ {
+ Font aFont = System::GetStandardFont( STDFONT_FIXED );
+ Font aControlFont;
+ aControlFont.SetName( aFont.GetName() );
+ aControlFont.SetFamily( aFont.GetFamily() );
+ aControlFont.SetPitch( aFont.GetPitch() );
+ GetField()->SetControlFont( aControlFont );
+ }
+}
+
+ // -----------------------------------------------------------------------
+
+PatternField::PatternField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+PatternField::PatternField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_PATTERNFIELD )
+{
+ rResId.SetRT( RSC_PATTERNFIELD );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ SetField( this );
+ SpinField::ImplLoadRes( rResId );
+ PatternFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+PatternField::~PatternField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long PatternField::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplPatternProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetEditMask(), GetLiteralMask(),
+ IsStrictFormat(), GetFormatFlags(),
+ ImplIsSameMask(), ImplGetInPattKeyInput() ) )
+ return 1;
+ }
+
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long PatternField::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void PatternField::Modify()
+{
+ if ( !ImplGetInPattKeyInput() )
+ {
+ if ( IsStrictFormat() )
+ ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() );
+ else
+ MarkToBeReformatted( TRUE );
+ }
+
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+PatternBox::PatternBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+PatternBox::PatternBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_PATTERNBOX )
+{
+ rResId.SetRT( RSC_PATTERNBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+
+ SetField( this );
+ ComboBox::ImplLoadRes( rResId );
+ PatternFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+PatternBox::~PatternBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long PatternBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplPatternProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), GetEditMask(), GetLiteralMask(),
+ IsStrictFormat(), GetFormatFlags(),
+ ImplIsSameMask(), ImplGetInPattKeyInput() ) )
+ return 1;
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long PatternBox::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void PatternBox::Modify()
+{
+ if ( !ImplGetInPattKeyInput() )
+ {
+ if ( IsStrictFormat() )
+ ImplPatternProcessStrictModify( GetField(), GetEditMask(), GetLiteralMask(), GetFormatFlags(), ImplIsSameMask() );
+ else
+ MarkToBeReformatted( TRUE );
+ }
+
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void PatternBox::ReformatAll()
+{
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ aStr = ImplPatternReformat( GetEntry( i ), GetEditMask(), GetLiteralMask(), GetFormatFlags() );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ PatternFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void PatternBox::InsertString( const XubString& rStr, USHORT nPos )
+{
+ ComboBox::InsertEntry( ImplPatternReformat( rStr, GetEditMask(), GetLiteralMask(), GetFormatFlags() ), nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void PatternBox::RemoveString( const XubString& rStr )
+{
+ ComboBox::RemoveEntry( ImplPatternReformat( rStr, GetEditMask(), GetLiteralMask(), GetFormatFlags() ) );
+}
+
+// -----------------------------------------------------------------------
+
+XubString PatternBox::GetString( USHORT nPos ) const
+{
+ return ImplPatternReformat( ComboBox::GetEntry( nPos ), GetEditMask(), GetLiteralMask(), GetFormatFlags() );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT PatternBox::GetStringPos( const XubString& rStr ) const
+{
+ return ComboBox::GetEntryPos( ImplPatternReformat( rStr, GetEditMask(), GetLiteralMask(), GetFormatFlags() ) );
+}
+
+// =======================================================================
+
+static BOOL ImplNeed4DigitYear( USHORT nYear, const AllSettings& rSettings )
+{
+ USHORT nTwoDigitYearStart = rSettings.GetMiscSettings().GetTwoDigitYearStart();
+
+ // Wenn Jahr nicht im 2stelligen Grenzbereich liegt,
+ if ( (nYear < nTwoDigitYearStart) || (nYear >= nTwoDigitYearStart+100) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplCutDayFromString( XubString& rStr, const International& )
+{
+ // Nach Zahl suchen
+ while ( rStr.Len() && !(rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') )
+ rStr.Erase( 0, 1 );
+ if ( !rStr.Len() )
+ return 0;
+ XubString aNumStr;
+ while ( rStr.Len() && (rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') )
+ {
+ aNumStr.Insert( rStr.GetChar( 0 ) );
+ rStr.Erase( 0, 1 );
+ }
+ return (USHORT)aNumStr.ToInt32();
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplCutMonthFromString( XubString& rStr, const International& rInter )
+{
+ USHORT nPos;
+
+ //Nach Monatsnamen suchen
+ for ( USHORT i=1; i <= 12; i++ )
+ {
+ const XubString& rMonthName = rInter.GetMonthText( i );
+ // Voller Monatsname ?
+ nPos = rStr.Search( rMonthName );
+ if ( nPos != STRING_NOTFOUND )
+ {
+ rStr.Erase( 0, nPos + rMonthName.Len() );
+ return i;
+ }
+ // Kurzer Monatsname ?
+ const XubString& rAbbrevMonthName = rInter.GetAbbrevMonthText( i );
+ nPos = rStr.Search( rAbbrevMonthName );
+ if ( nPos != STRING_NOTFOUND )
+ {
+ rStr.Erase( 0, nPos + rAbbrevMonthName.Len() );
+ return i;
+ }
+ }
+
+ // Nach Zahl suchen
+ while ( rStr.Len() && !(rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') )
+ rStr.Erase( 0, 1 );
+ if ( !rStr.Len() )
+ return 0;
+ XubString aNumStr;
+ while ( rStr.Len() && (rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') )
+ {
+ aNumStr.Insert( rStr.GetChar( 0 ) );
+ rStr.Erase( 0, 1 );
+ }
+ return (USHORT)aNumStr.ToInt32();
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplCutYearFromString( XubString& rStr, const International& )
+{
+ // Nach Zahl suchen
+ while ( rStr.Len() && !(rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') )
+ rStr.Erase( 0, 1 );
+ if ( !rStr.Len() )
+ return 0;
+ XubString aNumStr;
+ while ( rStr.Len() && (rStr.GetChar( 0 ) >= '0' && rStr.GetChar( 0 ) <= '9') )
+ {
+ aNumStr.Insert( rStr.GetChar( 0 ) );
+ aNumStr.Erase( 0, 1 );
+ }
+ return (USHORT)aNumStr.ToInt32();
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplDateProcessKeyInput( Edit*, const KeyEvent& rKEvt,
+ BOOL bStrictFormat, BOOL bLongFormat,
+ const International& rInter )
+{
+ xub_Unicode cChar = rKEvt.GetCharCode();
+
+ if ( !bStrictFormat || bLongFormat )
+ return FALSE;
+ else
+ {
+ USHORT nGroup = rKEvt.GetKeyCode().GetGroup();
+ if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
+ (nGroup == KEYGROUP_MISC)||
+ ((cChar >= '0') && (cChar <= '9')) ||
+ (cChar == rInter.GetDateSep()) )
+ return FALSE;
+ else
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplDateGetValue( const XubString& rStr, Date& rDate,
+ BOOL bLongFormat, const International& rInter,
+ const AllSettings& rSettings )
+{
+ XubString aStr = rStr;
+ BOOL bStrLongFormat = FALSE;
+ xub_StrLen nSep1Pos;
+ xub_StrLen nSep2Pos;
+ USHORT mnFirst;
+ USHORT nSecond;
+ USHORT nThird;
+ Date aDate( 0, 0, 0 );
+ DateFormat eDateFormat;
+
+ if ( !rStr.Len() )
+ return FALSE;
+
+ if ( bLongFormat )
+ eDateFormat = rInter.GetLongDateFormat();
+ else
+ eDateFormat = rInter.GetDateFormat();
+
+ // Sind da Buchstaben drin ?
+
+ bStrLongFormat = isAlphaType( ImplGetCharClass()->getStringType( aStr, 0, aStr.Len(), CreateLocale(rInter) ) );
+
+ // Bei enthaltenen Buchstaben gehen wir davon aus, das ein langes
+ // Datumsformat eingegeben wurde
+ if ( bStrLongFormat )
+ {
+ switch( eDateFormat )
+ {
+ case MDY:
+ mnFirst = ImplCutMonthFromString( aStr, rInter );
+ nSecond = ImplCutDayFromString( aStr, rInter );
+ nThird = ImplCutYearFromString( aStr, rInter );
+ break;
+ case DMY:
+ mnFirst = ImplCutDayFromString( aStr, rInter );
+ nSecond = ImplCutMonthFromString( aStr, rInter );
+ nThird = ImplCutYearFromString( aStr, rInter );
+ break;
+ case YMD:
+ default:
+ mnFirst = ImplCutYearFromString( aStr, rInter );
+ nSecond = ImplCutMonthFromString( aStr, rInter );
+ nThird = ImplCutDayFromString( aStr, rInter );
+ break;
+ }
+ }
+ else
+ {
+ // Nach Separatoren suchen
+ XubString aSepStr( RTL_CONSTASCII_USTRINGPARAM( ",.;:-/" ) );
+
+ // Die obigen Zeichen durch das Separatorzeichen ersetzen
+ for ( xub_StrLen i = 0; i < aSepStr.Len(); i++ )
+ {
+ if ( aSepStr.GetChar( i ) == rInter.GetDateSep() )
+ continue;
+ for ( xub_StrLen j = 0; j < aStr.Len(); j++ )
+ {
+ if ( aStr.GetChar( j ) == aSepStr.GetChar( i ) )
+ aStr.SetChar( j, rInter.GetDateSep() );
+ }
+ }
+
+ nSep1Pos = aStr.Search( rInter.GetDateSep() );
+ if ( nSep1Pos == STRING_NOTFOUND )
+ return FALSE;
+ nSep2Pos = aStr.Search( rInter.GetDateSep(), nSep1Pos+1 );
+
+ // Kein Jahr eingegeben ?
+ if ( nSep2Pos == STRING_NOTFOUND )
+ {
+ switch( eDateFormat )
+ {
+ case DMY:
+ case MDY:
+ nSep2Pos = aStr.Len();
+ aStr += rInter.GetDateSep();
+ aStr += aDate.GetYear();
+ break;
+ default:
+ case YMD:
+ {
+ nSep2Pos = nSep1Pos;
+ XubString aYearStr( aDate.GetYear() );
+ nSep2Pos = aYearStr.Len();
+ aStr.Insert( rInter.GetDateSep(), 0 );
+ aStr.Insert( aYearStr, 0 );
+ }
+ break;
+ }
+ }
+
+ mnFirst = (USHORT)aStr.Copy( 0, nSep1Pos ).ToInt32();
+ aStr.Erase( 0, nSep1Pos+1 );
+ nSecond = (USHORT)aStr.Copy( 0, nSep2Pos-nSep1Pos-1 ).ToInt32();
+ aStr.Erase( 0, nSep2Pos-nSep1Pos-1+1 );
+ nThird = (USHORT)aStr.ToInt32();
+ }
+
+ switch ( eDateFormat )
+ {
+ case MDY:
+ if ( !nSecond || !mnFirst )
+ return FALSE;
+ aDate = Date( nSecond, mnFirst, nThird );
+ break;
+ case DMY:
+ if ( !mnFirst || !nSecond )
+ return FALSE;
+ aDate = Date( mnFirst, nSecond, nThird );
+ break;
+ default:
+ case YMD:
+ if ( !nSecond || !nThird )
+ return FALSE;
+ aDate = Date( nThird, nSecond, mnFirst );
+ break;
+ }
+
+ DateFormatter::ExpandCentury( aDate, rSettings.GetMiscSettings().GetTwoDigitYearStart() );
+ if ( (aDate.GetDay() > 31) || (aDate.GetMonth() > 12) )
+ return FALSE;
+ if ( !aDate.IsValid() )
+ return FALSE;
+ rDate = aDate;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL DateFormatter::ImplDateReformat( const XubString& rStr, XubString& rOutStr,
+ const AllSettings& rSettings )
+{
+ Date aDate( 0, 0, 0 );
+ if ( !ImplDateGetValue( rStr, aDate, mbLongFormat, GetInternational(), GetFieldSettings() ) )
+ return TRUE;
+
+ Date aTempDate = aDate;
+ if ( aTempDate > GetMax() )
+ aTempDate = GetMax();
+ else if ( aTempDate < GetMin() )
+ aTempDate = GetMin();
+
+ if ( GetErrorHdl().IsSet() && (aDate != aTempDate) )
+ {
+ maCorrectedDate = aTempDate;
+ if( !GetErrorHdl().Call( this ) )
+ {
+ maCorrectedDate = Date();
+ return FALSE;
+ }
+ else
+ maCorrectedDate = Date();
+ }
+
+ rOutStr = ImplGetDateAsText( aTempDate, rSettings );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString DateFormatter::ImplGetDateAsText( const Date& rDate,
+ const AllSettings& rSettings ) const
+{
+ XubString aDateAsText;
+
+ International aIntn = GetInternational();
+ BOOL b4DigitYear = ImplNeed4DigitYear( rDate.GetYear(), rSettings );
+ if ( mbLongFormat )
+ {
+ if ( b4DigitYear && !aIntn.IsLongDateCentury() )
+ aIntn.SetLongDateCentury( TRUE );
+ aDateAsText = aIntn.GetLongDate( rDate );
+ }
+ else
+ {
+ if ( b4DigitYear && !aIntn.IsDateCentury() )
+ aIntn.SetDateCentury( TRUE );
+ aDateAsText = aIntn.GetDate( rDate );
+ }
+
+ return aDateAsText;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDateIncrementDay( Date& rDate, BOOL bUp )
+{
+ DateFormatter::ExpandCentury( rDate );
+
+ if ( bUp )
+ {
+ if ( (rDate.GetDay() != 31) || (rDate.GetMonth() != 12) || (rDate.GetYear() != 9999) )
+ rDate++;
+ }
+ else
+ {
+ if ( (rDate.GetDay() != 1 ) || (rDate.GetMonth() != 1) || (rDate.GetYear() != 0) )
+ rDate--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDateIncrementMonth( Date& rDate, BOOL bUp )
+{
+ DateFormatter::ExpandCentury( rDate );
+
+ USHORT nMonth = rDate.GetMonth();
+ USHORT nYear = rDate.GetYear();
+ if ( bUp )
+ {
+ if ( (nMonth == 12) && (nYear < 9999) )
+ {
+ rDate.SetMonth( 1 );
+ rDate.SetYear( nYear + 1 );
+ }
+ else
+ {
+ if ( nMonth < 12 )
+ rDate.SetMonth( nMonth + 1 );
+ }
+ }
+ else
+ {
+ if ( (nMonth == 1) && (nYear > 0) )
+ {
+ rDate.SetMonth( 12 );
+ rDate.SetYear( nYear - 1 );
+ }
+ else
+ {
+ if ( nMonth > 1 )
+ rDate.SetMonth( nMonth - 1 );
+ }
+ }
+
+ USHORT nDaysInMonth = rDate.GetDaysInMonth();
+ if ( rDate.GetDay() > nDaysInMonth )
+ rDate.SetDay( nDaysInMonth );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDateIncrementYear( Date& rDate, BOOL bUp )
+{
+ DateFormatter::ExpandCentury( rDate );
+
+ USHORT nYear = rDate.GetYear();
+ if ( bUp )
+ {
+ if ( nYear < 9999 )
+ rDate.SetYear( nYear + 1 );
+ }
+ else
+ {
+ if ( nYear > 0 )
+ rDate.SetYear( nYear - 1 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DateField::ImplDateSpinArea( BOOL bUp )
+{
+ // Wenn alles selektiert ist, Tage hochzaehlen
+ if ( GetField() )
+ {
+ Date aDate( GetDate() );
+ Selection aSelection = GetField()->GetSelection();
+ aSelection.Justify();
+ XubString aText( GetText() );
+ if ( (xub_StrLen)aSelection.Len() == aText.Len() )
+ ImplDateIncrementDay( aDate, bUp );
+ else
+ {
+ xub_StrLen nDateArea = 0;
+
+ DateFormat eFormat;
+ if ( IsLongFormat() )
+ eFormat = GetInternational().GetLongDateFormat();
+ else
+ eFormat = GetInternational().GetDateFormat();
+
+ if ( !IsLongFormat() )
+ {
+ // Area suchen
+ xub_StrLen nPos = 0;
+ for ( xub_StrLen i = 1; i <= 3; i++ )
+ {
+ nPos = aText.Search( GetInternational().GetDateSep(), nPos );
+ if ( nPos >= (USHORT)aSelection.Max() )
+ {
+ nDateArea = i;
+ break;
+ }
+ else
+ nPos++;
+ }
+ }
+ else
+ nDateArea = 1;
+
+ switch( eFormat )
+ {
+ case MDY:
+ switch( nDateArea )
+ {
+ case 1: ImplDateIncrementMonth( aDate, bUp );
+ break;
+ case 2: ImplDateIncrementDay( aDate, bUp );
+ break;
+ case 3: ImplDateIncrementYear( aDate, bUp );
+ break;
+ }
+ break;
+ case DMY:
+ switch( nDateArea )
+ {
+ case 1: ImplDateIncrementDay( aDate, bUp );
+ break;
+ case 2: ImplDateIncrementMonth( aDate, bUp );
+ break;
+ case 3: ImplDateIncrementYear( aDate, bUp );
+ break;
+ }
+ break;
+ case YMD:
+ switch( nDateArea )
+ {
+ case 1: ImplDateIncrementYear( aDate, bUp );
+ break;
+ case 2: ImplDateIncrementMonth( aDate, bUp );
+ break;
+ case 3: ImplDateIncrementDay( aDate, bUp );
+ break;
+ }
+ break;
+ }
+ }
+
+ ImplNewFieldValue( aDate );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::ImplInit()
+{
+ mbLongFormat = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+DateFormatter::DateFormatter() :
+ maMin( 1, 1, 1900 ),
+ maMax( 31, 12, 2200 ),
+ maFieldDate( 0 ),
+ maLastDate( 0 )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::ImplLoadRes( const ResId& )
+{
+ ResMgr* pMgr = Resource::GetResManager();
+ USHORT nMask = pMgr->ReadShort();
+
+ if ( DATEFORMATTER_MIN & nMask )
+ {
+ maMin = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) );
+ }
+ if ( DATEFORMATTER_MAX & nMask )
+ {
+ maMax = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) );
+ }
+ if ( DATEFORMATTER_LONGFORMAT & nMask )
+ mbLongFormat = (BOOL)pMgr->ReadShort();
+
+ if ( DATEFORMATTER_STRICTFORMAT & nMask )
+ SetStrictFormat( (BOOL)pMgr->ReadShort() );
+
+ if ( DATEFORMATTER_I12 & nMask )
+ {
+ SetInternational( International( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) ) );
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) );
+ }
+ if ( DATEFORMATTER_VALUE & nMask )
+ {
+ maFieldDate = Date( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE*)pMgr->GetClass() ) );
+ if ( maFieldDate > maMax )
+ maFieldDate = maMax;
+ if ( maFieldDate < maMin )
+ maFieldDate = maMin;
+ maLastDate = maFieldDate;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+DateFormatter::~DateFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::ReformatAll()
+{
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::SetMin( const Date& rNewMin )
+{
+ maMin = rNewMin;
+ if ( !IsEmptyFieldValue() )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::SetMax( const Date& rNewMax )
+{
+ maMax = rNewMax;
+ if ( !IsEmptyFieldValue() )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::SetLongFormat( BOOL bLong )
+{
+ mbLongFormat = bLong;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::SetDate( const Date& rNewDate )
+{
+ SetUserDate( rNewDate );
+ maFieldDate = maLastDate;
+ maLastDate = GetDate();
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::SetUserDate( const Date& rNewDate )
+{
+ ImplSetUserDate( rNewDate );
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::ImplSetUserDate( const Date& rNewDate, Selection* pNewSelection )
+{
+ Date aNewDate = rNewDate;
+ if ( aNewDate > maMax )
+ aNewDate = maMax;
+ else if ( aNewDate < maMin )
+ aNewDate = maMin;
+ maLastDate = aNewDate;
+
+ if ( GetField() )
+ ImplSetText( ImplGetDateAsText( aNewDate, GetFieldSettings() ), pNewSelection );
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::ImplNewFieldValue( const Date& rDate )
+{
+ if ( GetField() )
+ {
+ Selection aSelection = GetField()->GetSelection();
+ aSelection.Justify();
+ XubString aText = GetField()->GetText();
+ // Wenn bis ans Ende selektiert war, soll das auch so bleiben...
+ if ( (xub_StrLen)aSelection.Max() == aText.Len() )
+ {
+ if ( !aSelection.Len() )
+ aSelection.Min() = SELECTION_MAX;
+ aSelection.Max() = SELECTION_MAX;
+ }
+
+ Date aOldLastDate = maLastDate;
+ ImplSetUserDate( rDate, &aSelection );
+ maLastDate = aOldLastDate;
+
+ // Modify am Edit wird nur bei KeyInput gesetzt...
+ if ( GetField()->GetText() != aText )
+ {
+ GetField()->SetModifyFlag();
+ GetField()->Modify();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Date DateFormatter::GetDate() const
+{
+ Date aDate( 0, 0, 0 );
+
+ if ( GetField() )
+ {
+ if ( ImplDateGetValue( GetField()->GetText(), aDate,
+ mbLongFormat, GetInternational(),
+ GetFieldSettings() ) )
+ {
+ if ( aDate > maMax )
+ aDate = maMax;
+ else if ( aDate < maMin )
+ aDate = maMin;
+ }
+ else
+ {
+ // !!! TH-18.2.99: Wenn wir Zeit haben sollte einmal
+ // !!! geklaert werden, warum dieses beim Datum gegenueber
+ // !!! allen anderen Feldern anders behandelt wird.
+ // !!! Siehe dazu Bug: 52304
+
+ if ( maLastDate.GetDate() )
+ aDate = maLastDate;
+ else if ( !IsEmptyFieldValueEnabled() )
+ aDate = Date();
+ }
+ }
+
+ return aDate;
+}
+
+// -----------------------------------------------------------------------
+
+Date DateFormatter::GetRealDate() const
+{
+ // !!! TH-18.2.99: Wenn wir Zeit haben sollte dieses auch einmal
+ // !!! fuer die Numeric-Klassen eingebaut werden.
+
+ Date aDate( 0, 0, 0 );
+
+ if ( GetField() )
+ {
+ ImplDateGetValue( GetField()->GetText(), aDate,
+ mbLongFormat, GetInternational(),
+ GetFieldSettings() );
+ }
+
+ return aDate;
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::SetEmptyDate()
+{
+ FormatterBase::SetEmptyFieldValue();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL DateFormatter::IsEmptyDate() const
+{
+ BOOL bEmpty = FormatterBase::IsEmptyFieldValue();
+
+ if ( GetField() && MustBeReformatted() && IsEmptyFieldValueEnabled() )
+ {
+ if ( !GetField()->GetText().Len() )
+ {
+ bEmpty = TRUE;
+ }
+ else if ( !maLastDate.GetDate() )
+ {
+ Date aDate;
+ bEmpty = !ImplDateGetValue( GetField()->GetText(), aDate,
+ mbLongFormat, GetInternational(),
+ GetFieldSettings() );
+ }
+ }
+ return bEmpty;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL DateFormatter::IsDateModified() const
+{
+ if ( ImplGetEmptyFieldValue() )
+ return !IsEmptyDate();
+ else if ( GetDate() != maFieldDate )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::Reformat()
+{
+ if ( !GetField() )
+ return;
+
+ if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
+ return;
+
+ XubString aStr;
+ BOOL bOK = ImplDateReformat( GetField()->GetText(), aStr, GetFieldSettings() );
+ if( !bOK )
+ return;
+
+ if ( aStr.Len() )
+ {
+ ImplSetText( aStr );
+ ImplDateGetValue( aStr, maLastDate, mbLongFormat,
+ GetInternational(), GetFieldSettings() );
+ }
+ else
+ {
+ if ( maLastDate.GetDate() )
+ SetDate( maLastDate );
+ else if ( !IsEmptyFieldValueEnabled() )
+ SetDate( Date() );
+ else
+ {
+ ImplSetText( ImplGetSVEmptyStr() );
+ ImplGetEmptyFieldValue() = TRUE;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::ExpandCentury( Date& rDate )
+{
+ ExpandCentury( rDate, Application::GetSettings().GetMiscSettings().GetTwoDigitYearStart() );
+}
+
+// -----------------------------------------------------------------------
+
+void DateFormatter::ExpandCentury( Date& rDate, USHORT nTwoDigitYearStart )
+{
+ USHORT nDateYear = rDate.GetYear();
+ if ( nDateYear < 100 )
+ {
+ USHORT nCentury = nTwoDigitYearStart / 100;
+ if ( nDateYear < (nTwoDigitYearStart % 100) )
+ nCentury++;
+ rDate.SetYear( nDateYear + (nCentury*100) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+DateField::DateField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle ),
+ maFirst( GetMin() ),
+ maLast( GetMax() )
+{
+ SetField( this );
+ SetText( GetInternational().GetDate( ImplGetFieldDate() ) );
+ Reformat();
+ ResetLastDate();
+}
+
+// -----------------------------------------------------------------------
+
+DateField::DateField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_DATEFIELD ),
+ maFirst( GetMin() ),
+ maLast( GetMax() )
+{
+ rResId.SetRT( RSC_DATEFIELD );
+ WinBits nStyle = ImplInitRes( rResId );
+ SpinField::ImplInit( pParent, nStyle );
+ SetField( this );
+ SetText( GetInternational().GetDate( ImplGetFieldDate() ) );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+
+ ResetLastDate();
+}
+
+// -----------------------------------------------------------------------
+
+void DateField::ImplLoadRes( const ResId& rResId )
+{
+ SpinField::ImplLoadRes( rResId );
+ DateFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+
+ USHORT nMask = ReadShortRes();
+
+ if ( DATEFIELD_FIRST & nMask )
+ {
+ maFirst = Date( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
+ }
+ if ( DATEFIELD_LAST & nMask )
+ {
+ maLast = Date( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
+ }
+
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+DateField::~DateField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long DateField::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplDateProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsLongFormat(), GetInternational() ) )
+ return 1;
+ }
+
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long DateField::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() )
+ {
+ // !!! TH-18.2.99: Wenn wir Zeit haben sollte einmal
+ // !!! geklaert werden, warum dieses beim Datum gegenueber
+ // !!! allen anderen Feldern anders behandelt wird.
+ // !!! Siehe dazu Bug: 52304
+
+ BOOL bTextLen = GetText().Len() != 0;
+ if ( bTextLen || !IsEmptyFieldValueEnabled() )
+ Reformat();
+ else if ( !bTextLen && IsEmptyFieldValueEnabled() )
+ {
+ ResetLastDate();
+ ImplGetEmptyFieldValue() = TRUE;
+ }
+ }
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void DateField::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SpinField::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & (SETTINGS_INTERNATIONAL | SETTINGS_MISC)) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void DateField::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void DateField::Up()
+{
+ ImplDateSpinArea( TRUE );
+ SpinField::Up();
+}
+
+// -----------------------------------------------------------------------
+
+void DateField::Down()
+{
+ ImplDateSpinArea( FALSE );
+ SpinField::Down();
+}
+
+// -----------------------------------------------------------------------
+
+void DateField::First()
+{
+ ImplNewFieldValue( maFirst );
+ SpinField::First();
+}
+
+// -----------------------------------------------------------------------
+
+void DateField::Last()
+{
+ ImplNewFieldValue( maLast );
+ SpinField::Last();
+}
+
+// -----------------------------------------------------------------------
+
+void DateField::SetExtFormat( ExtDateFieldFormat eFormat )
+{
+ Date aDate = GetDate();
+ International aInt( Application::GetAppInternational() );
+
+ BOOL bLongFormat = FALSE; // immer bis auf XTDATEF_SYSTEM_LONG
+
+ switch ( eFormat )
+ {
+ case XTDATEF_SYSTEM_SHORT:
+ {
+ }
+ break;
+ case XTDATEF_SYSTEM_SHORT_YY:
+ {
+ aInt.SetDateCentury( FALSE );
+ }
+ break;
+ case XTDATEF_SYSTEM_SHORT_YYYY:
+ {
+ aInt.SetDateCentury( TRUE );
+ }
+ break;
+ case XTDATEF_SYSTEM_LONG:
+ {
+ bLongFormat = TRUE;
+ }
+ break;
+ case XTDATEF_SHORT_DDMMYY:
+ {
+ aInt.SetDateCentury( FALSE );
+ aInt.SetDateFormat( DMY );
+ }
+ break;
+ case XTDATEF_SHORT_MMDDYY:
+ {
+ aInt.SetDateCentury( FALSE );
+ aInt.SetDateFormat( MDY );
+ }
+ break;
+ case XTDATEF_SHORT_YYMMDD:
+ {
+ aInt.SetDateCentury( FALSE );
+ aInt.SetDateFormat( YMD );
+ }
+ break;
+ case XTDATEF_SHORT_DDMMYYYY:
+ {
+ aInt.SetDateCentury( TRUE );
+ aInt.SetDateFormat( DMY );
+ }
+ break;
+ case XTDATEF_SHORT_MMDDYYYY:
+ {
+ aInt.SetDateCentury( TRUE );
+ aInt.SetDateFormat( MDY );
+ }
+ break;
+ case XTDATEF_SHORT_YYYYMMDD:
+ {
+ aInt.SetDateCentury( TRUE );
+ aInt.SetDateFormat( YMD );
+ }
+ break;
+ case XTDATEF_SHORT_YYMMDD_DIN5008:
+ {
+ aInt.SetDateCentury( FALSE );
+ aInt.SetDateSep( '-' );
+ aInt.SetDateFormat( YMD );
+ }
+ break;
+ case XTDATEF_SHORT_YYYYMMDD_DIN5008:
+ {
+ aInt.SetDateCentury( TRUE );
+ aInt.SetDateSep( '-' );
+ aInt.SetDateFormat( YMD );
+ }
+ break;
+ default: DBG_ERROR( "ExtDateFieldFormat unknown!" );
+ }
+
+ SetInternational( aInt );
+ SetLongFormat( bLongFormat );
+ if ( GetField() && GetField()->GetText().Len() )
+ SetUserDate( aDate );
+}
+
+// -----------------------------------------------------------------------
+
+DateBox::DateBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ SetText( GetInternational().GetDate( ImplGetFieldDate() ) );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+DateBox::DateBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_DATEBOX )
+{
+ rResId.SetRT( RSC_DATEBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ComboBox::ImplInit( pParent, nStyle );
+ SetField( this );
+ SetText( GetInternational().GetDate( ImplGetFieldDate() ) );
+ ComboBox::ImplLoadRes( rResId );
+ DateFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ Reformat();
+
+ if ( !( nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+DateBox::~DateBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long DateBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplDateProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsLongFormat(), GetInternational() ) )
+ return 1;
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void DateBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ComboBox::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_INTERNATIONAL) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+long DateBox::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() )
+ {
+ BOOL bTextLen = GetText().Len() != 0;
+ if ( bTextLen || !IsEmptyFieldValueEnabled() )
+ Reformat();
+ else if ( !bTextLen && IsEmptyFieldValueEnabled() )
+ {
+ ResetLastDate();
+ ImplGetEmptyFieldValue() = TRUE;
+ }
+ }
+ }
+
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void DateBox::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void DateBox::ReformatAll()
+{
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ ImplDateReformat( GetEntry( i ), aStr, GetFieldSettings() );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ DateFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void DateBox::InsertDate( const Date& rDate, USHORT nPos )
+{
+ Date aDate = rDate;
+ if ( aDate > GetMax() )
+ aDate = GetMax();
+ else if ( aDate < GetMin() )
+ aDate = GetMin();
+
+ ComboBox::InsertEntry( ImplGetDateAsText( aDate, GetFieldSettings() ), nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void DateBox::RemoveDate( const Date& rDate )
+{
+ ComboBox::RemoveEntry( ImplGetDateAsText( rDate, GetFieldSettings() ) );
+}
+
+// -----------------------------------------------------------------------
+
+Date DateBox::GetDate( USHORT nPos ) const
+{
+ Date aDate( 0, 0, 0 );
+ ImplDateGetValue( ComboBox::GetEntry( nPos ), aDate, IsLongFormat(),
+ GetInternational(), GetSettings() );
+ return aDate;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT DateBox::GetDatePos( const Date& rDate ) const
+{
+ XubString aStr;
+ if ( IsLongFormat() )
+ aStr = GetInternational().GetLongDate( rDate );
+ else
+ aStr = GetInternational().GetDate( rDate );
+ return ComboBox::GetEntryPos( aStr );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplTimeProcessKeyInput( Edit*, const KeyEvent& rKEvt,
+ BOOL bStrictFormat, BOOL bDuration,
+ TimeFieldFormat eFormat,
+ const International& rInter )
+{
+ xub_Unicode cChar = rKEvt.GetCharCode();
+
+ if ( !bStrictFormat )
+ return FALSE;
+ else
+ {
+ USHORT nGroup = rKEvt.GetKeyCode().GetGroup();
+ if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
+ (nGroup == KEYGROUP_MISC) ||
+ ((cChar >= '0') && (cChar <= '9')) ||
+ (cChar == rInter.GetTimeSep()) ||
+ ((eFormat == TIMEF_100TH_SEC) && (cChar == rInter.GetTime100SecSep())) ||
+ ((eFormat == TIMEF_SEC_CS) && (cChar == rInter.GetTime100SecSep())) ||
+ (bDuration && (cChar == '-')) )
+ return FALSE;
+ else
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplTimeGetValue( const XubString& rStr, Time& rTime,
+ TimeFieldFormat eTimeFormat, BOOL bDuration,
+ const International& rInter )
+{
+ XubString aStr = rStr;
+ short nHour = 0;
+ short nMinute = 0;
+ short nSecond = 0;
+ short n100Sec = 0;
+ Time aTime( 0, 0, 0 );
+
+ if ( !rStr.Len() )
+ return FALSE;
+
+ // Nach Separatoren suchen
+ XubString aSepStr( RTL_CONSTASCII_USTRINGPARAM( ",.;:/" ) );
+ if ( !bDuration )
+ aSepStr.Append( '-' );
+
+ // Die obigen Zeichen durch das Separatorzeichen ersetzen
+ for ( xub_StrLen i = 0; i < aSepStr.Len(); i++ )
+ {
+ if ( aSepStr.GetChar( i ) == rInter.GetTimeSep() )
+ continue;
+ for ( xub_StrLen j = 0; j < aStr.Len(); j++ )
+ {
+ if ( aStr.GetChar( j ) == aSepStr.GetChar( i ) )
+ aStr.SetChar( j, rInter.GetTimeSep() );
+ }
+ }
+
+ BOOL bNegative = FALSE;
+ xub_StrLen nSepPos = aStr.Search( rInter.GetTimeSep() );
+ if ( aStr.GetChar( 0 ) == '-' )
+ bNegative = TRUE;
+ if ( eTimeFormat != TIMEF_SEC_CS )
+ {
+ if ( nSepPos == STRING_NOTFOUND )
+ return FALSE;
+ nHour = (short)aStr.Copy( 0, nSepPos ).ToInt32();
+ aStr.Erase( 0, nSepPos+1 );
+
+ nSepPos = aStr.Search( rInter.GetTimeSep() );
+ if ( aStr.GetChar( 0 ) == '-' )
+ bNegative = TRUE;
+ if ( nSepPos != STRING_NOTFOUND )
+ {
+ nMinute = (short)aStr.Copy( 0, nSepPos ).ToInt32();
+ aStr.Erase( 0, nSepPos+1 );
+
+ nSepPos = aStr.Search( rInter.GetTimeSep() );
+ if ( aStr.GetChar( 0 ) == '-' )
+ bNegative = TRUE;
+ if ( nSepPos != STRING_NOTFOUND )
+ {
+ nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32();
+ aStr.Erase( 0, nSepPos+1 );
+ if ( aStr.GetChar( 0 ) == '-' )
+ bNegative = TRUE;
+ n100Sec = (short)aStr.ToInt32();
+ }
+ else
+ nSecond = (short)aStr.ToInt32();
+ }
+ else
+ nMinute = (short)aStr.ToInt32();
+ }
+ else if ( nSepPos == STRING_NOTFOUND )
+ {
+ nSecond = (short)aStr.ToInt32();
+ nMinute += nSecond / 60;
+ nSecond %= 60;
+ nHour += nMinute / 60;
+ nMinute %= 60;
+ }
+ else
+ {
+ nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32();
+ aStr.Erase( 0, nSepPos+1 );
+
+ nSepPos = aStr.Search( rInter.GetTimeSep() );
+ if ( aStr.GetChar( 0 ) == '-' )
+ bNegative = TRUE;
+ if ( nSepPos != STRING_NOTFOUND )
+ {
+ nMinute = nSecond;
+ nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32();
+ aStr.Erase( 0, nSepPos+1 );
+
+ nSepPos = aStr.Search( rInter.GetTimeSep() );
+ if ( aStr.GetChar( 0 ) == '-' )
+ bNegative = TRUE;
+ if ( nSepPos != STRING_NOTFOUND )
+ {
+ nHour = nMinute;
+ nMinute = nSecond;
+ nSecond = (short)aStr.Copy( 0, nSepPos ).ToInt32();
+ aStr.Erase( 0, nSepPos+1 );
+ }
+ else
+ {
+ nHour += nMinute / 60;
+ nMinute %= 60;
+ }
+ }
+ else
+ {
+ nMinute += nSecond / 60;
+ nSecond %= 60;
+ nHour += nMinute / 60;
+ nMinute %= 60;
+ }
+ n100Sec = (short)aStr.ToInt32();
+
+ if ( n100Sec )
+ {
+ xub_StrLen nLen = 1; // mindestens eine Ziffer, weil sonst n100Sec==0
+
+ while ( aStr.GetChar(nLen) >= '0' && aStr.GetChar(nLen) <= '9' )
+ nLen++;
+
+ if ( nLen > 2 )
+ {
+ while( nLen > 3 )
+ {
+ n100Sec = n100Sec / 10;
+ nLen--;
+ }
+ // Rundung bei negativen Zahlen???
+ n100Sec = (n100Sec + 5) / 10;
+ }
+ else
+ {
+ while( nLen < 2 )
+ {
+ n100Sec = n100Sec * 10;
+ nLen++;
+ }
+ }
+ }
+ }
+
+ if ( (nMinute > 59) || (nSecond > 59) || (n100Sec > 100) )
+ return FALSE;
+
+ if ( eTimeFormat == TIMEF_NONE )
+ nSecond = n100Sec = 0;
+ else if ( eTimeFormat == TIMEF_SEC )
+ n100Sec = 0;
+
+ if ( !bDuration )
+ {
+ if ( bNegative || (nHour < 0) || (nMinute < 0) ||
+ (nSecond < 0) || (n100Sec < 0) )
+ return FALSE;
+
+ aStr.ToUpperAscii();
+ XubString aAM( rInter.GetTimeAM() );
+ XubString aPM( rInter.GetTimePM() );
+ aAM.ToUpperAscii();
+ aPM.ToUpperAscii();
+
+ if ( (aStr.Search( aPM ) != STRING_NOTFOUND) && (nHour < 12) )
+ nHour += 12;
+ if ( (aStr.Search( aAM ) != STRING_NOTFOUND) && (nHour == 12) )
+ nHour = 0;
+
+ aTime = Time( (USHORT)nHour, (USHORT)nMinute, (USHORT)nSecond,
+ (USHORT)n100Sec );
+ }
+ else
+ {
+ if ( bNegative || (nHour < 0) || (nMinute < 0) ||
+ (nSecond < 0) || (n100Sec < 0) )
+ {
+ bNegative = TRUE;
+ nHour = nHour < 0 ? -nHour : nHour;
+ nMinute = nMinute < 0 ? -nMinute : nMinute;
+ nSecond = nSecond < 0 ? -nSecond : nSecond;
+ n100Sec = n100Sec < 0 ? -n100Sec : n100Sec;
+ }
+
+ aTime = Time( (USHORT)nHour, (USHORT)nMinute, (USHORT)nSecond,
+ (USHORT)n100Sec );
+ if ( bNegative )
+ aTime = -aTime;
+ }
+
+ rTime = aTime;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TimeFormatter::ImplTimeReformat( const XubString& rStr, XubString& rOutStr )
+{
+ Time aTime( 0, 0, 0 );
+ if ( !ImplTimeGetValue( rStr, aTime, meFormat, mbDuration, GetInternational() ) )
+ return TRUE;
+
+ Time aTempTime = aTime;
+ if ( aTempTime > GetMax() )
+ aTempTime = GetMax() ;
+ else if ( aTempTime < GetMin() )
+ aTempTime = GetMin();
+
+ if ( GetErrorHdl().IsSet() && (aTime != aTempTime) )
+ {
+ maCorrectedTime = aTempTime;
+ if ( !GetErrorHdl().Call( this ) )
+ {
+ maCorrectedTime = Time();
+ return FALSE;
+ }
+ else
+ maCorrectedTime = Time();
+ }
+
+ BOOL bSecond = FALSE;
+ BOOL b100Sec = FALSE;
+ if ( meFormat != TIMEF_NONE )
+ bSecond = TRUE;
+ if ( meFormat == TIMEF_100TH_SEC )
+ b100Sec = TRUE;
+
+ if ( meFormat == TIMEF_SEC_CS )
+ {
+ ULONG n = aTempTime.GetHour() * 3600L;
+ n += aTempTime.GetMin() * 60L;
+ n += aTempTime.GetSec();
+ rOutStr = String::CreateFromInt32( n );
+ rOutStr += GetInternational().GetTime100SecSep();
+ if ( aTempTime.Get100Sec() < 10 )
+ rOutStr += '0';
+ rOutStr += String::CreateFromInt32( aTempTime.Get100Sec() );
+ }
+ else if ( mbDuration )
+ rOutStr = GetInternational().GetDuration( aTempTime, bSecond, b100Sec );
+ else
+ rOutStr = GetInternational().GetTime( aTempTime, bSecond, b100Sec );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void TimeField::ImplTimeSpinArea( BOOL bUp )
+{
+ if ( GetField() )
+ {
+ xub_StrLen nTimeArea = 0;
+ xub_StrLen nPos;
+
+ Time aTime( GetTime() );
+ XubString aText( GetText() );
+ Selection aSelection( GetField()->GetSelection() );
+
+ // Area suchen
+ if ( meFormat != TIMEF_SEC_CS )
+ {
+ for ( xub_StrLen i = 1, nPos = 0; i <= 4; i++ )
+ {
+ xub_StrLen nPos1 = aText.Search( GetInternational().GetTimeSep(), nPos );
+ xub_StrLen nPos2 = aText.Search( GetInternational().GetTime100SecSep(), nPos );
+ nPos = nPos1 < nPos2 ? nPos1 : nPos2;
+ if ( nPos >= (xub_StrLen)aSelection.Max() )
+ {
+ nTimeArea = i;
+ break;
+ }
+ else
+ nPos++;
+ }
+ }
+ else
+ {
+ nPos = aText.Search( GetInternational().GetTime100SecSep() );
+ if ( nPos == STRING_NOTFOUND || nPos >= (xub_StrLen)aSelection.Max() )
+ nTimeArea = 3;
+ else
+ nTimeArea = 4;
+ }
+
+ if ( nTimeArea )
+ {
+ Time aAddTime( 0, 0, 0 );
+ if ( nTimeArea == 1 )
+ aAddTime = Time( 1, 0 );
+ else if ( nTimeArea == 2 )
+ aAddTime = Time( 0, 1 );
+ else if ( nTimeArea == 3 )
+ aAddTime = Time( 0, 0, 1 );
+ else if ( nTimeArea == 4 )
+ aAddTime = Time( 0, 0, 0, 1 );
+
+ if ( !bUp )
+ aAddTime = -aAddTime;
+
+ aTime += aAddTime;
+ if ( !mbDuration )
+ {
+ Time aAbsMaxTime( 23, 59, 59, 99 );
+ if ( aTime > aAbsMaxTime )
+ aTime = aAbsMaxTime;
+ Time aAbsMinTime( 0, 0 );
+ if ( aTime < aAbsMinTime )
+ aTime = aAbsMinTime;
+ }
+ ImplNewFieldValue( aTime );
+ }
+
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::ImplInit()
+{
+ meFormat = TIMEF_NONE;
+ mbDuration = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+TimeFormatter::TimeFormatter() :
+ maMin( 0, 0 ),
+ maMax( 23, 59, 59, 99 ),
+ maFieldTime( 0, 0 ),
+ maLastTime( 0, 0 )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::ImplLoadRes( const ResId& )
+{
+ ResMgr* pMgr = Resource::GetResManager();
+ USHORT nMask = pMgr->ReadShort();
+
+ if ( TIMEFORMATTER_MIN & nMask )
+ {
+ SetMin( Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) ) );
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ }
+
+ if ( TIMEFORMATTER_MAX & nMask )
+ {
+ SetMax( Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) ) );
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ }
+
+ if ( TIMEFORMATTER_TIMEFIELDFORMAT & nMask )
+ meFormat = (TimeFieldFormat)pMgr->ReadShort();
+
+ if ( TIMEFORMATTER_DURATION & nMask )
+ mbDuration = (BOOL)pMgr->ReadShort();
+
+ if ( TIMEFORMATTER_STRICTFORMAT & nMask )
+ SetStrictFormat( (BOOL)pMgr->ReadShort() );
+
+ if ( TIMEFORMATTER_I12 & nMask )
+ {
+ SetInternational( International( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) ) );
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ }
+
+ if ( TIMEFORMATTER_VALUE & nMask )
+ {
+ maFieldTime = Time( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ if ( maFieldTime > GetMax() )
+ maFieldTime = GetMax();
+ if ( maFieldTime < GetMin() )
+ maFieldTime = GetMin();
+ maLastTime = maFieldTime;
+
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+TimeFormatter::~TimeFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::ReformatAll()
+{
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::SetMin( const Time& rNewMin )
+{
+ maMin = rNewMin;
+ if ( !IsEmptyFieldValue() )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::SetMax( const Time& rNewMax )
+{
+ maMax = rNewMax;
+ if ( !IsEmptyFieldValue() )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::SetFormat( TimeFieldFormat eNewFormat )
+{
+ meFormat = eNewFormat;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::SetDuration( BOOL bNewDuration )
+{
+ mbDuration = bNewDuration;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::SetTime( const Time& rNewTime )
+{
+ SetUserTime( rNewTime );
+ maFieldTime = maLastTime;
+ ImplGetEmptyFieldValue() = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::ImplNewFieldValue( const Time& rTime )
+{
+ if ( GetField() )
+ {
+ Selection aSelection = GetField()->GetSelection();
+ aSelection.Justify();
+ XubString aText = GetField()->GetText();
+ // Wenn bis ans Ende selektiert war, soll das auch so bleiben...
+ if ( (xub_StrLen)aSelection.Max() == aText.Len() )
+ {
+ if ( !aSelection.Len() )
+ aSelection.Min() = SELECTION_MAX;
+ aSelection.Max() = SELECTION_MAX;
+ }
+
+ Time aOldLastTime = maLastTime;
+ ImplSetUserTime( rTime, &aSelection );
+ maLastTime = aOldLastTime;
+
+ // Modify am Edit wird nur bei KeyInput gesetzt...
+ if ( GetField()->GetText() != aText )
+ {
+ GetField()->SetModifyFlag();
+ GetField()->Modify();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::ImplSetUserTime( const Time& rNewTime, Selection* pNewSelection )
+{
+ Time aNewTime = rNewTime;
+ if ( aNewTime > GetMax() )
+ aNewTime = GetMax();
+ else if ( aNewTime < GetMin() )
+ aNewTime = GetMin();
+ maLastTime = aNewTime;
+
+ if ( GetField() )
+ {
+ XubString aStr;
+ BOOL bSec = FALSE;
+ BOOL b100Sec = FALSE;
+ if ( meFormat != TIMEF_NONE )
+ bSec = TRUE;
+ if ( meFormat == TIMEF_100TH_SEC || meFormat == TIMEF_SEC_CS )
+ b100Sec = TRUE;
+ if ( meFormat == TIMEF_SEC_CS )
+ {
+ ULONG n = aNewTime.GetHour() * 3600L;
+ n += aNewTime.GetMin() * 60L;
+ n += aNewTime.GetSec();
+ aStr = String::CreateFromInt32( n );
+ aStr += GetInternational().GetTime100SecSep();
+ if ( aNewTime.Get100Sec() < 10 )
+ aStr += '0';
+ aStr += String::CreateFromInt32( aNewTime.Get100Sec() );
+ }
+ else if ( mbDuration )
+ aStr = GetInternational().GetDuration( aNewTime, bSec, b100Sec );
+ else
+ aStr = GetInternational().GetTime( aNewTime, bSec, b100Sec );
+
+ ImplSetText( aStr, pNewSelection );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::SetUserTime( const Time& rNewTime )
+{
+ ImplSetUserTime( rNewTime );
+}
+
+// -----------------------------------------------------------------------
+
+Time TimeFormatter::GetTime() const
+{
+ Time aTime( 0, 0, 0 );
+
+ if ( GetField() )
+ {
+ if ( ImplTimeGetValue( GetField()->GetText(), aTime,
+ meFormat, mbDuration, GetInternational() ) )
+ {
+ if ( aTime > GetMax() )
+ aTime = GetMax();
+ else if ( aTime < GetMin() )
+ aTime = GetMin();
+ }
+ else
+ aTime = maLastTime;
+ }
+
+ return aTime;
+}
+
+// -----------------------------------------------------------------------
+
+Time TimeFormatter::GetRealTime() const
+{
+ Time aTime( 0, 0, 0 );
+
+ if ( GetField() )
+ {
+ ImplTimeGetValue( GetField()->GetText(), aTime,
+ meFormat, mbDuration, GetInternational() );
+ }
+
+ return aTime;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TimeFormatter::IsTimeModified() const
+{
+ if ( ImplGetEmptyFieldValue() )
+ return !IsEmptyTime();
+ else if ( GetTime() != maFieldTime )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void TimeFormatter::Reformat()
+{
+ if ( !GetField() )
+ return;
+
+ if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
+ return;
+
+ XubString aStr;
+ BOOL bOK = ImplTimeReformat( GetField()->GetText(), aStr );
+ if ( !bOK )
+ return;
+
+ if ( aStr.Len() )
+ {
+ ImplSetText( aStr );
+ ImplTimeGetValue( aStr, maLastTime, meFormat, mbDuration, GetInternational() );
+ }
+ else
+ SetTime( maLastTime );
+}
+
+// -----------------------------------------------------------------------
+
+TimeField::TimeField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle ),
+ maFirst( GetMin() ),
+ maLast( GetMax() )
+{
+ SetField( this );
+ SetText( GetInternational().GetTime( maFieldTime, FALSE, FALSE ) );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+TimeField::TimeField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_TIMEFIELD ),
+ maFirst( GetMin() ),
+ maLast( GetMax() )
+{
+ rResId.SetRT( RSC_TIMEFIELD );
+ WinBits nStyle = ImplInitRes( rResId );
+ SpinField::ImplInit( pParent, nStyle );
+ SetField( this );
+ SetText( GetInternational().GetTime( maFieldTime, FALSE, FALSE ) );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeField::ImplLoadRes( const ResId& rResId )
+{
+ SpinField::ImplLoadRes( rResId );
+ TimeFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+
+ USHORT nMask = ReadShortRes();
+
+ if ( TIMEFIELD_FIRST & nMask )
+ {
+ maFirst = Time( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
+ }
+ if ( TIMEFIELD_LAST & nMask )
+ {
+ maLast = Time( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
+ }
+
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+TimeField::~TimeField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long TimeField::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplTimeProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), mbDuration, meFormat, GetInternational() ) )
+ return 1;
+ }
+
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long TimeField::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TimeField::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SpinField::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_INTERNATIONAL) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeField::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeField::Up()
+{
+ ImplTimeSpinArea( TRUE );
+ SpinField::Up();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeField::Down()
+{
+ ImplTimeSpinArea( FALSE );
+ SpinField::Down();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeField::First()
+{
+ ImplNewFieldValue( maFirst );
+ SpinField::First();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeField::Last()
+{
+ ImplNewFieldValue( maLast );
+ SpinField::Last();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeField::SetExtFormat( ExtTimeFieldFormat eFormat )
+{
+ Time aTime = GetTime();
+ International aInt( Application::GetAppInternational() );
+
+ switch ( eFormat )
+ {
+ case EXTTIMEF_24H_SHORT:
+ {
+ aInt.SetTimeFormat( HOUR_24 );
+ SetDuration( FALSE );
+ SetFormat( TIMEF_NONE );
+ }
+ break;
+ case EXTTIMEF_24H_LONG:
+ {
+ aInt.SetTimeFormat( HOUR_24 );
+ SetDuration( FALSE );
+ SetFormat( TIMEF_SEC );
+ }
+ break;
+ case EXTTIMEF_12H_SHORT:
+ {
+ aInt.SetTimeFormat( HOUR_12 );
+ SetDuration( FALSE );
+ SetFormat( TIMEF_NONE );
+ }
+ break;
+ case EXTTIMEF_12H_LONG:
+ {
+ aInt.SetTimeFormat( HOUR_12 );
+ SetDuration( FALSE );
+ SetFormat( TIMEF_SEC );
+ }
+ break;
+ case EXTTIMEF_DURATION_SHORT:
+ {
+ SetDuration( TRUE );
+ SetFormat( TIMEF_NONE );
+ }
+ break;
+ case EXTTIMEF_DURATION_LONG:
+ {
+ SetDuration( TRUE );
+ SetFormat( TIMEF_SEC );
+ }
+ break;
+ default: DBG_ERROR( "ExtTimeFieldFormat unknown!" );
+ }
+
+ SetInternational( aInt );
+ if ( GetField() && GetField()->GetText().Len() )
+ SetUserTime( aTime );
+}
+
+// -----------------------------------------------------------------------
+
+TimeBox::TimeBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ SetText( GetInternational().GetTime( maFieldTime, FALSE, FALSE ) );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+TimeBox::TimeBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_TIMEBOX )
+{
+ rResId.SetRT( RSC_TIMEBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ComboBox::ImplInit( pParent, nStyle );
+ SetField( this );
+ SetText( GetInternational().GetTime( maFieldTime, FALSE, FALSE ) );
+ ComboBox::ImplLoadRes( rResId );
+ TimeFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+TimeBox::~TimeBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long TimeBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) &&
+ !rNEvt.GetKeyEvent()->GetKeyCode().IsControlMod() )
+ {
+ if ( ImplTimeProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), mbDuration, meFormat, GetInternational() ) )
+ return 1;
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long TimeBox::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TimeBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ComboBox::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_INTERNATIONAL) )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeBox::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void TimeBox::ReformatAll()
+{
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ ImplTimeReformat( GetEntry( i ), aStr );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ TimeFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void TimeBox::InsertTime( const Time& rTime, USHORT nPos )
+{
+ Time aTime = rTime;
+ if ( aTime > GetMax() )
+ aTime = GetMax();
+ else if ( aTime < GetMin() )
+ aTime = GetMin();
+
+ BOOL bSec = FALSE;
+ BOOL b100Sec = FALSE;
+ if ( meFormat == TIMEF_SEC )
+ bSec = TRUE;
+ if ( meFormat == TIMEF_100TH_SEC || meFormat == TIMEF_SEC_CS )
+ bSec = b100Sec = TRUE;
+ ComboBox::InsertEntry( GetInternational().GetTime( aTime, bSec, b100Sec ), nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void TimeBox::RemoveTime( const Time& rTime )
+{
+ BOOL bSec = FALSE;
+ BOOL b100Sec = FALSE;
+ if ( meFormat == TIMEF_SEC )
+ bSec = TRUE;
+ if ( meFormat == TIMEF_100TH_SEC || TIMEF_SEC_CS )
+ bSec = b100Sec = TRUE;
+ ComboBox::RemoveEntry( GetInternational().GetTime( rTime, bSec, b100Sec ) );
+}
+
+// -----------------------------------------------------------------------
+
+Time TimeBox::GetTime( USHORT nPos ) const
+{
+ Time aTime( 0, 0, 0 );
+ ImplTimeGetValue( ComboBox::GetEntry( nPos ), aTime,
+ meFormat, mbDuration, GetInternational() );
+ return aTime;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TimeBox::GetTimePos( const Time& rTime ) const
+{
+ BOOL bSec = FALSE;
+ BOOL b100Sec = FALSE;
+ if ( meFormat == TIMEF_SEC )
+ bSec = TRUE;
+ if ( meFormat == TIMEF_100TH_SEC || TIMEF_SEC_CS )
+ bSec = b100Sec = TRUE;
+ return ComboBox::GetEntryPos( GetInternational().GetTime( rTime, bSec, b100Sec ) );
+}
diff --git a/vcl/source/control/fixbrd.cxx b/vcl/source/control/fixbrd.cxx
new file mode 100644
index 000000000000..e7ca718c2537
--- /dev/null
+++ b/vcl/source/control/fixbrd.cxx
@@ -0,0 +1,255 @@
+/*************************************************************************
+ *
+ * $RCSfile: fixbrd.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_FIXBRD_CXX
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_FIXBRD_HXX
+#include <fixbrd.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+void FixedBorder::ImplInit( Window* pParent, WinBits nStyle )
+{
+ mnType = FIXEDBORDER_TYPE_DOUBLEOUT;
+ mbTransparent = TRUE;
+
+ nStyle = ImplInitStyle( nStyle );
+ Control::ImplInit( pParent, nStyle, NULL );
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+WinBits FixedBorder::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBorder::ImplInitSettings()
+{
+ Window* pParent = GetParent();
+ if ( (pParent->IsChildTransparentModeEnabled() ||
+ !(pParent->GetStyle() & WB_CLIPCHILDREN) ) &&
+ !IsControlBackground() && mbTransparent )
+ {
+ SetMouseTransparent( TRUE );
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ SetMouseTransparent( FALSE );
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+FixedBorder::FixedBorder( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_FIXEDBORDER )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+FixedBorder::FixedBorder( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_FIXEDBORDER )
+{
+ rResId.SetRT( RSC_CONTROL );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+FixedBorder::~FixedBorder()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBorder::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
+ const Point& rPos, const Size& rSize )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aRect( rPos, rSize );
+ USHORT nBorderStyle = mnType;
+
+ if ( (nDrawFlags & WINDOW_DRAW_MONO) ||
+ (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ nBorderStyle |= FRAME_DRAW_MONO;
+
+ DecorationView aDecoView( pDev );
+ aDecoView.DrawFrame( aRect, nBorderStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBorder::Paint( const Rectangle& rRect )
+{
+ ImplDraw( this, 0, Point(), GetOutputSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBorder::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+
+ pDev->Push();
+ pDev->SetMapMode();
+ ImplDraw( pDev, nFlags, aPos, aSize );
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBorder::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBorder::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( (nType == STATE_CHANGE_DATA) ||
+ (nType == STATE_CHANGE_UPDATEMODE) )
+ {
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBorder::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBorder::SetTransparent( BOOL bTransparent )
+{
+ if ( mbTransparent != bTransparent )
+ {
+ mbTransparent = bTransparent;
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBorder::SetBorderType( USHORT nType )
+{
+ if ( mnType != nType )
+ {
+ mnType = nType;
+ Invalidate();
+ }
+}
diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx
new file mode 100644
index 000000000000..54cab781ebe2
--- /dev/null
+++ b/vcl/source/control/fixed.cxx
@@ -0,0 +1,1051 @@
+/*************************************************************************
+ *
+ * $RCSfile: fixed.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_FIXED_CXX
+
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_FIXED_HXX
+#include <fixed.hxx>
+#endif
+
+#include <rc.h>
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define FIXEDLINE_BORDER 12
+#define FIXEDLINE_TEXT_BORDER 2
+
+#define FIXEDTEXT_VIEW_STYLE (WB_3DLOOK | \
+ WB_LEFT | WB_CENTER | WB_RIGHT | \
+ WB_TOP | WB_VCENTER | WB_BOTTOM | \
+ WB_WORDBREAK | WB_NOLABEL | \
+ WB_INFO | WB_PATHELLIPSIS)
+#define FIXEDLINE_VIEW_STYLE (WB_3DLOOK | WB_NOLABEL)
+#define FIXEDBITMAP_VIEW_STYLE (WB_3DLOOK | \
+ WB_LEFT | WB_CENTER | WB_RIGHT | \
+ WB_TOP | WB_VCENTER | WB_BOTTOM | \
+ WB_SCALE)
+#define FIXEDIMAGE_VIEW_STYLE (WB_3DLOOK | \
+ WB_LEFT | WB_CENTER | WB_RIGHT | \
+ WB_TOP | WB_VCENTER | WB_BOTTOM | \
+ WB_SCALE)
+
+// =======================================================================
+
+static Point ImplCalcPos( WinBits nStyle, const Point& rPos,
+ const Size& rObjSize, const Size& rWinSize )
+{
+ long nX;
+ long nY;
+
+ if ( nStyle & WB_LEFT )
+ nX = 0;
+ else if ( nStyle & WB_RIGHT )
+ nX = rWinSize.Width()-rObjSize.Width();
+ else
+ nX = (rWinSize.Width()-rObjSize.Width())/2;
+
+ if ( nStyle & WB_TOP )
+ nY = 0;
+ else if ( nStyle & WB_BOTTOM )
+ nX = rWinSize.Height()-rObjSize.Height();
+ else
+ nY = (rWinSize.Height()-rObjSize.Height())/2;
+
+ if ( nStyle & WB_TOPLEFTVISIBLE )
+ {
+ if ( nX < 0 )
+ nX = 0;
+ if ( nY < 0 )
+ nY = 0;
+ }
+
+ Point aPos( nX+rPos.X(), nY+rPos.Y() );
+ return aPos;
+}
+
+// =======================================================================
+
+void FixedText::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( nStyle );
+ Control::ImplInit( pParent, nStyle, NULL );
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits FixedText::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void FixedText::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont;
+ if ( GetStyle() & WB_INFO )
+ aFont = rStyleSettings.GetInfoFont();
+ else
+ aFont = rStyleSettings.GetLabelFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ {
+ if ( GetStyle() & WB_INFO )
+ aColor = rStyleSettings.GetInfoTextColor();
+ else
+ aColor = rStyleSettings.GetLabelTextColor();
+ }
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Window* pParent = GetParent();
+ if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+FixedText::FixedText( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_FIXEDTEXT )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+FixedText::FixedText( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_FIXEDTEXT )
+{
+ rResId.SetRT( RSC_TEXT );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT FixedText::ImplGetTextStyle( WinBits nWinStyle )
+{
+ USHORT nTextStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_MULTILINE | TEXT_DRAW_ENDELLIPSIS;
+
+ if ( nWinStyle & WB_RIGHT )
+ nTextStyle |= TEXT_DRAW_RIGHT;
+ else if ( nWinStyle & WB_CENTER )
+ nTextStyle |= TEXT_DRAW_CENTER;
+ else
+ nTextStyle |= TEXT_DRAW_LEFT;
+ if ( nWinStyle & WB_BOTTOM )
+ nTextStyle |= TEXT_DRAW_BOTTOM;
+ else if ( nWinStyle & WB_VCENTER )
+ nTextStyle |= TEXT_DRAW_VCENTER;
+ else
+ nTextStyle |= TEXT_DRAW_TOP;
+ if ( nWinStyle & WB_WORDBREAK )
+ nTextStyle |= TEXT_DRAW_WORDBREAK;
+ if ( nWinStyle & WB_NOLABEL )
+ nTextStyle &= ~TEXT_DRAW_MNEMONIC;
+
+ return nTextStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void FixedText::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
+ const Point& rPos, const Size& rSize )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ WinBits nWinStyle = GetStyle();
+ XubString aText( GetText() );
+ USHORT nTextStyle = FixedText::ImplGetTextStyle( nWinStyle );
+
+ if ( nWinStyle & WB_PATHELLIPSIS )
+ {
+ nTextStyle &= ~(TEXT_DRAW_ENDELLIPSIS | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK);
+ nTextStyle |= TEXT_DRAW_PATHELLIPSIS;
+ }
+ if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC )
+ {
+ if ( nTextStyle & TEXT_DRAW_MNEMONIC )
+ {
+ aText = GetNonMnemonicString( aText );
+ nTextStyle &= ~TEXT_DRAW_MNEMONIC;
+ }
+ }
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ }
+ if ( (nDrawFlags & WINDOW_DRAW_MONO) ||
+ (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ nTextStyle |= TEXT_DRAW_MONO;
+
+ pDev->DrawText( Rectangle( rPos, rSize ), aText, nTextStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void FixedText::Paint( const Rectangle& rRect )
+{
+ ImplDraw( this, 0, Point(), GetOutputSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+void FixedText::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Font aFont = GetDrawPixelFont( pDev );
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ if ( nFlags & WINDOW_DRAW_MONO )
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ else
+ pDev->SetTextColor( GetTextColor() );
+ pDev->SetTextFillColor();
+
+ // Border
+ if ( !(nFlags & WINDOW_DRAW_NOBORDER) && (GetStyle() & WB_BORDER) )
+ {
+ pDev->SetLineColor( Color( COL_BLACK ) );
+ pDev->SetFillColor();
+ pDev->DrawRect( Rectangle( aPos, aSize ) );
+ }
+
+ ImplDraw( pDev, nFlags, aPos, aSize );
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedText::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedText::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( (nType == STATE_CHANGE_ENABLE) ||
+ (nType == STATE_CHANGE_TEXT) ||
+ (nType == STATE_CHANGE_UPDATEMODE) )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ if ( (GetPrevStyle() & FIXEDTEXT_VIEW_STYLE) !=
+ (GetStyle() & FIXEDTEXT_VIEW_STYLE) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedText::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size FixedText::CalcMinimumSize( long nMaxWidth ) const
+{
+ USHORT nStyle = ImplGetTextStyle( GetStyle() );
+ if ( !( GetStyle() & WB_NOLABEL ) )
+ nStyle |= TEXT_DRAW_MNEMONIC;
+
+ Size aSize = GetTextRect( Rectangle( Point(), Size( (nMaxWidth ? nMaxWidth : 0x7fffffff)-FIXEDLINE_BORDER, 0x7fffffff ) ),
+ GetText(), nStyle ).GetSize();
+
+ // GetTextRect verkraftet keinen leeren String:
+ if ( aSize.Width() < 0 )
+ aSize.Width() = 0;
+ if ( aSize.Height() <= 0 )
+ aSize.Height() = GetTextHeight();
+
+ return CalcWindowSize( aSize );
+}
+
+
+// =======================================================================
+
+void FixedLine::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( nStyle );
+ Control::ImplInit( pParent, nStyle, NULL );
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits FixedLine::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void FixedLine::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetGroupFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetGroupTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Window* pParent = GetParent();
+ if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+FixedLine::FixedLine( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_FIXEDLINE )
+{
+ ImplInit( pParent, nStyle );
+ SetSizePixel( Size( 2, 2 ) );
+}
+
+// -----------------------------------------------------------------------
+
+FixedLine::FixedLine( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_FIXEDLINE )
+{
+ rResId.SetRT( RSC_FIXEDLINE );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedLine::Paint( const Rectangle& rRect )
+{
+ Size aOutSize = GetOutputSizePixel();
+ String aText = GetText();
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ WinBits nWinStyle = GetStyle();
+
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
+ SetLineColor( Color( COL_BLACK ) );
+ else
+ SetLineColor( rStyleSettings.GetShadowColor() );
+
+ if ( !aText.Len() || (nWinStyle & WB_VERT) )
+ {
+ long nX;
+ long nY;
+
+ if ( nWinStyle & WB_VERT )
+ {
+ nX = (aOutSize.Width()-1)/2;
+ DrawLine( Point( nX, 0 ), Point( nX, aOutSize.Height()-1 ) );
+ }
+ else
+ {
+ nY = (aOutSize.Height()-1)/2;
+ DrawLine( Point( 0, nY ), Point( aOutSize.Width()-1, nY ) );
+ }
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetLightColor() );
+ if ( nWinStyle & WB_VERT )
+ DrawLine( Point( nX+1, 0 ), Point( nX+1, aOutSize.Height()-1 ) );
+ else
+ DrawLine( Point( 0, nY+1 ), Point( aOutSize.Width()-1, nY+1 ) );
+ }
+ }
+ else
+ {
+ USHORT nStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER | TEXT_DRAW_ENDELLIPSIS;
+ Rectangle aRect( FIXEDLINE_BORDER, 0, aOutSize.Width()-FIXEDLINE_BORDER, aOutSize.Height() );
+
+ if ( !IsEnabled() )
+ nStyle |= TEXT_DRAW_DISABLE;
+ if ( GetStyle() & WB_NOLABEL )
+ nStyle &= ~TEXT_DRAW_MNEMONIC;
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
+ nStyle |= TEXT_DRAW_MONO;
+
+ aRect = GetTextRect( aRect, aText, nStyle );
+ long nTop = aRect.Top() + ((aRect.GetHeight()-1)/2);
+
+ DrawLine( Point( 0, nTop ), Point( aRect.Left()-FIXEDLINE_TEXT_BORDER, nTop ) );
+ DrawLine( Point( aRect.Right()+FIXEDLINE_TEXT_BORDER, nTop ), Point( aOutSize.Width()-1, nTop ) );
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( 0, nTop+1 ), Point( aRect.Left()-FIXEDLINE_TEXT_BORDER, nTop+1 ) );
+ DrawLine( Point( aRect.Right()+FIXEDLINE_TEXT_BORDER, nTop+1 ), Point( aOutSize.Width()-1, nTop+1 ) );
+ }
+
+ DrawText( aRect, aText, nStyle );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedLine::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FixedLine::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedLine::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( (nType == STATE_CHANGE_ENABLE) ||
+ (nType == STATE_CHANGE_TEXT) ||
+ (nType == STATE_CHANGE_UPDATEMODE) )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ if ( (GetPrevStyle() & FIXEDLINE_VIEW_STYLE) !=
+ (GetStyle() & FIXEDLINE_VIEW_STYLE) )
+ Invalidate();
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_STYLE) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedLine::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// =======================================================================
+
+void FixedBitmap::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( nStyle );
+ Control::ImplInit( pParent, nStyle, NULL );
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+WinBits FixedBitmap::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBitmap::ImplInitSettings()
+{
+ Window* pParent = GetParent();
+ if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBitmap::ImplLoadRes( const ResId& rResId )
+{
+ Control::ImplLoadRes( rResId );
+
+ USHORT nObjMask = ReadShortRes();
+
+ if ( RSC_FIXEDBITMAP_BITMAP & nObjMask )
+ {
+ maBitmap = Bitmap( ResId( (RSHEADER_TYPE*)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+FixedBitmap::FixedBitmap( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_FIXEDBITMAP )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+FixedBitmap::FixedBitmap( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_FIXEDBITMAP )
+{
+ rResId.SetRT( RSC_FIXEDBITMAP );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+FixedBitmap::~FixedBitmap()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBitmap::ImplDraw( OutputDevice* pDev, ULONG /* nDrawFlags */,
+ const Point& rPos, const Size& rSize )
+{
+ // Haben wir ueberhaupt eine Bitmap
+ if ( !(!maBitmap) )
+ {
+ if ( GetStyle() & WB_SCALE )
+ pDev->DrawBitmap( rPos, rSize, maBitmap );
+ else
+ {
+ Point aPos = ImplCalcPos( GetStyle(), rPos, maBitmap.GetSizePixel(), rSize );
+ pDev->DrawBitmap( aPos, maBitmap );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBitmap::Paint( const Rectangle& rRect )
+{
+ ImplDraw( this, 0, Point(), GetOutputSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBitmap::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Rectangle aRect( aPos, aSize );
+
+ pDev->Push();
+ pDev->SetMapMode();
+
+ // Border
+ if ( !(nFlags & WINDOW_DRAW_NOBORDER) && (GetStyle() & WB_BORDER) )
+ {
+ DecorationView aDecoView( pDev );
+ aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
+ }
+ pDev->IntersectClipRegion( aRect );
+ ImplDraw( pDev, nFlags, aRect.TopLeft(), aRect.GetSize() );
+
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBitmap::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBitmap::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( (nType == STATE_CHANGE_DATA) ||
+ (nType == STATE_CHANGE_UPDATEMODE) )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ if ( (GetPrevStyle() & FIXEDBITMAP_VIEW_STYLE) !=
+ (GetStyle() & FIXEDBITMAP_VIEW_STYLE) )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBitmap::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedBitmap::SetBitmap( const Bitmap& rBitmap )
+{
+ maBitmap = rBitmap;
+ StateChanged( STATE_CHANGE_DATA );
+}
+
+// =======================================================================
+
+void FixedImage::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( nStyle );
+ mbInUserDraw = FALSE;
+ Control::ImplInit( pParent, nStyle, NULL );
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+WinBits FixedImage::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::ImplInitSettings()
+{
+ Window* pParent = GetParent();
+ if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::ImplLoadRes( const ResId& rResId )
+{
+ Control::ImplLoadRes( rResId );
+
+ USHORT nObjMask = ReadShortRes();
+
+ if ( RSC_FIXEDIMAGE_IMAGE & nObjMask )
+ {
+ maImage = Image( ResId( (RSHEADER_TYPE*)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+FixedImage::FixedImage( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_FIXEDIMAGE )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+FixedImage::FixedImage( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_FIXEDIMAGE )
+{
+ rResId.SetRT( RSC_FIXEDIMAGE );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+FixedImage::~FixedImage()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
+ const Point& rPos, const Size& rSize )
+{
+ USHORT nStyle = 0;
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nStyle |= IMAGE_DRAW_DISABLE;
+ }
+
+ // Haben wir ueberhaupt ein Image
+ if ( !(!maImage) )
+ {
+ if ( GetStyle() & WB_SCALE )
+ pDev->DrawImage( rPos, rSize, maImage, nStyle );
+ else
+ {
+ Point aPos = ImplCalcPos( GetStyle(), rPos, maImage.GetSizePixel(), rSize );
+ pDev->DrawImage( aPos, maImage, nStyle );
+ }
+ }
+
+ mbInUserDraw = TRUE;
+ UserDrawEvent aUDEvt( pDev, Rectangle( rPos, rSize ), 0, nStyle );
+ UserDraw( aUDEvt );
+ mbInUserDraw = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::Paint( const Rectangle& rRect )
+{
+ ImplDraw( this, 0, Point(), GetOutputSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::UserDraw( const UserDrawEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Rectangle aRect( aPos, aSize );
+
+ pDev->Push();
+ pDev->SetMapMode();
+
+ // Border
+ if ( !(nFlags & WINDOW_DRAW_NOBORDER) && (GetStyle() & WB_BORDER) )
+ {
+ DecorationView aDecoView( pDev );
+ aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
+ }
+ pDev->IntersectClipRegion( aRect );
+ ImplDraw( pDev, nFlags, aRect.TopLeft(), aRect.GetSize() );
+
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( (nType == STATE_CHANGE_ENABLE) ||
+ (nType == STATE_CHANGE_DATA) ||
+ (nType == STATE_CHANGE_UPDATEMODE) )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ if ( (GetPrevStyle() & FIXEDIMAGE_VIEW_STYLE) !=
+ (GetStyle() & FIXEDIMAGE_VIEW_STYLE) )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FixedImage::SetImage( const Image& rImage )
+{
+ if ( rImage != maImage )
+ {
+ maImage = rImage;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Point FixedImage::CalcImagePos( const Point& rPos,
+ const Size& rObjSize, const Size& rWinSize )
+{
+ return ImplCalcPos( GetStyle(), rPos, rObjSize, rWinSize );
+}
diff --git a/vcl/source/control/group.cxx b/vcl/source/control/group.cxx
new file mode 100644
index 000000000000..2124a2cf6012
--- /dev/null
+++ b/vcl/source/control/group.cxx
@@ -0,0 +1,349 @@
+/*************************************************************************
+ *
+ * $RCSfile: group.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_GROUP_CXX
+
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_GROUP_HXX
+#include <group.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define GROUP_BORDER 12
+#define GROUP_TEXT_BORDER 2
+
+#define GROUP_VIEW_STYLE (WB_3DLOOK | WB_NOLABEL)
+
+// =======================================================================
+
+void GroupBox::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( nStyle );
+ Control::ImplInit( pParent, nStyle, NULL );
+ SetMouseTransparent( TRUE );
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits GroupBox::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void GroupBox::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetGroupFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetGroupTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Window* pParent = GetParent();
+ if ( (pParent->IsChildTransparentModeEnabled() ||
+ !(pParent->GetStyle() & WB_CLIPCHILDREN) ) &&
+ !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+GroupBox::GroupBox( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_GROUPBOX )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+GroupBox::GroupBox( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_GROUPBOX )
+{
+ rResId.SetRT( RSC_GROUPBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void GroupBox::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
+ const Point& rPos, const Size& rSize )
+{
+ long nTop;
+ long nTextOff;
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ XubString aText( GetText() );
+ Rectangle aRect( rPos, rSize );
+ USHORT nTextStyle = TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_ENDELLIPSIS | TEXT_DRAW_MNEMONIC;
+
+ if ( GetStyle() & WB_NOLABEL )
+ nTextStyle &= ~TEXT_DRAW_MNEMONIC;
+ if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC )
+ {
+ if ( nTextStyle & TEXT_DRAW_MNEMONIC )
+ {
+ aText = GetNonMnemonicString( aText );
+ nTextStyle &= ~TEXT_DRAW_MNEMONIC;
+ }
+ }
+ if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
+ {
+ if ( !IsEnabled() )
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ }
+ if ( (nDrawFlags & WINDOW_DRAW_MONO) ||
+ (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ nTextStyle |= TEXT_DRAW_MONO;
+ nDrawFlags |= WINDOW_DRAW_MONO;
+ }
+
+ if ( !aText.Len() )
+ {
+ nTop = rPos.Y();
+ nTextOff = 0;
+ }
+ else
+ {
+ aRect.Left() += GROUP_BORDER;
+ aRect.Right() -= GROUP_BORDER;
+ aRect = pDev->GetTextRect( aRect, aText, nTextStyle );
+ nTop = rPos.Y();
+ nTop += aRect.GetHeight() / 2;
+ nTextOff = GROUP_TEXT_BORDER;
+ }
+
+ if ( nDrawFlags & WINDOW_DRAW_MONO )
+ pDev->SetLineColor( Color( COL_BLACK ) );
+ else
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+
+ if ( !aText.Len() )
+ pDev->DrawLine( Point( rPos.X(), nTop ), Point( rPos.X()+rSize.Width()-2, nTop ) );
+ else
+ {
+ pDev->DrawLine( Point( rPos.X(), nTop ), Point( aRect.Left()-nTextOff, nTop ) );
+ pDev->DrawLine( Point( aRect.Right()+nTextOff, nTop ), Point( rPos.X()+rSize.Width()-2, nTop ) );
+ }
+ pDev->DrawLine( Point( rPos.X(), nTop ), Point( rPos.X(), rPos.Y()+rSize.Height()-2 ) );
+ pDev->DrawLine( Point( rPos.X(), rPos.Y()+rSize.Height()-2 ), Point( rPos.X()+rSize.Width()-2, rPos.Y()+rSize.Height()-2 ) );
+ pDev->DrawLine( Point( rPos.X()+rSize.Width()-2, rPos.Y()+rSize.Height()-2 ), Point( rPos.X()+rSize.Width()-2, nTop ) );
+
+ if ( !(nDrawFlags & WINDOW_DRAW_MONO) )
+ {
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ if ( !aText.Len() )
+ pDev->DrawLine( Point( rPos.X()+1, nTop+1 ), Point( rPos.X()+rSize.Width()-3, nTop+1 ) );
+ else
+ {
+ pDev->DrawLine( Point( rPos.X()+1, nTop+1 ), Point( aRect.Left()-nTextOff, nTop+1 ) );
+ pDev->DrawLine( Point( aRect.Right()+nTextOff, nTop+1 ), Point( rPos.X()+rSize.Width()-3, nTop+1 ) );
+ }
+ pDev->DrawLine( Point( rPos.X()+1, nTop+1 ), Point( rPos.X()+1, rPos.Y()+rSize.Height()-3 ) );
+ pDev->DrawLine( Point( rPos.X(), rPos.Y()+rSize.Height()-1 ), Point( rPos.X()+rSize.Width()-1, rPos.Y()+rSize.Height()-1 ) );
+ pDev->DrawLine( Point( rPos.X()+rSize.Width()-1, rPos.Y()+rSize.Height()-1 ), Point( rPos.X()+rSize.Width()-1, nTop ) );
+ }
+
+ pDev->DrawText( aRect, aText, nTextStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void GroupBox::Paint( const Rectangle& )
+{
+ ImplDraw( this, 0, Point(), GetOutputSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+void GroupBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Font aFont = GetDrawPixelFont( pDev );
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ if ( nFlags & WINDOW_DRAW_MONO )
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ else
+ pDev->SetTextColor( GetTextColor() );
+ pDev->SetTextFillColor();
+
+ ImplDraw( pDev, nFlags, aPos, aSize );
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void GroupBox::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void GroupBox::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( (nType == STATE_CHANGE_ENABLE) ||
+ (nType == STATE_CHANGE_TEXT) ||
+ (nType == STATE_CHANGE_UPDATEMODE) )
+ {
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ if ( (GetPrevStyle() & GROUP_VIEW_STYLE) !=
+ (GetStyle() & GROUP_VIEW_STYLE) )
+ Invalidate();
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void GroupBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
diff --git a/vcl/source/control/ilstbox.cxx b/vcl/source/control/ilstbox.cxx
new file mode 100644
index 000000000000..3f1b977e7eab
--- /dev/null
+++ b/vcl/source/control/ilstbox.cxx
@@ -0,0 +1,2387 @@
+/*************************************************************************
+ *
+ * $RCSfile: ilstbox.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:35 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_ILSTBOX_CXX
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SCRBAR_HXX
+#include <scrbar.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+
+#ifndef _SV_LSTBOX_H
+#include <lstbox.h>
+#endif
+#ifndef _SV_ILSTBOX_HXX
+#include <ilstbox.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+void ImplInitFieldSettings( Window* pWin, BOOL bFont, BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetFieldFont();
+ if ( pWin->IsControlFont() )
+ aFont.Merge( pWin->GetControlFont() );
+ pWin->SetZoomedPointFont( aFont );
+ }
+
+ if ( bFont || bForeground )
+ {
+ Color aTextColor = rStyleSettings.GetFieldTextColor();
+ if ( pWin->IsControlForeground() )
+ aTextColor = pWin->GetControlForeground();
+ pWin->SetTextColor( aTextColor );
+ }
+
+ if ( bBackground )
+ {
+ if( pWin->IsControlBackground() )
+ pWin->SetBackground( pWin->GetControlBackground() );
+ else
+ pWin->SetBackground( rStyleSettings.GetFieldColor() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplInitDropDownButton( PushButton* pButton )
+{
+ if ( pButton->GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_SPINUPDOWN )
+ pButton->SetSymbol( SYMBOL_SPIN_UPDOWN );
+ else
+ pButton->SetSymbol( SYMBOL_SPIN_DOWN );
+}
+
+// =======================================================================
+
+ImplEntryList::ImplEntryList()
+{
+ mnLastSelected = LISTBOX_ENTRY_NOTFOUND;
+ mnSelectionAnchor = LISTBOX_ENTRY_NOTFOUND;
+ mnImages = 0;
+ mbCallSelectionChangedHdl = TRUE;
+
+ mnMRUCount = 0;
+ mnMaxMRUCount = 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImplEntryList::~ImplEntryList()
+{
+ Clear();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplEntryList::Clear()
+{
+ mnImages = 0;
+ for ( USHORT n = GetEntryCount(); n; )
+ {
+ ImplEntryType* pImplEntry = GetEntry( --n );
+ delete pImplEntry;
+ }
+ List::Clear();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplEntryList::SelectEntry( USHORT nPos, BOOL bSelect )
+{
+ ImplEntryType* pImplEntry = GetEntry( nPos );
+ if ( pImplEntry && ( pImplEntry->mbIsSelected != bSelect ) )
+ {
+ pImplEntry->mbIsSelected = bSelect;
+ if ( mbCallSelectionChangedHdl )
+ maSelectionChangedHdl.Call( (void*)nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplEntryList::InsertEntry( USHORT nPos, ImplEntryType* pNewEntry, BOOL bSort )
+{
+ if ( !!pNewEntry->maImage )
+ mnImages++;
+
+ if ( !bSort || !Count() )
+ {
+ Insert( pNewEntry, nPos );
+ }
+ else
+ {
+ const XubString& rStr = pNewEntry->maStr;
+ ULONG nLow, nHigh, nMid;
+
+ nHigh = Count();
+
+ const International& rIntl = Application::GetSettings().GetInternational();
+ ImplEntryType* pTemp = GetEntry( (USHORT)(nHigh-1) );
+ StringCompare eComp = rIntl.Compare( rStr, pTemp->maStr );
+
+ // Schnelles Einfuegen bei sortierten Daten
+ if ( eComp != COMPARE_LESS )
+ {
+ Insert( pNewEntry, LIST_APPEND );
+ }
+ else
+ {
+ nLow = mnMRUCount;
+ pTemp = (ImplEntryType*)GetEntry( (USHORT)nLow );
+ eComp = rIntl.Compare( rStr, pTemp->maStr );
+ if ( eComp != COMPARE_GREATER )
+ {
+ Insert( pNewEntry, (ULONG)0 );
+ }
+ else
+ {
+ // Binaeres Suchen
+ nHigh--;
+ do
+ {
+ nMid = (nLow + nHigh) / 2;
+ pTemp = (ImplEntryType*)GetObject( nMid );
+ eComp = rIntl.Compare( rStr, pTemp->maStr );
+
+ if ( eComp == COMPARE_LESS )
+ nHigh = nMid-1;
+ else
+ {
+ if ( eComp == COMPARE_GREATER )
+ nLow = nMid + 1;
+ else
+ break;
+ }
+ }
+ while ( nLow <= nHigh );
+
+ if ( eComp != COMPARE_LESS )
+ nMid++;
+
+ Insert( pNewEntry, nMid );
+ }
+ }
+ }
+
+ return (USHORT)GetPos( pNewEntry );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplEntryList::RemoveEntry( USHORT nPos )
+{
+ ImplEntryType* pImplEntry = (ImplEntryType*)List::Remove( nPos );
+ if ( pImplEntry )
+ {
+ if ( !!pImplEntry->maImage )
+ mnImages--;
+
+ delete pImplEntry;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplEntryList::FindEntry( const XubString& rStr, MatchMode nMatchMode, USHORT nMatchLen, USHORT nStart, BOOL bForward ) const
+{
+ BOOL bEqual;
+ USHORT nPos = LISTBOX_ENTRY_NOTFOUND;
+ USHORT nEntryCount = GetEntryCount();
+ if ( !bForward )
+ nStart++; // wird sofort dekrementiert
+ for ( USHORT n = nStart; bForward ? ( n < nEntryCount ) : n; )
+ {
+ if ( !bForward )
+ n--;
+
+ ImplEntryType* pImplEntry = GetEntry( n );
+ if ( nMatchMode == MATCH_CASE )
+ bEqual = pImplEntry->maStr.Equals( rStr, 0, nMatchLen );
+ else
+ bEqual = pImplEntry->maStr.EqualsIgnoreCaseAscii( rStr, 0, nMatchLen );
+ if ( bEqual )
+ {
+ // Wenn Case-Insensitiv matching, dann einen Eintrag bevorzugen,
+ // der trotzdem case-sensitiv matched.
+ if ( (nMatchMode == MATCH_CASE) ||
+ ((nMatchMode == MATCH_BEST) && (pImplEntry->maStr.Equals( rStr, 0, nMatchLen ))) )
+ {
+ nPos = n;
+ break;
+ }
+ else if ( nPos == LISTBOX_ENTRY_NOTFOUND )
+ nPos = n; // Bei Case-Insensitiv gewinnt der erste, wenn keiner 100%
+ }
+
+ if ( bForward )
+ n++;
+ }
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplEntryList::FindEntry( const void* pData ) const
+{
+ USHORT nPos = LISTBOX_ENTRY_NOTFOUND;
+ for ( USHORT n = GetEntryCount(); n; )
+ {
+ ImplEntryType* pImplEntry = GetEntry( --n );
+ if ( pImplEntry->mpUserData == pData )
+ {
+ nPos = n;
+ break;
+ }
+ }
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+XubString ImplEntryList::GetEntryText( USHORT nPos ) const
+{
+ XubString aEntryText;
+ ImplEntryType* pImplEntry = GetEntry( nPos );
+ if ( pImplEntry )
+ aEntryText = pImplEntry->maStr;
+ return aEntryText;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplEntryList::HasEntryImage( USHORT nPos ) const
+{
+ BOOL bImage = FALSE;
+ ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
+ if ( pImplEntry )
+ bImage = !!pImplEntry->maImage;
+ return bImage;
+}
+
+// -----------------------------------------------------------------------
+
+Image ImplEntryList::GetEntryImage( USHORT nPos ) const
+{
+ Image aImage;
+ ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
+ if ( pImplEntry )
+ aImage = pImplEntry->maImage;
+ return aImage;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplEntryList::SetEntryData( USHORT nPos, void* pNewData )
+{
+ ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
+ if ( pImplEntry )
+ pImplEntry->mpUserData = pNewData;
+}
+
+// -----------------------------------------------------------------------
+
+void* ImplEntryList::GetEntryData( USHORT nPos ) const
+{
+ ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
+ return pImplEntry ? pImplEntry->mpUserData : NULL;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplEntryList::GetSelectEntryCount() const
+{
+ USHORT nSelCount = 0;
+ for ( USHORT n = GetEntryCount(); n; )
+ {
+ ImplEntryType* pImplEntry = GetEntry( --n );
+ if ( pImplEntry->mbIsSelected )
+ nSelCount++;
+ }
+ return nSelCount;
+}
+
+// -----------------------------------------------------------------------
+
+XubString ImplEntryList::GetSelectEntry( USHORT nIndex ) const
+{
+ return GetEntryText( GetSelectEntryPos( nIndex ) );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplEntryList::GetSelectEntryPos( USHORT nIndex ) const
+{
+ USHORT nSelEntryPos = LISTBOX_ENTRY_NOTFOUND;
+ USHORT nSel = 0;
+ USHORT nEntryCount = GetEntryCount();
+
+ for ( USHORT n = 0; n < nEntryCount; n++ )
+ {
+ ImplEntryType* pImplEntry = GetEntry( n );
+ if ( pImplEntry->mbIsSelected )
+ {
+ if ( nSel == nIndex )
+ {
+ nSelEntryPos = n;
+ break;
+ }
+ nSel++;
+ }
+ }
+
+ return nSelEntryPos;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplEntryList::IsEntrySelected( const XubString& rStr ) const
+{
+ return IsEntryPosSelected( FindEntry( rStr ) );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplEntryList::IsEntryPosSelected( USHORT nIndex ) const
+{
+ ImplEntryType* pImplEntry = GetEntry( nIndex );
+ return pImplEntry ? pImplEntry->mbIsSelected : FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplEntryList::SetNoSelection()
+{
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT n = 0; n < nEntryCount; n++ )
+ SelectEntry( n, FALSE );
+}
+
+// =======================================================================
+
+ImplListBoxWindow::ImplListBoxWindow( Window* pParent, WinBits nWinStyle ) :
+ Control( pParent, 0 )
+{
+ mpEntryList = new ImplEntryList;
+
+ mnTop = 0;
+ mnLeft = 0;
+ mnBorder = 1;
+ mnSelectModifier = 0;
+ mnUserDrawEntry = LISTBOX_ENTRY_NOTFOUND;
+ mbTrack = FALSE;
+ mbImgsDiffSz = FALSE;
+ mbTravelSelect = FALSE;
+ mbTrackingSelect = FALSE;
+ mbSelectionChanged = FALSE;
+ mbMouseMoveSelect = FALSE;
+ mbMulti = FALSE;
+ mbGrabFocus = FALSE;
+ mbUserDrawEnabled = FALSE;
+ mbInUserDraw = FALSE;
+ mbReadOnly = FALSE;
+ mbSimpleMode = ( nWinStyle & WB_SIMPLEMODE ) ? TRUE : FALSE;
+ mbSort = ( nWinStyle & WB_SORT ) ? TRUE : FALSE;
+
+ mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
+ mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;
+ mnSeparatorPos = LISTBOX_ENTRY_NOTFOUND;
+
+ SetLineColor();
+ SetTextFillColor();
+ SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
+
+ maSearchTimeout.SetTimeout( 500 );
+ maSearchTimeout.SetTimeoutHdl( LINK( this, ImplListBoxWindow, SearchStringTimeout ) );
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ ImplCalcMetrics();
+}
+
+// -----------------------------------------------------------------------
+
+ImplListBoxWindow::~ImplListBoxWindow()
+{
+ maSearchTimeout.Stop();
+ delete mpEntryList;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::ImplInitSettings( BOOL bFont, BOOL bForeground, BOOL bBackground )
+{
+ ImplInitFieldSettings( this, bFont, bForeground, bBackground );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::ImplCalcMetrics()
+{
+ mnMaxWidth = 0;
+ mnMaxTxtWidth = 0;
+ mnMaxImgWidth = 0;
+ mnMaxImgTxtWidth= 0;
+ mnMaxImgHeight = 0;
+
+ mnTextHeight = (USHORT)GetTextHeight();
+ mnMaxTxtHeight = mnTextHeight + mnBorder;
+ mnMaxHeight = mnMaxTxtHeight;
+
+ if ( maUserItemSize.Height() > mnMaxHeight )
+ mnMaxHeight = (USHORT) maUserItemSize.Height();
+ if ( maUserItemSize.Width() > mnMaxWidth )
+ mnMaxWidth= (USHORT) maUserItemSize.Width();
+
+ for ( USHORT n = mpEntryList->GetEntryCount(); n; )
+ {
+ const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( --n );
+ ImplCalcEntryMetrics( *pEntry, TRUE );
+ }
+
+ Size aSz( GetOutputSizePixel().Width(), mnMaxHeight );
+ maFocusRect.SetSize( aSz );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ImplListBoxWindow, SearchStringTimeout, Timer*, EMPTYARG )
+{
+ maSearchStr.Erase();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::Clear()
+{
+ mpEntryList->Clear();
+
+ mnMaxHeight = mnMaxTxtHeight;
+ mnMaxWidth = 0;
+ mnMaxTxtWidth = 0;
+ mnMaxImgTxtWidth= 0;
+ mnMaxImgWidth = 0;
+ mnMaxImgHeight = 0;
+ mnTop = 0;
+ mnLeft = 0;
+ mbImgsDiffSz = FALSE;
+
+ Invalidate();
+}
+
+void ImplListBoxWindow::SetUserItemSize( const Size& rSz )
+{
+ maUserItemSize = rSz;
+ ImplCalcMetrics();
+}
+
+// -----------------------------------------------------------------------
+
+struct ImplEntryMetrics
+{
+ BOOL bText;
+ BOOL bImage;
+ USHORT nEntryWidth;
+ USHORT nEntryHeight;
+ USHORT nTextWidth;
+ USHORT nImgWidth;
+ USHORT nImgHeight;
+};
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::ImplCalcEntryMetrics( const ImplEntryType& rEntry, BOOL bUpdateMetrics )
+{
+ // bUpdateMetrics: Wenn Entry groesser als Max-Wert, dann uebernehmen
+
+ // Diese Methode war mal auch fuer RemoveRentry gedacht, deshalb die
+ // ImplEntryMetrics-Struktur, damit die Werte zurueckgegeben werden.
+ // Jetzt werden die aktuellen Metriken aber doch immer angepasst, weil
+ // bei RemoveEntry einmal komplett durchgegangen wird.
+
+ ImplEntryMetrics aMetrics;
+ aMetrics.bText = rEntry.maStr.Len() ? TRUE : FALSE;
+ aMetrics.bImage = !!rEntry.maImage;
+ aMetrics.nEntryWidth = 0;
+ aMetrics.nEntryHeight = 0;
+ aMetrics.nTextWidth = 0;
+ aMetrics.nImgWidth = 0;
+ aMetrics.nImgHeight = 0;
+
+ if ( aMetrics.bText )
+ {
+ aMetrics.nTextWidth = (USHORT)GetTextWidth( rEntry.maStr );
+ if( bUpdateMetrics && ( aMetrics.nTextWidth > mnMaxTxtWidth ) )
+ mnMaxTxtWidth = aMetrics.nTextWidth;
+ aMetrics.nEntryWidth = mnMaxTxtWidth;
+ }
+ if ( aMetrics.bImage )
+ {
+ Size aImgSz = rEntry.maImage.GetSizePixel();
+ aMetrics.nImgWidth = (USHORT) CalcZoom( aImgSz.Width() );
+ aMetrics.nImgHeight = (USHORT) CalcZoom( aImgSz.Height() );
+
+ if ( bUpdateMetrics )
+ {
+ if( mnMaxImgWidth && ( aMetrics.nImgWidth != mnMaxImgWidth ) )
+ mbImgsDiffSz = TRUE;
+ else if ( mnMaxImgHeight && ( aMetrics.nImgHeight != mnMaxImgHeight ) )
+ mbImgsDiffSz = TRUE;
+
+ if( aMetrics.nImgWidth > mnMaxImgWidth )
+ mnMaxImgWidth = aMetrics.nImgWidth;
+ if( aMetrics.nImgHeight > mnMaxImgHeight )
+ mnMaxImgHeight = aMetrics.nImgHeight;
+
+ mnMaxImgTxtWidth = Max( mnMaxImgTxtWidth, aMetrics.nTextWidth );
+ }
+ }
+ if ( IsUserDrawEnabled() || aMetrics.bImage )
+ {
+ aMetrics.nEntryWidth = Max( aMetrics.nImgWidth, (USHORT)maUserItemSize.Width() );
+ if ( aMetrics.bText )
+ aMetrics.nEntryWidth += aMetrics.nTextWidth + IMG_TXT_DISTANCE;
+ aMetrics.nEntryHeight = Max( mnMaxImgHeight, (USHORT)maUserItemSize.Height() ) + 2;
+ }
+
+ if ( bUpdateMetrics )
+ {
+ if ( aMetrics.nEntryWidth > mnMaxWidth )
+ mnMaxWidth = aMetrics.nEntryWidth;
+ if ( aMetrics.nEntryHeight > mnMaxHeight )
+ mnMaxHeight = aMetrics.nEntryHeight;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::ImplCallSelect()
+{
+ if ( !IsTravelSelect() && GetEntryList()->GetMaxMRUCount() )
+ {
+ // Insert the selected entry as MRU, if not allready first MRU
+ USHORT nSelected = GetEntryList()->GetSelectEntryPos( 0 );
+ USHORT nMRUCount = GetEntryList()->GetMRUCount();
+ String aSelected = GetEntryList()->GetEntryText( nSelected );
+ USHORT nFirstMatchingEntryPos = GetEntryList()->FindEntry( aSelected );
+ if ( nFirstMatchingEntryPos || !nMRUCount )
+ {
+ BOOL bSelectNewEntry = FALSE;
+ if ( nFirstMatchingEntryPos < nMRUCount )
+ {
+ RemoveEntry( nFirstMatchingEntryPos );
+ nMRUCount--;
+ if ( nFirstMatchingEntryPos == nSelected )
+ bSelectNewEntry = TRUE;
+ }
+ else if ( nMRUCount == GetEntryList()->GetMaxMRUCount() )
+ {
+ RemoveEntry( nMRUCount - 1 );
+ nMRUCount--;
+ }
+
+ ImplEntryType* pNewEntry = new ImplEntryType( aSelected );
+ pNewEntry->mbIsSelected = bSelectNewEntry;
+ GetEntryList()->InsertEntry( 0, pNewEntry, FALSE );
+ GetEntryList()->SetMRUCount( ++nMRUCount );
+ SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 );
+ maMRUChangedHdl.Call( NULL );
+ }
+ }
+
+ maSelectHdl.Call( NULL );
+ mbSelectionChanged = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplListBoxWindow::InsertEntry( USHORT nPos, ImplEntryType* pNewEntry )
+{
+ USHORT nNewPos = mpEntryList->InsertEntry( nPos, pNewEntry, mbSort );
+
+ ImplCalcEntryMetrics( *pNewEntry, TRUE );
+ return nNewPos;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::RemoveEntry( USHORT nPos )
+{
+ mpEntryList->RemoveEntry( nPos );
+ ImplCalcMetrics();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ mbMouseMoveSelect = FALSE; // Nur bis zum ersten MouseButtonDown
+
+ if ( !IsReadOnly() )
+ {
+ if( rMEvt.GetClicks() == 1 )
+ {
+ USHORT nSelect = (USHORT) ( ( rMEvt.GetPosPixel().Y() + mnBorder ) / mnMaxHeight ) + (USHORT) mnTop;
+ if( nSelect < mpEntryList->GetEntryCount() )
+ {
+ if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
+ mnTrackingSaveSelection = GetEntryList()->GetSelectEntryPos( 0 );
+ else
+ mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;
+
+ mnCurrentPos = nSelect;
+ mbTrackingSelect = TRUE;
+ SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() );
+ mbTrackingSelect = FALSE;
+ if ( mbGrabFocus )
+ GrabFocus();
+
+ StartTracking( STARTTRACK_SCROLLREPEAT );
+ }
+ }
+ if( rMEvt.GetClicks() == 2 )
+ {
+ maDoubleClickHdl.Call( this );
+ }
+ }
+ else // if ( mbGrabFocus )
+ {
+ GrabFocus();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( !mbMulti && mbMouseMoveSelect && mpEntryList->GetEntryCount() && !rMEvt.IsLeaveWindow() )
+ {
+ Point aPoint;
+ Rectangle aRect( aPoint, GetOutputSizePixel() );
+ if( aRect.IsInside( rMEvt.GetPosPixel() ) )
+ {
+ USHORT nSelect = (USHORT) ( ( rMEvt.GetPosPixel().Y() + mnBorder ) / mnMaxHeight ) + (USHORT) mnTop;
+ nSelect = Min( nSelect, (USHORT) ( mnTop + mnMaxVisibleEntries ) );
+ nSelect = Min( nSelect, (USHORT) ( mpEntryList->GetEntryCount() - 1 ) );
+ if ( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() || ( nSelect != GetEntryList()->GetSelectEntryPos( 0 ) ) )
+ {
+ mbTrackingSelect = TRUE;
+ SelectEntries( nSelect, LET_TRACKING, FALSE, FALSE );
+ mbTrackingSelect = FALSE;
+ }
+
+ // Falls der DD-Button gedrueckt wurde und jemand mit gedrueckter
+ // Maustaste in die ListBox faehrt...
+ if ( rMEvt.IsLeft() && !rMEvt.IsSynthetic() )
+ {
+ if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
+ mnTrackingSaveSelection = GetEntryList()->GetSelectEntryPos( 0 );
+ else
+ mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;
+ StartTracking( STARTTRACK_SCROLLREPEAT );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::SelectEntry( USHORT nPos, BOOL bSelect )
+{
+ if ( mpEntryList->IsEntryPosSelected( nPos ) != bSelect )
+ {
+ HideFocus();
+ if( bSelect )
+ {
+ if( !mbMulti )
+ {
+ // Selektierten Eintrag deselektieren
+ USHORT nDeselect = GetEntryList()->GetSelectEntryPos( 0 );
+ if( nDeselect != LISTBOX_ENTRY_NOTFOUND )
+ {
+ //SelectEntryPos( nDeselect, FALSE );
+ GetEntryList()->SelectEntry( nDeselect, FALSE );
+ if ( IsUpdateMode() && IsReallyVisible() )
+ ImplPaint( nDeselect, TRUE );
+ }
+ }
+ mpEntryList->SelectEntry( nPos, TRUE );
+ mnCurrentPos = nPos;
+ if ( ( nPos != LISTBOX_ENTRY_NOTFOUND ) && IsUpdateMode() )
+ {
+ ImplPaint( nPos );
+ if ( !IsVisible( nPos ) )
+ SetTopEntry( nPos );
+ }
+ }
+ else
+ {
+ mpEntryList->SelectEntry( nPos, FALSE );
+ ImplPaint( nPos, TRUE );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplListBoxWindow::SelectEntries( USHORT nSelect, LB_EVENT_TYPE eLET, BOOL bShift, BOOL bCtrl )
+{
+ BOOL bFocusChanged = FALSE;
+ BOOL bSelectionChanged = FALSE;
+
+ if( IsEnabled() )
+ {
+ // Hier (Single-ListBox) kann nur ein Eintrag deselektiert werden
+ if( !mbMulti )
+ {
+ USHORT nDeselect = mpEntryList->GetSelectEntryPos( 0 );
+ if( nSelect != nDeselect )
+ {
+ SelectEntry( nSelect, TRUE );
+ mpEntryList->SetLastSelected( nSelect );
+ bFocusChanged = TRUE;
+ bSelectionChanged = TRUE;
+ }
+ }
+ // MultiListBox ohne Modifier
+ else if( mbSimpleMode && !bCtrl && !bShift )
+ {
+ USHORT nEntryCount = mpEntryList->GetEntryCount();
+ for ( USHORT nPos = 0; nPos < nEntryCount; nPos++ )
+ {
+ BOOL bSelect = nPos == nSelect;
+ if ( mpEntryList->IsEntryPosSelected( nPos ) != bSelect )
+ {
+ SelectEntry( nPos, bSelect );
+ bFocusChanged = TRUE;
+ bSelectionChanged = TRUE;
+ }
+ }
+ mpEntryList->SetLastSelected( nSelect );
+ mpEntryList->SetSelectionAnchor( nSelect );
+ }
+ // MultiListBox nur mit CTRL/SHIFT oder nicht im SimpleMode
+ else if( ( !mbSimpleMode /* && !bShift */ ) || ( mbSimpleMode && ( bCtrl || bShift ) ) )
+ {
+ // Space fuer Selektionswechsel
+ if( !bShift && ( ( eLET == LET_KEYSPACE ) || ( eLET == LET_MBDOWN ) ) )
+ {
+ SelectEntry( nSelect, !mpEntryList->IsEntryPosSelected( nSelect ) );
+ mpEntryList->SetLastSelected( nSelect );
+ mpEntryList->SetSelectionAnchor( nSelect );
+ if ( !mpEntryList->IsEntryPosSelected( nSelect ) )
+ mpEntryList->SetSelectionAnchor( LISTBOX_ENTRY_NOTFOUND );
+ bFocusChanged = TRUE;
+ bSelectionChanged = TRUE;
+ }
+ else if( ( ( eLET == LET_TRACKING ) && ( nSelect != mnCurrentPos ) ) ||
+ ( bShift && ( ( eLET == LET_KEYMOVE ) || ( eLET == LET_MBDOWN ) ) ) )
+ {
+ mnCurrentPos = nSelect;
+ bFocusChanged = TRUE;
+
+ USHORT nAnchor = mpEntryList->GetSelectionAnchor();
+ if( ( nAnchor == LISTBOX_ENTRY_NOTFOUND ) && ( mpEntryList->GetSelectEntryCount() ) )
+ {
+ nAnchor = mpEntryList->GetSelectEntryPos( mpEntryList->GetSelectEntryCount() - 1 );
+ }
+ if( nAnchor != LISTBOX_ENTRY_NOTFOUND )
+ {
+ // Alle Eintraege vom Anchor bis nSelect muessen selektiert sein
+ USHORT nStart = Min( nSelect, nAnchor );
+ USHORT nEnd = Max( nSelect, nAnchor );
+ for ( USHORT n = nStart; n <= nEnd; n++ )
+ {
+ if ( !mpEntryList->IsEntryPosSelected( n ) )
+ {
+ SelectEntry( n, TRUE );
+ bSelectionChanged = TRUE;
+ }
+ }
+
+ // Ggf. muss noch was deselektiert werden...
+ USHORT nLast = mpEntryList->GetLastSelected();
+ if ( nLast != LISTBOX_ENTRY_NOTFOUND )
+ {
+ if ( ( nLast > nSelect ) && ( nLast > nAnchor ) )
+ {
+ for ( USHORT n = nSelect+1; n <= nLast; n++ )
+ {
+ if ( mpEntryList->IsEntryPosSelected( n ) )
+ {
+ SelectEntry( n, FALSE );
+ bSelectionChanged = TRUE;
+ }
+ }
+ }
+ else if ( ( nLast < nSelect ) && ( nLast < nAnchor ) )
+ {
+ for ( USHORT n = nLast; n < nSelect; n++ )
+ {
+ if ( mpEntryList->IsEntryPosSelected( n ) )
+ {
+ SelectEntry( n, FALSE );
+ bSelectionChanged = TRUE;
+ }
+ }
+ }
+ }
+ mpEntryList->SetLastSelected( nSelect );
+ }
+ }
+ else if( eLET != LET_TRACKING )
+ {
+ HideFocus();
+ ImplPaint( nSelect, TRUE );
+ bFocusChanged = TRUE;
+ }
+ }
+ else if( bShift )
+ {
+ bFocusChanged = TRUE;
+ }
+
+ if( bSelectionChanged )
+ mbSelectionChanged = TRUE;
+
+ if( bFocusChanged )
+ {
+ maFocusRect.SetPos( Point( 0, ( nSelect - mnTop ) * mnMaxHeight ) );
+ if( HasFocus() )
+ ShowFocus( maFocusRect );
+ }
+ }
+ return bSelectionChanged;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::Tracking( const TrackingEvent& rTEvt )
+{
+ Point aPoint;
+ Rectangle aRect( aPoint, GetOutputSizePixel() );
+ BOOL bInside = aRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() );
+
+ if( rTEvt.IsTrackingCanceled() || rTEvt.IsTrackingEnded() ) // MouseButtonUp
+ {
+ if ( bInside && !rTEvt.IsTrackingCanceled() )
+ {
+ mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
+ ImplCallSelect();
+ }
+ else
+ {
+ maCancelHdl.Call( NULL );
+ if ( !mbMulti )
+ {
+ mbTrackingSelect = TRUE;
+ SelectEntry( mnTrackingSaveSelection, TRUE );
+ mbTrackingSelect = FALSE;
+ if ( mnTrackingSaveSelection != LISTBOX_ENTRY_NOTFOUND )
+ {
+ maFocusRect.SetPos( Point( 0, ( mnCurrentPos - mnTop ) * mnMaxHeight ) );
+ ShowFocus( maFocusRect );
+ }
+ }
+ }
+
+ mbTrack = FALSE;
+ }
+ else
+ {
+ BOOL bTrackOrQuickClick = mbTrack;
+ if( !mbTrack )
+ {
+ if ( bInside )
+ {
+ mbTrack = TRUE;
+ }
+
+ // Folgender Fall tritt nur auf, wenn man ganz kurz die Maustaste drueckt
+ if( rTEvt.IsTrackingEnded() && mbTrack )
+ {
+ bTrackOrQuickClick = TRUE;
+ mbTrack = FALSE;
+ }
+ }
+
+ if( bTrackOrQuickClick )
+ {
+ MouseEvent aMEvt = rTEvt.GetMouseEvent();
+ Point aPt( aMEvt.GetPosPixel() );
+ BOOL bShift = aMEvt.IsShift();
+ BOOL bCtrl = aMEvt.IsMod1();
+
+ USHORT nSelect = LISTBOX_ENTRY_NOTFOUND;
+ if( aPt.Y() < 0 )
+ {
+ nSelect = mnCurrentPos ? ( mnCurrentPos - 1 ) : 0;
+ if( nSelect < mnTop )
+ SetTopEntry( mnTop-1 );
+ }
+ else if( aPt.Y() > GetOutputSizePixel().Height() )
+ {
+ nSelect = Min( (USHORT)(mnCurrentPos+1), (USHORT)(mpEntryList->GetEntryCount()-1) );
+ if( nSelect >= mnTop + mnMaxVisibleEntries )
+ SetTopEntry( mnTop+1 );
+ }
+ else
+ {
+ nSelect = (USHORT) ( ( aPt.Y() + mnBorder ) / mnMaxHeight ) + (USHORT) mnTop;
+ nSelect = Min( nSelect, (USHORT) ( mnTop + mnMaxVisibleEntries ) );
+ nSelect = Min( nSelect, (USHORT) ( mpEntryList->GetEntryCount() - 1 ) );
+ }
+
+ if ( bInside )
+ {
+ if ( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() )
+ {
+ mbTrackingSelect = TRUE;
+ SelectEntries( nSelect, LET_TRACKING, bShift, bCtrl );
+ mbTrackingSelect = FALSE;
+ }
+ }
+ else
+ {
+ if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
+ {
+ mbTrackingSelect = TRUE;
+ SelectEntry( GetEntryList()->GetSelectEntryPos( 0 ), FALSE );
+ mbTrackingSelect = FALSE;
+ }
+ }
+ mnCurrentPos = nSelect;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::KeyInput( const KeyEvent& rKEvt )
+{
+ if( !ProcessKeyInput( rKEvt ) )
+ Control::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
+{
+ // zu selektierender Eintrag
+ USHORT nSelect = LISTBOX_ENTRY_NOTFOUND;
+ LB_EVENT_TYPE eLET = LET_KEYMOVE;
+
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ BOOL bShift = aKeyCode.IsShift();
+ BOOL bCtrl = aKeyCode.IsMod1();
+ BOOL bMod2 = aKeyCode.IsMod2();
+ BOOL bDone = FALSE;
+
+ switch( aKeyCode.GetCode() )
+ {
+ case KEY_UP:
+ {
+ if ( IsReadOnly() )
+ {
+ if ( GetTopEntry() )
+ SetTopEntry( GetTopEntry()-1 );
+ }
+ else if ( !bMod2 )
+ {
+ if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
+ nSelect = mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND;
+ else if ( mnCurrentPos )
+ nSelect = mnCurrentPos - 1;
+
+ if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect < mnTop ) )
+ SetTopEntry( mnTop-1 );
+
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_DOWN:
+ {
+ if ( IsReadOnly() )
+ {
+ SetTopEntry( GetTopEntry()+1 );
+ }
+ else if ( !bMod2 )
+ {
+ if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
+ nSelect = mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND;
+ else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
+ nSelect = mnCurrentPos+1;
+
+ if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect >= ( mnTop + mnMaxVisibleEntries ) ) )
+ SetTopEntry( mnTop+1 );
+
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_PAGEUP:
+ {
+ if ( IsReadOnly() )
+ {
+ SetTopEntry( ( mnTop > mnMaxVisibleEntries ) ?
+ (mnTop-mnMaxVisibleEntries) : 0 );
+ }
+ else if ( !bCtrl && !bMod2 )
+ {
+ if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
+ nSelect = mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND;
+ else if ( mnCurrentPos )
+ {
+ if( mnCurrentPos == mnTop )
+ SetTopEntry( ( mnTop > mnMaxVisibleEntries ) ?
+ ( mnTop-mnMaxVisibleEntries+1 ) : 0 );
+ nSelect = mnTop;
+ }
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_PAGEDOWN:
+ {
+ if ( IsReadOnly() )
+ {
+ SetTopEntry( mnTop + mnMaxVisibleEntries );
+ }
+ else if ( !bCtrl && !bMod2 )
+ {
+ if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
+ nSelect = mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND;
+ else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
+ {
+ USHORT nCount = mpEntryList->GetEntryCount();
+ USHORT nTmp = Min( mnMaxVisibleEntries, nCount );
+ nTmp += mnTop - 1;
+ if( mnCurrentPos == nTmp && mnCurrentPos != nCount - 1 )
+ {
+ long nTmp2 = Min( (long)(nCount-mnMaxVisibleEntries), (long)((long)mnTop+(long)mnMaxVisibleEntries-1) );
+ nTmp2 = Max( (long)0 , nTmp2 );
+ nTmp = (USHORT)(nTmp2+(mnMaxVisibleEntries-1) );
+ SetTopEntry( (USHORT)nTmp2 );
+ }
+ nSelect = nTmp;
+ }
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_HOME:
+ {
+ if ( IsReadOnly() )
+ {
+ SetTopEntry( 0 );
+ }
+ else if ( !bCtrl && !bMod2 )
+ {
+ if ( mnCurrentPos )
+ {
+ nSelect = mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND;
+ if( mnTop != 0 )
+ SetTopEntry( 0 );
+
+ bDone = TRUE;
+ }
+ }
+ }
+ break;
+
+ case KEY_END:
+ {
+ if ( IsReadOnly() )
+ {
+ SetTopEntry( 0xFFFF );
+ }
+ else if ( !bCtrl && !bMod2 )
+ {
+ if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
+ nSelect = mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND;
+ else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
+ {
+ USHORT nCount = mpEntryList->GetEntryCount();
+ nSelect = nCount - 1;
+ if( nCount > mnMaxVisibleEntries )
+ SetTopEntry( nCount - mnMaxVisibleEntries );
+ }
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_LEFT:
+ {
+ if ( !bCtrl && !bMod2 )
+ {
+ ScrollHorz( -HORZ_SCROLL );
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_RIGHT:
+ {
+ if ( !bCtrl && !bMod2 )
+ {
+ ScrollHorz( HORZ_SCROLL );
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ case KEY_RETURN:
+ {
+ if ( !bMod2 && !IsReadOnly() )
+ {
+ mnSelectModifier = rKEvt.GetKeyCode().GetModifier();
+ ImplCallSelect();
+ bDone = FALSE; // RETURN nicht abfangen.
+ }
+ }
+ break;
+
+ case KEY_SPACE:
+ {
+ if ( !bMod2 && !IsReadOnly() )
+ {
+ if( mbMulti && ( !mbSimpleMode || ( mbSimpleMode && bCtrl && !bShift ) ) )
+ {
+ nSelect = mnCurrentPos;
+ eLET = LET_KEYSPACE;
+ }
+ bDone = TRUE;
+ }
+ }
+ break;
+
+ default:
+ {
+ xub_Unicode c = rKEvt.GetCharCode();
+
+ if ( !IsReadOnly() && (c >= 32) && (c != 127) &&
+ !rKEvt.GetKeyCode().IsControlMod() )
+ {
+ maSearchStr += c;
+ XubString aTmpSearch( maSearchStr );
+
+ nSelect = mpEntryList->FindEntry( aTmpSearch, MATCH_IGNORECASE, aTmpSearch.Len(), mnCurrentPos );
+ if ( (nSelect == LISTBOX_ENTRY_NOTFOUND) && (aTmpSearch.Len() > 1) )
+ {
+ // Wenn alles die gleichen Buchstaben, dann anderer Such-Modus
+ BOOL bAllEqual = TRUE;
+ for ( USHORT n = aTmpSearch.Len(); n && bAllEqual; )
+ bAllEqual = aTmpSearch.GetChar( --n ) == c;
+ if ( bAllEqual )
+ {
+ aTmpSearch = c;
+ nSelect = mpEntryList->FindEntry( aTmpSearch, MATCH_IGNORECASE, aTmpSearch.Len(), mnCurrentPos+1 );
+ }
+ }
+ if ( nSelect == LISTBOX_ENTRY_NOTFOUND )
+ nSelect = mpEntryList->FindEntry( aTmpSearch, MATCH_IGNORECASE, aTmpSearch.Len(), 0 );
+
+ if ( nSelect != LISTBOX_ENTRY_NOTFOUND )
+ {
+ if( nSelect < mnTop )
+ SetTopEntry( nSelect );
+ else if( nSelect >= (mnTop + mnMaxVisibleEntries) )
+ SetTopEntry( nSelect - mnMaxVisibleEntries + 1 );
+
+ if ( nSelect == mnCurrentPos )
+ nSelect = LISTBOX_ENTRY_NOTFOUND;
+
+ maSearchTimeout.Start();
+ }
+ else
+ maSearchStr.Erase();
+ bDone = TRUE;
+ }
+ }
+ }
+
+ if ( (nSelect != LISTBOX_ENTRY_NOTFOUND) &&
+ ((nSelect != mnCurrentPos ) || ( eLET == LET_KEYSPACE)) )
+ {
+ DBG_ASSERT( (nSelect != mnCurrentPos) || mbMulti, "ImplListBox: Selecting same Entry" );
+ mnCurrentPos = nSelect;
+ if ( SelectEntries( nSelect, eLET, bShift, bCtrl ) )
+ {
+ mbTravelSelect = TRUE;
+ mnSelectModifier = rKEvt.GetKeyCode().GetModifier();
+ ImplCallSelect();
+ mbTravelSelect = FALSE;
+ }
+ }
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::ImplPaint( USHORT nPos, BOOL bErase )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ long nWidth = GetOutputSizePixel().Width();
+ long nY = ( nPos - mnTop ) * mnMaxHeight;
+ Rectangle aRect( Point( 0, nY ), Size( nWidth, mnMaxHeight ) );
+
+ if( IsEnabled() )
+ {
+ if( mpEntryList->IsEntryPosSelected( nPos ) )
+ {
+ SetTextColor( rStyleSettings.GetHighlightTextColor() );
+ SetFillColor( rStyleSettings.GetHighlightColor() );
+ DrawRect( aRect );
+ }
+ else
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ if( bErase )
+ Erase( aRect );
+ }
+ }
+ else // Disabled
+ {
+ SetTextColor( rStyleSettings.GetDisableColor() );
+ //SetFillColor( rStyleSettings.Get???Color() );
+ //DrawRect( aRect );
+ if( bErase )
+ Erase( aRect );
+ }
+
+ if ( IsUserDrawEnabled() )
+ {
+ mbInUserDraw = TRUE;
+ mnUserDrawEntry = nPos;
+ aRect.Left() -= mnLeft;
+ if ( nPos < GetEntryList()->GetMRUCount() )
+ nPos = GetEntryList()->FindEntry( GetEntryList()->GetEntryText( nPos ), MATCH_CASE, STRING_LEN, GetEntryList()->GetMRUCount() );
+ nPos -= GetEntryList()->GetMRUCount();
+ UserDrawEvent aUDEvt( this, aRect, nPos, 0 );
+ maUserDrawHdl.Call( &aUDEvt );
+ mbInUserDraw = FALSE;
+ }
+ else
+ {
+ DrawEntry( nPos, TRUE, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText, BOOL bDrawTextAtImagePos )
+{
+ // Bei Aenderungen in dieser Methode ggf. auch ImplWin::DrawEntry() anpassen.
+
+ if ( mbInUserDraw )
+ nPos = mnUserDrawEntry; // real entry, not the matching entry from MRU
+
+ long nY = ( nPos - mnTop ) * mnMaxHeight;
+
+ if( bDrawImage && mpEntryList->HasImages() )
+ {
+ Image aImage = mpEntryList->GetEntryImage( nPos );
+ if( !!aImage )
+ {
+ Size aImgSz = aImage.GetSizePixel();
+ Point aPtImg( mnBorder - mnLeft, nY + ( ( mnMaxHeight - aImgSz.Height() ) / 2 ) );
+
+ if ( !IsZoom() )
+ {
+ DrawImage( aPtImg, aImage );
+ }
+ else
+ {
+ aImgSz.Width() = CalcZoom( aImgSz.Width() );
+ aImgSz.Height() = CalcZoom( aImgSz.Height() );
+ DrawImage( aPtImg, aImgSz, aImage );
+ }
+ }
+ }
+
+ if( bDrawText )
+ {
+ XubString aStr( mpEntryList->GetEntryText( nPos ) );
+ if ( aStr.Len() )
+ {
+ Point aPtTxt( mnBorder - mnLeft, nY + ( ( mnMaxHeight - mnMaxTxtHeight ) / 2 ) );
+ if( !bDrawTextAtImagePos && ( mpEntryList->HasEntryImage(nPos) || IsUserDrawEnabled() ) )
+ {
+ USHORT nMaxWidth = Max( mnMaxImgWidth, (USHORT)maUserItemSize.Width() );
+ aPtTxt.X() += nMaxWidth + IMG_TXT_DISTANCE;
+ }
+ DrawText( aPtTxt, aStr );
+ }
+ }
+
+ if ( ( mnSeparatorPos != LISTBOX_ENTRY_NOTFOUND ) &&
+ ( ( nPos == mnSeparatorPos ) || ( nPos == mnSeparatorPos+1 ) ) )
+ {
+ Color aOldLineColor( GetLineColor() );
+ SetLineColor( ( GetBackground().GetColor() != COL_LIGHTGRAY ) ? COL_LIGHTGRAY : COL_GRAY );
+ Point aStartPos( 0, nY );
+ if ( nPos == mnSeparatorPos )
+ aStartPos.Y() += mnMaxHeight-1;
+ Point aEndPos( aStartPos );
+ aEndPos.X() = GetOutputSizePixel().Width();
+ DrawLine( aStartPos, aEndPos );
+ SetLineColor( aOldLineColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::Paint( const Rectangle& rRect )
+{
+ USHORT nCount = mpEntryList->GetEntryCount();
+
+ if( HasFocus() )
+ HideFocus();
+
+ long nY = 0; // + mnBorder;
+ long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder;
+
+ for( USHORT i = (USHORT)mnTop; i < nCount && nY < nHeight + mnMaxHeight; i++ )
+ {
+ if( nY + mnMaxHeight >= rRect.Top() &&
+ nY <= rRect.Bottom() + mnMaxHeight )
+ {
+ ImplPaint( i );
+ }
+ nY += mnMaxHeight;
+ }
+
+ maFocusRect.SetPos( Point( 0, ( mnCurrentPos - mnTop ) * mnMaxHeight ) );
+ if( HasFocus() )
+ ShowFocus( maFocusRect );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::Resize()
+{
+ Size aSz( GetOutputSizePixel().Width(), mnMaxHeight );
+ maFocusRect.SetSize( aSz );
+ mnMaxVisibleEntries = (USHORT) ( GetOutputSizePixel().Height() / mnMaxHeight );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::GetFocus()
+{
+ USHORT nPos = mnCurrentPos;
+ if ( nPos == LISTBOX_ENTRY_NOTFOUND )
+ nPos = 0;
+ maFocusRect.SetPos( Point( 0, ( nPos - mnTop ) * mnMaxHeight ) );
+ ShowFocus( maFocusRect );
+ Control::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::LoseFocus()
+{
+ HideFocus();
+ Control::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+/*
+void ImplListBoxWindow::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), String() );
+
+ Window::RequestHelp( rHEvt );
+}
+*/
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::SetTopEntry( USHORT nTop )
+{
+ USHORT nMaxTop = 0;
+ if ( GetEntryList()->GetEntryCount() > mnMaxVisibleEntries )
+ nMaxTop = GetEntryList()->GetEntryCount() - mnMaxVisibleEntries;
+ nTop = Min( nTop, nMaxTop );
+ if ( nTop != mnTop )
+ {
+ HideFocus();
+ long nDiff = ( mnTop - nTop ) * mnMaxHeight;
+ mnTop = nTop;
+ Scroll( 0, nDiff );
+ maFocusRect.Top() += nDiff;
+ maFocusRect.Bottom() += nDiff;
+ if( HasFocus() )
+ ShowFocus( maFocusRect );
+ maScrollHdl.Call( this );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::SetLeftIndent( USHORT n )
+{
+ ScrollHorz( n - mnLeft );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::ScrollHorz( short n )
+{
+ short nDiff = 0;
+ if ( n > 0 )
+ {
+ long nWidth = GetOutputSizePixel().Width();
+ if( ( mnMaxWidth - mnLeft + n ) > nWidth )
+ nDiff = n;
+ }
+ else if ( n < 0 )
+ {
+ if( mnLeft )
+ {
+ USHORT nAbs = -n;
+ nDiff = - ( ( mnLeft > nAbs ) ? nAbs : mnLeft );
+ }
+ }
+
+ if ( nDiff )
+ {
+ HideFocus();
+ mnLeft += nDiff;
+ Scroll( -nDiff, 0 );
+ if( HasFocus() )
+ ShowFocus( maFocusRect );
+ maScrollHdl.Call( this );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size ImplListBoxWindow::CalcSize( USHORT nMaxLines ) const
+{
+ Size aSz;
+// USHORT nL = Min( nMaxLines, mpEntryList->GetEntryCount() );
+ aSz.Height() = nMaxLines * mnMaxHeight;
+ aSz.Width() = mnMaxWidth + 2*mnBorder;
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_ZOOM )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ ImplCalcMetrics();
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsUpdateMode() && IsReallyVisible() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ ImplCalcMetrics();
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ ImplCalcMetrics();
+ Invalidate();
+ }
+}
+
+// =======================================================================
+
+ImplListBox::ImplListBox( Window* pParent, WinBits nWinStyle ) :
+ Control( pParent, nWinStyle ),
+ maLBWindow( this, nWinStyle&(~WB_BORDER) )
+{
+ mpVScrollBar = new ScrollBar( this, WB_VSCROLL | WB_DRAG );
+ mpHScrollBar = new ScrollBar( this, WB_HSCROLL | WB_DRAG );
+ mpScrollBarBox = new ScrollBarBox( this );
+
+ Link aLink( LINK( this, ImplListBox, ScrollBarHdl ) );
+ mpVScrollBar->SetScrollHdl( aLink );
+ mpHScrollBar->SetScrollHdl( aLink );
+
+ mbVScroll = FALSE;
+ mbHScroll = FALSE;
+ mbAutoHScroll = ( nWinStyle & WB_AUTOHSCROLL ) ? TRUE : FALSE;
+
+ maLBWindow.SetScrollHdl( LINK( this, ImplListBox, LBWindowScrolled ) );
+ maLBWindow.SetMRUChangedHdl( LINK( this, ImplListBox, MRUChanged ) );
+ maLBWindow.Show();
+}
+
+// -----------------------------------------------------------------------
+
+ImplListBox::~ImplListBox()
+{
+ delete mpHScrollBar;
+ delete mpVScrollBar;
+ delete mpScrollBarBox;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::Clear()
+{
+ maLBWindow.Clear();
+ if ( GetEntryList()->GetMRUCount() )
+ {
+ maLBWindow.GetEntryList()->SetMRUCount( 0 );
+ maLBWindow.SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND );
+ }
+ mpVScrollBar->SetThumbPos( 0 );
+ mpHScrollBar->SetThumbPos( 0 );
+ StateChanged( STATE_CHANGE_DATA );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplListBox::InsertEntry( USHORT nPos, const XubString& rStr )
+{
+ ImplEntryType* pNewEntry = new ImplEntryType( rStr );
+ USHORT nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
+ StateChanged( STATE_CHANGE_DATA );
+ return nNewPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplListBox::InsertEntry( USHORT nPos, const Image& rImage )
+{
+ ImplEntryType* pNewEntry = new ImplEntryType( rImage );
+ USHORT nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
+ StateChanged( STATE_CHANGE_DATA );
+ return nNewPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplListBox::InsertEntry( USHORT nPos, const XubString& rStr, const Image& rImage )
+{
+ ImplEntryType* pNewEntry = new ImplEntryType( rStr, rImage );
+ USHORT nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
+ StateChanged( STATE_CHANGE_DATA );
+ return nNewPos;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::RemoveEntry( USHORT nPos )
+{
+ maLBWindow.RemoveEntry( nPos );
+ StateChanged( STATE_CHANGE_DATA );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::SelectEntry( USHORT nPos, BOOL bSelect )
+{
+ maLBWindow.SelectEntry( nPos, bSelect );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::SetNoSelection()
+{
+ USHORT nSelected = GetEntryList()->GetSelectEntryCount();
+ for ( USHORT n = 0; n < nSelected; n++ )
+ {
+ USHORT nS = GetEntryList()->GetSelectEntryPos( n );
+ SelectEntry( nS, FALSE );
+ }
+ maLBWindow.GetEntryList()->SetNoSelection();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::GetFocus()
+{
+ maLBWindow.GrabFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::Resize()
+{
+ ImplResizeControls();
+ ImplCheckScrollBars();
+}
+
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ImplListBox, MRUChanged, void*, EMPTYARG )
+{
+ StateChanged( STATE_CHANGE_DATA );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ImplListBox, LBWindowScrolled, void*, EMPTYARG )
+{
+ mpVScrollBar->SetThumbPos( GetTopEntry() );
+ mpHScrollBar->SetThumbPos( GetLeftIndent() );
+
+ maScrollHdl.Call( this );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ImplListBox, ScrollBarHdl, ScrollBar*, pSB )
+{
+ USHORT nPos = (USHORT) pSB->GetThumbPos();
+ if( pSB == mpVScrollBar )
+ SetTopEntry( nPos );
+ else if( pSB == mpHScrollBar )
+ SetLeftIndent( nPos );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::ImplCheckScrollBars()
+{
+ BOOL bArrange = FALSE;
+
+ Size aOutSz = GetOutputSizePixel();
+ USHORT nEntries = GetEntryList()->GetEntryCount();
+ USHORT nMaxVisEntries = (USHORT) (aOutSz.Height() / GetEntryHeight());
+
+ // vert. ScrollBar
+ if( nEntries > nMaxVisEntries )
+ {
+ if( !mbVScroll )
+ bArrange = TRUE;
+ mbVScroll = TRUE;
+
+ // Ueberpruefung des rausgescrollten Bereichs
+ SetTopEntry( GetTopEntry() ); // MaxTop wird geprueft...
+ }
+ else
+ {
+ if( mbVScroll )
+ bArrange = TRUE;
+ mbVScroll = FALSE;
+ SetTopEntry( 0 );
+ }
+
+ // horz. ScrollBar
+ if( mbAutoHScroll )
+ {
+ long nWidth = (USHORT) aOutSz.Width();
+ if ( mbVScroll )
+ nWidth -= mpVScrollBar->GetSizePixel().Width();
+
+ long nMaxWidth = GetMaxEntryWidth();
+ if( nWidth < nMaxWidth )
+ {
+ if( !mbHScroll )
+ bArrange = TRUE;
+ mbHScroll = TRUE;
+
+ if ( !mbVScroll ) // ggf. brauchen wir jetzt doch einen
+ {
+ nMaxVisEntries = (USHORT) ( ( aOutSz.Height() - mpHScrollBar->GetSizePixel().Height() ) / GetEntryHeight() );
+ if( nEntries > nMaxVisEntries )
+ {
+ bArrange = TRUE;
+ mbVScroll = TRUE;
+
+ // Ueberpruefung des rausgescrollten Bereichs
+ SetTopEntry( GetTopEntry() ); // MaxTop wird geprueft...
+ }
+ }
+
+ // Ueberpruefung des rausgescrollten Bereichs
+ USHORT nMaxLI = (USHORT) (nMaxWidth - nWidth);
+ if ( nMaxLI < GetLeftIndent() )
+ SetLeftIndent( nMaxLI );
+ }
+ else
+ {
+ if( mbHScroll )
+ bArrange = TRUE;
+ mbHScroll = FALSE;
+ SetLeftIndent( 0 );
+ }
+ }
+
+ if( bArrange )
+ ImplResizeControls();
+
+ ImplInitScrollBars();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::ImplInitScrollBars()
+{
+ Size aOutSz = maLBWindow.GetOutputSizePixel();
+
+ if ( mbVScroll )
+ {
+ USHORT nEntries = GetEntryList()->GetEntryCount();
+ USHORT nVisEntries = (USHORT) (aOutSz.Height() / GetEntryHeight());
+ mpVScrollBar->SetRangeMax( nEntries );
+ mpVScrollBar->SetVisibleSize( nVisEntries );
+ mpVScrollBar->SetPageSize( nVisEntries - 1 );
+ }
+
+ if ( mbHScroll )
+ {
+ mpHScrollBar->SetRangeMax( GetMaxEntryWidth() + HORZ_SCROLL );
+ mpHScrollBar->SetVisibleSize( (USHORT)aOutSz.Width() );
+ mpHScrollBar->SetLineSize( HORZ_SCROLL );
+ mpHScrollBar->SetPageSize( aOutSz.Width() - HORZ_SCROLL );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::ImplResizeControls()
+{
+ // Hier werden die Controls nur angeordnet, ob die Scrollbars
+ // sichtbar sein sollen wird bereits in ImplCheckScrollBars ermittelt.
+
+ Size aOutSz = GetOutputSizePixel();
+ long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
+ nSBWidth = CalcZoom( nSBWidth );
+
+ Size aInnerSz( aOutSz );
+ if ( mbVScroll )
+ aInnerSz.Width() -= nSBWidth;
+ if ( mbHScroll )
+ aInnerSz.Height() -= nSBWidth;
+
+ maLBWindow.SetPosSizePixel( Point(), aInnerSz );
+
+ // ScrollBarBox
+ if( mbVScroll && mbHScroll )
+ {
+ mpScrollBarBox->SetPosSizePixel( Point( aInnerSz.Width(), aInnerSz.Height() ),
+ Size( nSBWidth, nSBWidth ) );
+ mpScrollBarBox->Show();
+ }
+ else
+ {
+ mpScrollBarBox->Hide();
+ }
+
+ // vert. ScrollBar
+ if( mbVScroll )
+ {
+ mpVScrollBar->SetPosSizePixel( Point( aOutSz.Width()-nSBWidth, 0 ),
+ Size( nSBWidth, aInnerSz.Height() ) );
+ mpVScrollBar->Show();
+ }
+ else
+ {
+ mpVScrollBar->Hide();
+ SetTopEntry( 0 );
+ }
+
+ // horz. ScrollBar
+ if( mbHScroll )
+ {
+ mpHScrollBar->SetPosSizePixel( Point( 0, aOutSz.Height()-nSBWidth ),
+ Size( aInnerSz.Width(), nSBWidth ) );
+ mpHScrollBar->Show();
+ }
+ else
+ {
+ mpHScrollBar->Hide();
+ SetLeftIndent( 0 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ ImplCheckScrollBars();
+ }
+ else if ( ( nType == STATE_CHANGE_UPDATEMODE ) || ( nType == STATE_CHANGE_DATA ) )
+ {
+ BOOL bUpdate = IsUpdateMode();
+ maLBWindow.SetUpdateMode( bUpdate );
+// mpHScrollBar->SetUpdateMode( bUpdate );
+// mpVScrollBar->SetUpdateMode( bUpdate );
+ if ( bUpdate && IsReallyVisible() )
+ ImplCheckScrollBars();
+ }
+ else if( nType == STATE_CHANGE_ENABLE )
+ {
+ mpHScrollBar->Enable( IsEnabled() );
+ mpVScrollBar->Enable( IsEnabled() );
+ mpScrollBarBox->Enable( IsEnabled() );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_ZOOM )
+ {
+ maLBWindow.SetZoom( GetZoom() );
+ Resize();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ maLBWindow.SetControlFont( GetControlFont() );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ maLBWindow.SetControlForeground( GetControlForeground() );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ maLBWindow.SetControlBackground( GetControlBackground() );
+ }
+
+ Control::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+// if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+// (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+// {
+// maLBWindow.SetSettings( GetSettings() );
+// Resize();
+// }
+// else
+ Control::DataChanged( rDCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long ImplListBox::Notify( NotifyEvent& rNEvt )
+{
+ long nDone = 0;
+ if ( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
+ if ( rCEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
+ {
+ nDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
+ }
+ }
+ }
+
+ return nDone ? nDone : Window::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplListBox::HandleWheelAsCursorTravel( const CommandEvent& rCEvt )
+{
+ BOOL bDone = FALSE;
+ if ( rCEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
+ {
+ USHORT nKey = ( pData->GetDelta() < 0 ) ? KEY_DOWN : KEY_UP;
+ KeyEvent aKeyEvent( 0, KeyCode( nKey ) );
+ bDone = ProcessKeyInput( aKeyEvent );
+ }
+ }
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBox::SetMRUEntries( const XubString& rEntries, xub_Unicode cSep )
+{
+ BOOL bChanges = GetEntryList()->GetMRUCount() ? TRUE : FALSE;
+
+ // Remove old MRU entries
+ for ( USHORT n = GetEntryList()->GetMRUCount();n; )
+ maLBWindow.RemoveEntry( --n );
+
+ USHORT nMRUCount = 0;
+ USHORT nEntries = rEntries.GetTokenCount( cSep );
+ for ( USHORT nEntry = 0; nEntry < nEntries; nEntry++ )
+ {
+ XubString aEntry = rEntries.GetToken( nEntry, cSep );
+ // Accept only existing entries
+ if ( GetEntryList()->FindEntry( aEntry ) != LISTBOX_ENTRY_NOTFOUND )
+ {
+ ImplEntryType* pNewEntry = new ImplEntryType( aEntry );
+ maLBWindow.GetEntryList()->InsertEntry( nMRUCount++, pNewEntry, FALSE );
+ bChanges = TRUE;
+ }
+ }
+
+ if ( bChanges )
+ {
+ maLBWindow.GetEntryList()->SetMRUCount( nMRUCount );
+ SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 );
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString ImplListBox::GetMRUEntries( xub_Unicode cSep ) const
+{
+ String aEntries;
+ for ( USHORT n = 0; n < GetEntryList()->GetMRUCount(); n++ )
+ {
+ aEntries += GetEntryList()->GetEntryText( n );
+ if( n < ( GetEntryList()->GetMRUCount() - 1 ) )
+ aEntries += cSep;
+ }
+ return aEntries;
+}
+
+// =======================================================================
+
+ImplWin::ImplWin( Window* pParent, WinBits nWinStyle ) :
+ Control ( pParent, nWinStyle )
+{
+ SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
+ mbInUserDraw = FALSE;
+ mbUserDrawEnabled = FALSE;
+ mnItemPos = LISTBOX_ENTRY_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWin::MBDown()
+{
+ if( IsEnabled() )
+ maMBDownHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWin::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if( IsEnabled() )
+ {
+// Control::MouseButtonDown( rMEvt );
+ MBDown();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWin::Paint( const Rectangle& rRect )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if( IsEnabled() )
+ {
+ if( HasFocus() )
+ {
+ SetTextColor( rStyleSettings.GetHighlightTextColor() );
+ SetFillColor( rStyleSettings.GetHighlightColor() );
+ DrawRect( maFocusRect );
+ }
+ else
+ {
+ Color aColor = rStyleSettings.GetFieldTextColor();
+ if( IsControlForeground() )
+ aColor = GetControlForeground();
+ SetTextColor( aColor );
+ Erase( maFocusRect );
+ }
+ }
+ else // Disabled
+ {
+ SetTextColor( rStyleSettings.GetDisableColor() );
+ Erase( maFocusRect );
+ }
+
+ if ( IsUserDrawEnabled() )
+ {
+ mbInUserDraw = TRUE;
+ UserDrawEvent aUDEvt( this, maFocusRect, mnItemPos, 0 );
+ maUserDrawHdl.Call( &aUDEvt );
+ mbInUserDraw = FALSE;
+ }
+ else
+ {
+ DrawEntry( TRUE, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWin::DrawEntry( BOOL bDrawImage, BOOL bDrawText, BOOL bDrawTextAtImagePos )
+{
+ long nBorder = 1;
+ Size aOutSz = GetOutputSizePixel();
+
+ BOOL bImage = !!maImage;
+ if( bDrawImage && bImage )
+ {
+ Size aImgSz = maImage.GetSizePixel();
+ Point aPtImg( nBorder, ( ( aOutSz.Height() - aImgSz.Height() ) / 2 ) );
+
+ if ( !IsZoom() )
+ {
+ DrawImage( aPtImg, maImage );
+ }
+ else
+ {
+ aImgSz.Width() = CalcZoom( aImgSz.Width() );
+ aImgSz.Height() = CalcZoom( aImgSz.Height() );
+ DrawImage( aPtImg, aImgSz, maImage );
+ }
+ }
+
+ if( bDrawText && maString.Len() )
+ {
+ long nTextHeight = GetTextHeight();
+ Point aPtTxt( nBorder, (aOutSz.Height()-nTextHeight)/2 );
+ if ( !bDrawTextAtImagePos && ( bImage || IsUserDrawEnabled() ) )
+ {
+ long nMaxWidth = Max( maImage.GetSizePixel().Width(), maUserItemSize.Width() );
+ aPtTxt.X() += nMaxWidth + IMG_TXT_DISTANCE;
+ }
+ DrawText( aPtTxt, maString );
+ }
+
+ if( HasFocus() )
+ ShowFocus( maFocusRect );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWin::Resize()
+{
+ maFocusRect.SetSize( GetOutputSizePixel() );
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWin::GetFocus()
+{
+ ShowFocus( maFocusRect );
+ Invalidate();
+ Control::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWin::LoseFocus()
+{
+ HideFocus();
+ Invalidate();
+ Control::LoseFocus();
+}
+
+// =======================================================================
+
+ImplBtn::ImplBtn( Window* pParent, WinBits nWinStyle ) :
+ PushButton( pParent, nWinStyle ),
+ mbDown ( FALSE )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBtn::MBDown()
+{
+ if( IsEnabled() )
+ maMBDownHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBtn::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ //PushButton::MouseButtonDown( rMEvt );
+ if( IsEnabled() )
+ {
+ MBDown();
+ mbDown = TRUE;
+ }
+}
+
+// =======================================================================
+
+ImplListBoxFloatingWindow::ImplListBoxFloatingWindow( Window* pParent ) :
+ FloatingWindow( pParent, WB_NOBORDER )
+{
+ mpImplLB = NULL;
+ mnDDLineCount = 0;
+ mbAutoWidth = FALSE;
+
+ EnableSaveBackground();
+}
+
+// -----------------------------------------------------------------------
+
+long ImplListBoxFloatingWindow::PreNotify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if( !GetParent()->HasChildPathFocus( TRUE ) )
+ EndPopupMode();
+ }
+
+ return FloatingWindow::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxFloatingWindow::SetPosSizePixel( long nX, long nY, long nWidth, long nHeight, USHORT nFlags )
+{
+ FloatingWindow::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
+
+ // Fix #60890# ( MBA ): um auch im aufgeklappten Zustand der Listbox die Gr"o\se einfach zu einen
+ // Aufruf von Resize() "andern zu k"onnen, wird die Position hier ggf. angepa\t
+ if ( IsReallyVisible() && ( nFlags & WINDOW_POSSIZE_HEIGHT ) )
+ {
+ Point aPos = GetParent()->GetPosPixel();
+ aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
+
+ if ( nFlags & WINDOW_POSSIZE_X )
+ aPos.X() = nX;
+
+ if ( nFlags & WINDOW_POSSIZE_Y )
+ aPos.Y() = nY;
+
+ USHORT nIndex;
+ SetPosPixel( ImplCalcPos( this, Rectangle( aPos, GetParent()->GetSizePixel() ), FLOATWIN_POPUPMODE_DOWN, nIndex ) );
+ }
+
+// if( !IsReallyVisible() )
+ {
+ // Die ImplListBox erhaelt kein Resize, weil nicht sichtbar.
+ // Die Fenster muessen aber ein Resize() erhalten, damit die
+ // Anzahl der sichtbaren Eintraege fuer PgUp/PgDown stimmt.
+ // Die Anzahl kann auch nicht von List/Combobox berechnet werden,
+ // weil hierfuer auch die ggf. vorhandene vertikale Scrollbar
+ // beruecksichtigt werden muss.
+ mpImplLB->SetSizePixel( GetOutputSizePixel() );
+ ((Window*)mpImplLB)->Resize();
+ ((Window*)mpImplLB->GetMainWindow())->Resize();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size ImplListBoxFloatingWindow::CalcFloatSize()
+{
+ Size aFloatSz( maPrefSz );
+
+ long nLeft, nTop, nRight, nBottom;
+ GetBorder( nLeft, nTop, nRight, nBottom );
+
+ USHORT nLines = mpImplLB->GetEntryList()->GetEntryCount();
+ if ( mnDDLineCount && ( nLines > mnDDLineCount ) )
+ nLines = mnDDLineCount;
+
+ Size aSz = mpImplLB->CalcSize( nLines );
+ long nMaxHeight = aSz.Height() + nTop + nBottom;
+
+ if ( mnDDLineCount )
+ aFloatSz.Height() = nMaxHeight;
+
+ if( mbAutoWidth )
+ {
+ // AutoSize erstmal nur fuer die Breite...
+
+ aFloatSz.Width() = aSz.Width() + nLeft + nRight;
+ aFloatSz.Width() += nRight; // etwas mehr Platz sieht besser aus...
+
+ if ( aFloatSz.Height() < nMaxHeight )
+ {
+ // dann wird noch der vertikale Scrollbar benoetigt
+ long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
+ aFloatSz.Width() += nSBWidth;
+ }
+ }
+
+ if ( aFloatSz.Height() > nMaxHeight )
+ aFloatSz.Height() = nMaxHeight;
+
+ // Minimale Hoehe, falls Hoehe nicht auf Float-Hoehe eingestellt wurde.
+ // Der Parent vom FloatWin muss die DropDown-Combo/Listbox sein.
+ Size aParentSz = GetParent()->GetSizePixel();
+ if( aFloatSz.Height() < aParentSz.Height() )
+ aFloatSz.Height() = aParentSz.Height();
+
+ // Nicht schmaler als der Parent werden...
+ if( aFloatSz.Width() < aParentSz.Width() )
+ aFloatSz.Width() = aParentSz.Width();
+
+ // Hoehe auf Entries alignen...
+ long nInnerHeight = aFloatSz.Height() - nTop - nBottom;
+ long nEntryHeight = mpImplLB->GetEntryHeight();
+ if ( nInnerHeight % nEntryHeight )
+ {
+ nInnerHeight /= nEntryHeight;
+ nInnerHeight++;
+ nInnerHeight *= nEntryHeight;
+ aFloatSz.Height() = nInnerHeight + nTop + nBottom;
+ }
+
+ return aFloatSz;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplListBoxFloatingWindow::StartFloat( BOOL bStartTracking )
+{
+ if( !IsInPopupMode() )
+ {
+ Size aFloatSz = CalcFloatSize();
+
+ SetSizePixel( aFloatSz );
+ mpImplLB->SetSizePixel( GetOutputSizePixel() );
+
+ Size aSz = GetParent()->GetSizePixel();
+ Point aPos = GetParent()->GetPosPixel();
+ aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
+ Rectangle aRect( aPos, aSz );
+ StartPopupMode( aRect, FLOATWIN_POPUPMODE_DOWN );
+
+ USHORT nPos = mpImplLB->GetEntryList()->GetSelectEntryPos( 0 );
+ if( nPos != LISTBOX_ENTRY_NOTFOUND )
+ mpImplLB->SetTopEntry( nPos );
+
+ if( bStartTracking )
+ mpImplLB->GetMainWindow()->EnableMouseMoveSelect( TRUE );
+
+ if ( mpImplLB->GetMainWindow()->IsGrabFocusAllowed() )
+ mpImplLB->GetMainWindow()->GrabFocus();
+ }
+}
+
diff --git a/vcl/source/control/imgctrl.cxx b/vcl/source/control/imgctrl.cxx
new file mode 100644
index 000000000000..ac1758e8e27d
--- /dev/null
+++ b/vcl/source/control/imgctrl.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * $RCSfile: imgctrl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_IMGCTRL_CXX
+
+#include <imgctrl.hxx>
+
+// -----------------------------------------------------------------------
+
+ImageControl::ImageControl( Window* pParent, WinBits nStyle ) :
+ FixedImage( pParent, nStyle )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ImageControl::Resize()
+{
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ImageControl::UserDraw( const UserDrawEvent& rUDEvt )
+{
+ maBmp.Draw( rUDEvt.GetDevice(),
+ rUDEvt.GetRect().TopLeft(),
+ rUDEvt.GetRect().GetSize() );
+}
+
+// -----------------------------------------------------------------------
+
+void ImageControl::SetBitmap( const BitmapEx& rBmp )
+{
+ maBmp = rBmp;
+ StateChanged( STATE_CHANGE_DATA );
+}
diff --git a/vcl/source/control/longcurr.cxx b/vcl/source/control/longcurr.cxx
new file mode 100644
index 000000000000..2fe137dda52f
--- /dev/null
+++ b/vcl/source/control/longcurr.cxx
@@ -0,0 +1,873 @@
+/*************************************************************************
+ *
+ * $RCSfile: longcurr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define VCL_LONGCURR_CXX
+
+#include <sot/object.hxx>
+#define _TOOLS_BIGINT
+#include <sot/factory.hxx>
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _BIGINT_HXX
+#include <tools/bigint.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+
+#include <event.hxx>
+#include <svapp.hxx>
+#include <svdata.hxx>
+#include <longcurr.hxx>
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define FORMAT_LONGCURRENCY 4
+
+// =======================================================================
+
+static BigInt ImplPower10( USHORT n )
+{
+ USHORT i;
+ BigInt nValue = 1;
+
+ for ( i=0; i < n; i++ )
+ nValue *= 10;
+
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplNumericProcessKeyInput( Edit*, const KeyEvent& rKEvt,
+ BOOL bStrictFormat,
+ const International& rInter )
+{
+ if ( !bStrictFormat )
+ return FALSE;
+ else
+ {
+ sal_Unicode cChar = rKEvt.GetCharCode();
+ USHORT nGroup = rKEvt.GetKeyCode().GetGroup();
+
+ if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
+ (nGroup == KEYGROUP_MISC) ||
+ ((cChar >= '0') && (cChar <= '9')) ||
+ (rInter.IsNumThousandSep() && (cChar == rInter.GetNumThousandSep())) ||
+ (cChar == rInter.GetNumDecimalSep()) ||
+ (cChar == '-') )
+ return FALSE;
+ else
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplNumericGetValue( const XubString& rStr, BigInt& rValue,
+ USHORT nDecDigits, const International& rInter,
+ BOOL bCurrency = FALSE )
+{
+ XubString aStr = rStr;
+ XubString aStr1;
+ XubString aStr2;
+ USHORT nDecPos;
+ BOOL bNegative = FALSE;
+ xub_StrLen i;
+
+ // Reaktion auf leeren String
+ if ( !rStr.Len() )
+ return FALSE;
+
+ // Fuehrende und nachfolgende Leerzeichen entfernen
+ aStr.EraseLeadingAndTrailingChars( ' ' );
+
+ // Position des Dezimalpunktes suchen
+ nDecPos = aStr.Search( rInter.GetNumDecimalSep() );
+
+ if ( nDecPos != STRING_NOTFOUND )
+ {
+ aStr1 = aStr.Copy( 0, nDecPos );
+ aStr2 = aStr.Copy( nDecPos+1 );
+ }
+ else
+ aStr1 = aStr;
+
+ // Negativ ?
+ if ( bCurrency )
+ {
+ if ( (aStr.GetChar( 0 ) == '(') && (aStr.GetChar( aStr.Len()-1 ) == ')') )
+ bNegative = TRUE;
+ if ( !bNegative )
+ {
+ for ( i=0; i < aStr.Len(); i++ )
+ {
+ if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
+ break;
+ else if ( aStr.GetChar( i ) == '-' )
+ {
+ bNegative = TRUE;
+ break;
+ }
+ }
+ }
+ if ( !bNegative && bCurrency && aStr.Len() )
+ {
+ USHORT nFormat = rInter.GetCurrNegativeFormat();
+ if ( (nFormat == 3) || (nFormat == 6) ||
+ (nFormat == 7) || (nFormat == 10) )
+ {
+ for ( i = (USHORT)(aStr.Len()-1); i > 0; i++ )
+ {
+ if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
+ break;
+ else if ( aStr.GetChar( i ) == '-' )
+ {
+ bNegative = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( aStr1.GetChar( 0 ) == '-' )
+ bNegative = TRUE;
+ }
+
+ // Alle unerwuenschten Zeichen rauswerfen
+ for ( i=0; i < aStr1.Len(); )
+ {
+ if ( (aStr1.GetChar( i ) >= '0') && (aStr1.GetChar( i ) <= '9') )
+ i++;
+ else
+ aStr1.Erase( i, 1 );
+ }
+ for ( i=0; i < aStr2.Len(); )
+ {
+ if ( (aStr2.GetChar( i ) >= '0') && (aStr2.GetChar( i ) <= '9') )
+ i++;
+ else
+ aStr2.Erase( i, 1 );
+ }
+
+ if ( !aStr1.Len() && !aStr2.Len() )
+ return FALSE;
+
+ if ( !aStr1.Len() )
+ aStr1.Insert( '0' );
+ if ( bNegative )
+ aStr1.Insert( '-', 0 );
+
+ // Nachkommateil zurechtstutzen und dabei runden
+ BOOL bRound = FALSE;
+ if ( aStr2.Len() > nDecDigits )
+ {
+ if ( aStr2.GetChar( nDecDigits ) >= '5' )
+ bRound = TRUE;
+ aStr2.Erase( nDecDigits );
+ }
+ if ( aStr2.Len() < nDecDigits )
+ aStr2.Expand( nDecDigits, '0' );
+
+ aStr = aStr1;
+ aStr += aStr2;
+
+ // Bereichsueberpruefung
+ BigInt nValue( aStr );
+ if ( bRound )
+ {
+ if ( !bNegative )
+ nValue+=1;
+ else
+ nValue-=1;
+ }
+
+ rValue = nValue;
+
+ return TRUE;
+}
+
+// =======================================================================
+
+static BOOL ImplLongCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
+ BOOL, const International& rInter )
+{
+ // Es gibt hier kein sinnvolles StrictFormat, also alle
+ // Zeichen erlauben
+ return ImplNumericProcessKeyInput( pEdit, rKEvt, FALSE, rInter );
+}
+
+// -----------------------------------------------------------------------
+
+inline XubString ImplLongCurrencySetValue( BigInt nValue, USHORT nDecDigits,
+ const International& rInter )
+{
+ // Umwandeln in einen Waehrungsstring
+ return rInter.GetCurr( nValue, nDecDigits ); // ???
+}
+
+// -----------------------------------------------------------------------
+
+inline BOOL ImplLongCurrencyGetValue( const XubString& rStr, BigInt& rValue,
+ USHORT nDecDigits, const International& rInter )
+{
+ // Zahlenwert holen
+ return ImplNumericGetValue( rStr, rValue, nDecDigits, rInter, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplLongCurrencyReformat( const XubString& rStr, BigInt nMin, BigInt nMax,
+ USHORT nDecDigits,
+ const International& rInter, String& rOutStr,
+ LongCurrencyFormatter& rFormatter )
+{
+ BigInt nValue;
+ if ( !ImplNumericGetValue( rStr, nValue, nDecDigits, rInter, TRUE ) )
+ return TRUE;
+ else
+ {
+ BigInt nTempVal = nValue;
+ if ( nTempVal > nMax )
+ nTempVal = nMax;
+ else if ( nTempVal < nMin )
+ nTempVal = nMin;
+
+ if ( rFormatter.GetErrorHdl().IsSet() && (nValue != nTempVal) )
+ {
+ rFormatter.mnCorrectedValue = nTempVal;
+ if ( !rFormatter.GetErrorHdl().Call( &rFormatter ) )
+ {
+ rFormatter.mnCorrectedValue = 0;
+ return FALSE;
+ }
+ else
+ rFormatter.mnCorrectedValue = 0;
+ }
+
+ rOutStr = rInter.GetCurr( nTempVal, nDecDigits );
+ return TRUE;
+ }
+}
+
+// =======================================================================
+
+void LongCurrencyFormatter::ImpInit()
+{
+ mnFieldValue = 0;
+ mnLastValue = 0;
+ mnMin = 0;
+ mnMax = 0x7FFFFFFF;
+ mnMax *= 0x7FFFFFFF;
+ mnCorrectedValue = 0;
+ mnType = FORMAT_LONGCURRENCY;
+ SetDecimalDigits( 0 );
+}
+
+// -----------------------------------------------------------------------
+
+LongCurrencyFormatter::LongCurrencyFormatter()
+{
+ ImpInit();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyFormatter::ImplLoadRes( const ResId& rResId )
+{
+ ImpInit();
+
+ ResMgr* pMgr = Resource::GetResManager();
+ USHORT nMask = pMgr->ReadShort();
+
+ if ( NUMERICFORMATTER_MIN & nMask )
+ mnMin = pMgr->ReadLong();
+
+ if ( NUMERICFORMATTER_MAX & nMask )
+ mnMax = pMgr->ReadLong();
+
+ if ( NUMERICFORMATTER_STRICTFORMAT & nMask )
+ SetStrictFormat( (BOOL)pMgr->ReadShort() );
+
+ if ( NUMERICFORMATTER_I12 & nMask )
+ {
+ SetInternational( International( ResId( (RSHEADER_TYPE *)pMgr->GetClass() ) ) );
+ pMgr->Increment( pMgr->GetObjSize( (RSHEADER_TYPE *)pMgr->GetClass() ) );
+ }
+ if ( NUMERICFORMATTER_DECIMALDIGITS & nMask )
+ SetDecimalDigits( pMgr->ReadShort() );
+
+ if ( NUMERICFORMATTER_VALUE & nMask )
+ {
+ mnFieldValue = pMgr->ReadLong();
+ if ( mnFieldValue > mnMax )
+ mnFieldValue = mnMax;
+ else if ( mnFieldValue < mnMin )
+ mnFieldValue = mnMin;
+ mnLastValue = mnFieldValue;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+LongCurrencyFormatter::~LongCurrencyFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyFormatter::SetValue( BigInt nNewValue )
+{
+ SetUserValue( nNewValue );
+ mnFieldValue = mnLastValue;
+ ImplGetEmptyFieldValue() = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyFormatter::SetUserValue( BigInt nNewValue )
+{
+ if ( nNewValue > mnMax )
+ nNewValue = mnMax;
+ else if ( nNewValue < mnMin )
+ nNewValue = mnMin;
+ mnLastValue = nNewValue;
+
+ if ( !GetField() )
+ return;
+
+ XubString aStr = ImplLongCurrencySetValue( nNewValue, GetDecimalDigits(), GetInternational() );
+ if ( GetField()->HasFocus() )
+ {
+ Selection aSelection = GetField()->GetSelection();
+ GetField()->SetText( aStr );
+ GetField()->SetSelection( aSelection );
+ }
+ else
+ GetField()->SetText( aStr );
+ MarkToBeReformatted( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+BigInt LongCurrencyFormatter::GetValue() const
+{
+ if ( !GetField() )
+ return 0;
+
+ BigInt nTempValue;
+ if ( ImplLongCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(),
+ GetInternational() ) )
+ {
+ if ( nTempValue > mnMax )
+ nTempValue = mnMax;
+ else if ( nTempValue < mnMin )
+ nTempValue = mnMin;
+ return nTempValue;
+ }
+ else
+ return mnLastValue;
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyFormatter::Reformat()
+{
+ if ( !GetField() )
+ return;
+
+ if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
+ return;
+
+ XubString aStr;
+ BOOL bOK = ImplLongCurrencyReformat( GetField()->GetText(), mnMin, mnMax,
+ GetDecimalDigits(), GetInternational(), aStr, *this );
+ if ( !bOK )
+ return;
+
+ if ( aStr.Len() )
+ {
+ GetField()->SetText( aStr );
+ MarkToBeReformatted( FALSE );
+ ImplLongCurrencyGetValue( aStr, mnLastValue, GetDecimalDigits(), GetInternational() );
+ }
+ else
+ SetValue( mnLastValue );
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyFormatter::ReformatAll()
+{
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyFormatter::SetMin( BigInt nNewMin )
+{
+ mnMin = nNewMin;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyFormatter::SetMax( BigInt nNewMax )
+{
+ mnMax = nNewMax;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyFormatter::SetDecimalDigits( USHORT nDigits )
+{
+ International aInter( GetInternational() );
+ aInter.SetCurrDigits( nDigits );
+ SetInternational( aInter );
+
+// ReformatAll(); // macht SetInternational()
+}
+
+// -----------------------------------------------------------------------
+
+USHORT LongCurrencyFormatter::GetDecimalDigits() const
+{
+ return GetInternational().GetCurrDigits();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL LongCurrencyFormatter::IsValueModified() const
+{
+ if ( ImplGetEmptyFieldValue() )
+ return !IsEmptyValue();
+ else if ( GetValue() != mnFieldValue )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyFormatter::SetEmptyValue()
+{
+ GetField()->SetText( ImplGetSVEmptyStr() );
+ ImplGetEmptyFieldValue() = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BigInt LongCurrencyFormatter::Normalize( BigInt nValue ) const
+{
+ return (nValue * ImplPower10( GetDecimalDigits() ) );
+}
+
+// -----------------------------------------------------------------------
+
+BigInt LongCurrencyFormatter::Denormalize( BigInt nValue ) const
+{
+ BigInt nFactor = ImplPower10( GetDecimalDigits() );
+ BigInt nTmp = nFactor;
+ nTmp /= 2;
+ nTmp += nValue;
+ nTmp /= nFactor;
+ return nTmp;
+}
+
+// =======================================================================
+
+void ImplNewLongCurrencyFieldValue( LongCurrencyField* pField, BigInt nNewValue )
+{
+ Selection aSelect = pField->GetSelection();
+ aSelect.Justify();
+ XubString aText = pField->GetText();
+ BOOL bLastSelected = ((xub_StrLen)aSelect.Max() == aText.Len()) ? TRUE : FALSE;
+
+ BigInt nOldLastValue = pField->mnLastValue;
+ pField->SetUserValue( nNewValue );
+ pField->mnLastValue = nOldLastValue;
+
+ if ( bLastSelected )
+ {
+ if ( !aSelect.Len() )
+ aSelect.Min() = SELECTION_MAX;
+ aSelect.Max() = SELECTION_MAX;
+ }
+ pField->SetSelection( aSelect );
+ pField->SetModifyFlag();
+ pField->Modify();
+}
+
+// =======================================================================
+
+LongCurrencyField::LongCurrencyField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle )
+{
+ SetField( this );
+ mnSpinSize = 1;
+ mnFirst = mnMin;
+ mnLast = mnMax;
+
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+LongCurrencyField::LongCurrencyField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_NUMERICFIELD )
+{
+ rResId.SetRT( RSC_NUMERICFIELD );
+ WinBits nStyle = ImplInitRes( rResId ) ;
+ SpinField::ImplInit( pParent, nStyle );
+
+ SetField( this );
+ mnSpinSize = 1;
+ mnFirst = mnMin;
+ mnLast = mnMax;
+
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyField::ImplLoadRes( const ResId& rResId )
+{
+ SpinField::ImplLoadRes( rResId );
+ LongCurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+
+ USHORT nMask = ReadShortRes();
+ if ( CURRENCYFIELD_FIRST & nMask )
+ mnFirst = ReadLongRes();
+
+ if ( CURRENCYFIELD_LAST & nMask )
+ mnLast = ReadLongRes();
+
+ if ( CURRENCYFIELD_SPINSIZE & nMask )
+ mnSpinSize = ReadLongRes();
+}
+
+// -----------------------------------------------------------------------
+
+LongCurrencyField::~LongCurrencyField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long LongCurrencyField::PreNotify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ if ( ImplLongCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), GetInternational() ) )
+ return 1;
+ }
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long LongCurrencyField::Notify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_GETFOCUS )
+ {
+ MarkToBeReformatted( FALSE );
+ }
+ else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() )
+ {
+ Reformat();
+ SpinField::Modify();
+ }
+ }
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyField::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyField::Up()
+{
+ BigInt nValue = GetValue();
+ nValue += mnSpinSize;
+ if ( nValue > mnMax )
+ nValue = mnMax;
+
+ ImplNewLongCurrencyFieldValue( this, nValue );
+ SpinField::Up();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyField::Down()
+{
+ BigInt nValue = GetValue();
+ nValue -= mnSpinSize;
+ if ( nValue < mnMin )
+ nValue = mnMin;
+
+ ImplNewLongCurrencyFieldValue( this, nValue );
+ SpinField::Down();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyField::First()
+{
+ ImplNewLongCurrencyFieldValue( this, mnFirst );
+ SpinField::First();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyField::Last()
+{
+ ImplNewLongCurrencyFieldValue( this, mnLast );
+ SpinField::Last();
+}
+
+// =======================================================================
+
+LongCurrencyBox::LongCurrencyBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+LongCurrencyBox::LongCurrencyBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_NUMERICFIELD )
+{
+ SetField( this );
+ WinBits nStyle = ImplInitRes( rResId ) ;
+ ComboBox::ImplLoadRes( rResId );
+ LongCurrencyFormatter::ImplLoadRes( rResId );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+LongCurrencyBox::~LongCurrencyBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long LongCurrencyBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ if ( ImplLongCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), GetInternational() ) )
+ return 1;
+ }
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long LongCurrencyBox::Notify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_GETFOCUS )
+ {
+ MarkToBeReformatted( FALSE );
+ }
+ else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() )
+ {
+ Reformat();
+ ComboBox::Modify();
+ }
+ }
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyBox::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyBox::ReformatAll()
+{
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ ImplLongCurrencyReformat( GetEntry( i ), mnMin, mnMax,
+ GetDecimalDigits(), GetInternational(),
+ aStr, *this );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ LongCurrencyFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyBox::InsertValue( BigInt nValue, USHORT nPos )
+{
+ XubString aStr = ImplLongCurrencySetValue( nValue, GetDecimalDigits(), GetInternational() );
+ ComboBox::InsertEntry( aStr, nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void LongCurrencyBox::RemoveValue( BigInt nValue )
+{
+ XubString aStr = ImplLongCurrencySetValue( nValue, GetDecimalDigits(), GetInternational() );
+ ComboBox::RemoveEntry( aStr );
+}
+
+// -----------------------------------------------------------------------
+
+BigInt LongCurrencyBox::GetValue( USHORT nPos ) const
+{
+ BigInt nValue = 0;
+ ImplLongCurrencyGetValue( ComboBox::GetEntry( nPos ), nValue,
+ GetDecimalDigits(), GetInternational() );
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT LongCurrencyBox::GetValuePos( BigInt nValue ) const
+{
+ XubString aStr = ImplLongCurrencySetValue( nValue, GetDecimalDigits(), GetInternational() );
+ return ComboBox::GetEntryPos( aStr );
+}
+
+// =======================================================================
+
+XubString International::GetCurr( const BigInt &rNumber, USHORT nDigits ) const
+{
+ DBG_ASSERT( nDigits < 10, "LongCurrency duerfen nur maximal 9 Nachkommastellen haben" );
+
+ if ( rNumber.IsZero() || (long)rNumber )
+ return GetCurr( (long)rNumber, nDigits );
+
+ BigInt aTmp( ImplPower10( nDigits ) );
+ BigInt aInteger( rNumber );
+ aInteger.Abs();
+ aInteger /= aTmp;
+ BigInt aFraction( rNumber );
+ aFraction.Abs();
+ aFraction %= aTmp;
+ if ( !aInteger.IsZero() )
+ {
+ aFraction += aTmp;
+ aTmp = 1000000000L;
+ }
+ if ( rNumber.IsNeg() )
+ aFraction *= -1;
+
+ XubString aTemplate = GetCurr( (long)aFraction, nDigits );
+ while( !aInteger.IsZero() )
+ {
+ aFraction = aInteger;
+ aFraction %= aTmp;
+ aInteger /= aTmp;
+ if( !aInteger.IsZero() )
+ aFraction += aTmp;
+
+ XubString aFractionStr = GetNum( (long)aFraction, 0 );
+
+ xub_StrLen nSPos = aTemplate.Search( '1' );
+ if ( aFractionStr.Len() == 1 )
+ aTemplate.SetChar( nSPos, aFractionStr.GetChar( 0 ) );
+ else
+ {
+ aTemplate.Erase( nSPos, 1 );
+ aTemplate.Insert( aFractionStr, nSPos );
+ }
+ }
+
+ return aTemplate;
+}
diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx
new file mode 100644
index 000000000000..f1e6eaadef8b
--- /dev/null
+++ b/vcl/source/control/lstbox.cxx
@@ -0,0 +1,1242 @@
+/*************************************************************************
+ *
+ * $RCSfile: lstbox.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_LSTBOX_CXX
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SCRBAR_HXX
+#include <scrbar.hxx>
+#endif
+#ifndef _SV_BUTTON_HXX
+#include <button.hxx>
+#endif
+#ifndef _SV_EDIT_HXX
+#include <edit.hxx>
+#endif
+#ifndef _SV_SUBEDIT_HXX
+#include <subedit.hxx>
+#endif
+#ifndef _SV_ILSTBOX_HXX
+#include <ilstbox.hxx>
+#endif
+#ifndef _SV_LSTBOX_HXX
+#include <lstbox.hxx>
+#endif
+#ifndef _SV_COMBOBOX_HXX
+#include <combobox.hxx>
+#endif
+
+#pragma hdrstop
+
+ // =======================================================================
+
+ListBox::ListBox( WindowType nType ) : Control( nType )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+ListBox::ListBox( Window* pParent, WinBits nStyle ) : Control( WINDOW_LISTBOX )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+ListBox::ListBox( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_LISTBOX )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_LISTBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+ListBox::~ListBox()
+{
+ delete mpImplLB;
+
+ // Beim zerstoeren des FloatWins macht TH ein GrabFocus auf den Parent,
+ // also diese ListBox => PreNotify()...
+ mpImplLB = NULL;
+
+ delete mpFloatWin;
+ delete mpImplWin;
+ delete mpBtn;
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::ImplInitData()
+{
+ mpFloatWin = NULL;
+ mpImplWin = NULL;
+ mpBtn = NULL;
+
+ mnDDHeight = 0;
+ mbDDAutoSize = TRUE;
+ mnSaveValue = LISTBOX_ENTRY_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::ImplInit( Window* pParent, WinBits nStyle )
+{
+ nStyle = ImplInitStyle( nStyle );
+ if ( !(nStyle & WB_NOBORDER) && ( nStyle & WB_DROPDOWN ) )
+ nStyle |= WB_BORDER;
+
+ Control::ImplInit( pParent, nStyle, NULL );
+ SetBackground();
+
+ if( nStyle & WB_DROPDOWN )
+ {
+ long nLeft, nTop, nRight, nBottom;
+ GetBorder( nLeft, nTop, nRight, nBottom );
+ mnDDHeight = (USHORT)(GetTextHeight() + nTop + nBottom + 4);
+
+ mpFloatWin = new ImplListBoxFloatingWindow( this );
+ mpFloatWin->SetAutoWidth( TRUE );
+ mpFloatWin->SetPopupModeEndHdl( LINK( this, ListBox, ImplPopupModeEndHdl ) );
+
+ mpImplWin = new ImplWin( this, WB_NOBORDER );
+ mpImplWin->SetMBDownHdl( LINK( this, ListBox, ImplClickBtnHdl ) );
+ mpImplWin->SetUserDrawHdl( LINK( this, ListBox, ImplUserDrawHdl ) );
+ mpImplWin->Show();
+
+ mpBtn = new ImplBtn( this, WB_NOLIGHTBORDER | WB_RECTSTYLE );
+ ImplInitDropDownButton( mpBtn );
+ mpBtn->SetMBDownHdl( LINK( this, ListBox, ImplClickBtnHdl ) );
+ mpBtn->Show();
+
+ }
+
+ Window* pLBParent = this;
+ if ( mpFloatWin )
+ pLBParent = mpFloatWin;
+ mpImplLB = new ImplListBox( pLBParent, nStyle&(~WB_BORDER) );
+ mpImplLB->SetSelectHdl( LINK( this, ListBox, ImplSelectHdl ) );
+ mpImplLB->SetCancelHdl( LINK( this, ListBox, ImplCancelHdl ) );
+ mpImplLB->SetDoubleClickHdl( LINK( this, ListBox, ImplDoubleClickHdl ) );
+ mpImplLB->SetUserDrawHdl( LINK( this, ListBox, ImplUserDrawHdl ) );
+ mpImplLB->SetPosPixel( Point() );
+ mpImplLB->Show();
+
+ if ( mpFloatWin )
+ {
+ mpFloatWin->SetImplListBox( mpImplLB );
+ mpImplLB->SetSelectionChangedHdl( LINK( this, ListBox, ImplSelectionChangedHdl ) );
+ }
+ else
+ mpImplLB->GetMainWindow()->AllowGrabFocus( TRUE );
+
+ SetCompoundControl( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits ListBox::ImplInitStyle( WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOTABSTOP) )
+ nStyle |= WB_TABSTOP;
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::ImplLoadRes( const ResId& rResId )
+{
+ Control::ImplLoadRes( rResId );
+
+ USHORT nSelPos = ReadShortRes();
+ USHORT nNumber = ReadShortRes();
+
+ for( USHORT i = 0; i < nNumber; i++ )
+ {
+ USHORT nPos = InsertEntry( ReadStringRes(), LISTBOX_APPEND );
+
+ long nId = ReadLongRes();
+ if( nId )
+ SetEntryData( nPos, (void *)nId ); // ID als UserData
+ }
+
+ if( nSelPos < nNumber )
+ SelectEntryPos( nSelPos );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ListBox, ImplSelectHdl, void*, EMPTYARG )
+{
+ BOOL bPopup = IsInDropDown();
+ if( IsDropDownBox() )
+ {
+ if( !mpImplLB->IsTravelSelect() )
+ {
+ mpFloatWin->EndPopupMode();
+ mpImplWin->GrabFocus();
+ }
+
+ mpImplWin->SetItemPos( GetSelectEntryPos() );
+ mpImplWin->SetString( GetSelectEntry() );
+ if( mpImplLB->GetEntryList()->HasImages() )
+ {
+ Image aImage = mpImplLB->GetEntryList()->GetEntryImage( GetSelectEntryPos() );
+ mpImplWin->SetImage( aImage );
+ }
+ mpImplWin->Invalidate();
+ }
+
+ if ( mpImplLB->IsSelectionChanged() || ( bPopup && !IsMultiSelectionEnabled() ) )
+ Select();
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ListBox, ImplCancelHdl, void*, EMPTYARG )
+{
+ if( IsInDropDown() )
+ mpFloatWin->EndPopupMode();
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ListBox, ImplSelectionChangedHdl, void*, n )
+{
+ if ( !mpImplLB->IsTrackingSelect() )
+ {
+ USHORT nChanged = (USHORT)(ULONG)n;
+ const ImplEntryList* pEntryList = mpImplLB->GetEntryList();
+ if ( pEntryList->IsEntryPosSelected( nChanged ) )
+ {
+ // Sollte mal ein ImplPaintEntry werden...
+ if ( nChanged < pEntryList->GetMRUCount() )
+ nChanged = pEntryList->FindEntry( pEntryList->GetEntryText( nChanged ), MATCH_CASE, STRING_LEN, pEntryList->GetMRUCount() );
+ mpImplWin->SetItemPos( nChanged );
+ mpImplWin->SetString( mpImplLB->GetEntryList()->GetEntryText( nChanged ) );
+ if( mpImplLB->GetEntryList()->HasImages() )
+ {
+ Image aImage = mpImplLB->GetEntryList()->GetEntryImage( nChanged );
+ mpImplWin->SetImage( aImage );
+ }
+ mpImplWin->Invalidate();
+ }
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ListBox, ImplDoubleClickHdl, void*, p )
+{
+ DoubleClick();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ListBox, ImplClickBtnHdl, void*, EMPTYARG )
+{
+ if( !mpFloatWin->IsInPopupMode() )
+ {
+ mpImplWin->GrabFocus();
+ mpBtn->SetPressed( TRUE );
+ mpFloatWin->StartFloat( TRUE );
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ListBox, ImplPopupModeEndHdl, void*, p )
+{
+ mpBtn->SetPressed( FALSE );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
+{
+ mpImplLB->GetMainWindow()->ImplInitSettings( TRUE, TRUE, TRUE );
+
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Font aFont = mpImplLB->GetMainWindow()->GetDrawPixelFont( pDev );
+ OutDevType eOutDevType = pDev->GetOutDevType();
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ pDev->SetTextFillColor();
+
+ // Border/Background
+ pDev->SetLineColor();
+ pDev->SetFillColor();
+ BOOL bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
+ BOOL bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
+ if ( bBorder || bBackground )
+ {
+ Rectangle aRect( aPos, aSize );
+ if ( bBorder )
+ {
+ DecorationView aDecoView( pDev );
+ aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
+ }
+ if ( bBackground )
+ {
+ pDev->SetFillColor( GetControlBackground() );
+ pDev->DrawRect( aRect );
+ }
+ }
+
+ // Inhalt
+ if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
+ {
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ }
+ else
+ {
+ if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ pDev->SetTextColor( rStyleSettings.GetDisableColor() );
+ }
+ else
+ {
+ pDev->SetTextColor( GetTextColor() );
+ }
+ }
+
+ long nOnePixel = GetDrawPixel( pDev, 1 );
+ if ( IsDropDownBox() )
+ {
+ XubString aText = GetSelectEntry();
+ long nTextHeight = pDev->GetTextHeight();
+ long nTextWidth = pDev->GetTextWidth( aText );
+ long nOffX = 3*nOnePixel;
+ long nOffY = (aSize.Height()-nTextHeight) / 2;
+
+ // Clipping?
+ if ( (nOffY < 0) ||
+ ((nOffY+nTextHeight) > aSize.Height()) ||
+ ((nOffX+nTextWidth) > aSize.Width()) )
+ {
+ Rectangle aClip( aPos, aSize );
+ if ( nTextHeight > aSize.Height() )
+ aClip.Bottom() += nTextHeight-aSize.Height()+1; // Damit HP-Drucker nicht 'weg-optimieren'
+ pDev->IntersectClipRegion( aClip );
+ }
+
+ pDev->DrawText( Point( aPos.X()+nOffX, aPos.Y()+nOffY ), aText );
+ }
+ else
+ {
+ long nTextHeight = pDev->GetTextHeight();
+ USHORT nLines = (USHORT)(aSize.Height() / nTextHeight);
+ Rectangle aClip( aPos, aSize );
+ pDev->IntersectClipRegion( aClip );
+ if ( !nLines )
+ nLines = 1;
+ for ( USHORT n = 0; n < nLines; n++ )
+ {
+ USHORT nEntry = n+mpImplLB->GetTopEntry();
+ BOOL bSelected = mpImplLB->GetEntryList()->IsEntryPosSelected( nEntry );
+ if ( bSelected )
+ {
+ pDev->SetFillColor( COL_BLACK );
+ pDev->DrawRect( Rectangle( Point( aPos.X(), aPos.Y() + n*nTextHeight ),
+ Point( aPos.X() + aSize.Width(), aPos.Y() + (n+1)*nTextHeight + 2*nOnePixel ) ) );
+ pDev->SetFillColor();
+ pDev->SetTextColor( COL_WHITE );
+ }
+ pDev->DrawText( Point( aPos.X() + 3*nOnePixel, aPos.Y() + n*nTextHeight + nOnePixel ), mpImplLB->GetEntryList()->GetEntryText( nEntry ) );
+ if ( bSelected )
+ pDev->SetTextColor( COL_BLACK );
+ }
+ }
+
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::GetFocus()
+{
+ if ( mpImplLB )
+ {
+ if( IsDropDownBox() )
+ mpImplWin->GrabFocus();
+ else
+ mpImplLB->GrabFocus();
+ }
+
+ Control::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::LoseFocus()
+{
+ if( IsDropDownBox() )
+ mpImplWin->HideFocus();
+ else
+ mpImplLB->HideFocus();
+
+ Control::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ Resize();
+ mpImplLB->Resize(); // Wird nicht durch ListBox::Resize() gerufen, wenn sich die ImplLB nicht aendert.
+
+ if ( mpImplWin )
+ {
+ mpImplWin->SetSettings( GetSettings() ); // Falls noch nicht eingestellt...
+ ImplInitFieldSettings( mpImplWin, TRUE, TRUE, TRUE );
+
+ mpBtn->SetSettings( GetSettings() );
+ ImplInitDropDownButton( mpBtn );
+ }
+
+
+ if ( IsDropDownBox() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::EnableAutoSize( BOOL bAuto )
+{
+ mbDDAutoSize = bAuto;
+ if ( mpFloatWin )
+ {
+ if ( bAuto && !mpFloatWin->GetDropDownLineCount() )
+ mpFloatWin->SetDropDownLineCount( 5 );
+ else if ( !bAuto )
+ mpFloatWin->SetDropDownLineCount( 0 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetDropDownLineCount( USHORT nLines )
+{
+ if ( mpFloatWin )
+ mpFloatWin->SetDropDownLineCount( nLines );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::GetDropDownLineCount() const
+{
+ USHORT nLines = 0;
+ if ( mpFloatWin )
+ nLines = mpFloatWin->GetDropDownLineCount();
+ return nLines;
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetPosSizePixel( long nX, long nY, long nWidth, long nHeight, USHORT nFlags )
+{
+ if( IsDropDownBox() && ( nFlags & WINDOW_POSSIZE_SIZE ) )
+ {
+ Size aPrefSz = mpFloatWin->GetPrefSize();
+ if ( ( nFlags & WINDOW_POSSIZE_HEIGHT ) && ( nHeight > mnDDHeight ) )
+ aPrefSz.Height() = nHeight-mnDDHeight;
+ if ( nFlags & WINDOW_POSSIZE_WIDTH )
+ aPrefSz.Width() = nWidth;
+ mpFloatWin->SetPrefSize( aPrefSz );
+
+ if ( IsAutoSizeEnabled() )
+ nHeight = mnDDHeight;
+ }
+
+ Control::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::Resize()
+{
+ Size aOutSz = GetOutputSizePixel();
+ if( IsDropDownBox() )
+ {
+ long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
+ nSBWidth = CalcZoom( nSBWidth );
+ mpImplWin->SetPosSizePixel( 0, 0, aOutSz.Width() - nSBWidth, aOutSz.Height() );
+ mpBtn->SetPosSizePixel( aOutSz.Width() - nSBWidth, 0, nSBWidth, aOutSz.Height() );
+ }
+ else
+ {
+ mpImplLB->SetSizePixel( aOutSz );
+ }
+
+ // FloatingWindow-Groesse auch im unsichtbare Zustand auf Stand halten,
+ // weil KEY_PGUP/DOWN ausgewertet wird...
+ if ( mpFloatWin )
+ mpFloatWin->SetSizePixel( mpFloatWin->CalcFloatSize() );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::StateChanged( StateChangedType nType )
+{
+ if( nType == STATE_CHANGE_READONLY )
+ {
+ if( mpImplWin )
+ mpImplWin->Enable( !IsReadOnly() );
+ if( mpBtn )
+ mpBtn->Enable( !IsReadOnly() );
+ }
+ else if( nType == STATE_CHANGE_ENABLE )
+ {
+ mpImplLB->Enable( IsEnabled() );
+ if( mpImplWin )
+ {
+ mpImplWin->Enable( IsEnabled() );
+ mpImplWin->Invalidate();
+ }
+ if( mpBtn )
+ mpBtn->Enable( IsEnabled() );
+ }
+ else if( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ mpImplLB->SetUpdateMode( IsUpdateMode() );
+ }
+ else if ( nType == STATE_CHANGE_ZOOM )
+ {
+ mpImplLB->SetZoom( GetZoom() );
+ if ( mpImplWin )
+ {
+ mpImplWin->SetZoom( GetZoom() );
+ mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() );
+ mpImplWin->Invalidate();
+ }
+ Resize();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ mpImplLB->SetControlFont( GetControlFont() );
+ if ( mpImplWin )
+ {
+ mpImplWin->SetControlFont( GetControlFont() );
+ mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() );
+ mpImplWin->Invalidate();
+ }
+ Resize();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ mpImplLB->SetControlForeground( GetControlForeground() );
+ if ( mpImplWin )
+ {
+ mpImplWin->SetControlForeground( GetControlForeground() );
+ mpImplWin->SetTextColor( GetControlForeground() );
+ mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() );
+ mpImplWin->Invalidate();
+ }
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ mpImplLB->SetControlBackground( GetControlBackground() );
+ if ( mpImplWin )
+ {
+ mpImplWin->SetBackground( mpImplLB->GetMainWindow()->GetControlBackground() );
+ mpImplWin->SetControlBackground( mpImplLB->GetMainWindow()->GetControlBackground() );
+ mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() );
+ mpImplWin->Invalidate();
+ }
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ mpImplLB->GetMainWindow()->EnableSort( ( GetStyle() & WB_SORT ) ? TRUE : FALSE );
+ }
+
+ Control::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+long ListBox::PreNotify( NotifyEvent& rNEvt )
+{
+ long nDone = 0;
+ if ( mpImplLB )
+ {
+ if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( rNEvt.GetWindow() == mpImplWin ) )
+ {
+ KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
+ switch( aKeyEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_DOWN:
+ {
+ if( mpFloatWin && !mpFloatWin->IsInPopupMode() &&
+ aKeyEvt.GetKeyCode().IsMod2() )
+ {
+ mpBtn->SetPressed( TRUE );
+ mpFloatWin->StartFloat( FALSE );
+ nDone = 1;
+ }
+ else
+ {
+ nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
+ }
+ }
+ break;
+ case KEY_UP:
+ {
+ if( mpFloatWin && mpFloatWin->IsInPopupMode() &&
+ aKeyEvt.GetKeyCode().IsMod2() )
+ {
+ mpFloatWin->EndPopupMode();
+ nDone = 1;
+ }
+ else
+ {
+ nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
+ }
+ }
+ break;
+ case KEY_RETURN:
+ {
+ if( IsInDropDown() )
+ {
+ mpImplLB->ProcessKeyInput( aKeyEvt );
+ nDone = 1;
+ }
+ }
+ break;
+
+ default:
+ nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
+ }
+ }
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( IsInDropDown() && !HasChildPathFocus( TRUE ) )
+ mpFloatWin->EndPopupMode();
+ }
+ else if ( (rNEvt.GetType() == EVENT_COMMAND) &&
+ (rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL) &&
+ (rNEvt.GetWindow() == mpImplWin) )
+ {
+ nDone = mpImplLB->HandleWheelAsCursorTravel( *rNEvt.GetCommandEvent() );
+ }
+ }
+
+ return nDone ? nDone : Control::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::Clear()
+{
+ mpImplLB->Clear();
+ if( IsDropDownBox() )
+ {
+ mpImplWin->SetItemPos( LISTBOX_ENTRY_NOTFOUND );
+ mpImplWin->SetString( ImplGetSVEmptyStr() );
+ Image aImage;
+ mpImplWin->SetImage( aImage );
+ mpImplWin->Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetNoSelection()
+{
+ mpImplLB->SetNoSelection();
+ if( IsDropDownBox() )
+ {
+ mpImplWin->SetItemPos( LISTBOX_ENTRY_NOTFOUND );
+ mpImplWin->SetString( ImplGetSVEmptyStr() );
+ Image aImage;
+ mpImplWin->SetImage( aImage );
+ mpImplWin->Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::InsertEntry( const XubString& rStr, USHORT nPos )
+{
+ USHORT nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr );
+ nRealPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ return nRealPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::InsertEntry( const Image& rImage, USHORT nPos )
+{
+ USHORT nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rImage );
+ nRealPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ return nRealPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::InsertEntry( const XubString& rStr, const Image& rImage, USHORT nPos )
+{
+ USHORT nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr, rImage );
+ nRealPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ return nRealPos;
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::RemoveEntry( const XubString& rStr )
+{
+ RemoveEntry( GetEntryPos( rStr ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::RemoveEntry( USHORT nPos )
+{
+ mpImplLB->RemoveEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::GetEntryPos( const XubString& rStr ) const
+{
+ USHORT nPos = mpImplLB->GetEntryList()->FindEntry( rStr, MATCH_CASE, STRING_LEN, mpImplLB->GetEntryList()->GetMRUCount() );
+ if ( nPos != LISTBOX_ENTRY_NOTFOUND )
+ nPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::GetEntryPos( const void* pData ) const
+{
+ USHORT nPos = mpImplLB->GetEntryList()->FindEntry( pData );
+ if ( nPos != LISTBOX_ENTRY_NOTFOUND )
+ nPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+XubString ListBox::GetEntry( USHORT nPos ) const
+{
+ return mpImplLB->GetEntryList()->GetEntryText( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::GetEntryCount() const
+{
+ return mpImplLB->GetEntryList()->GetEntryCount() - mpImplLB->GetEntryList()->GetMRUCount();
+}
+
+// -----------------------------------------------------------------------
+
+XubString ListBox::GetSelectEntry( USHORT nIndex ) const
+{
+ return GetEntry( GetSelectEntryPos( nIndex ) );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::GetSelectEntryCount() const
+{
+ return mpImplLB->GetEntryList()->GetSelectEntryCount();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::GetSelectEntryPos( USHORT nIndex ) const
+{
+ USHORT nPos = mpImplLB->GetEntryList()->GetSelectEntryPos( nIndex );
+ if ( nPos != LISTBOX_ENTRY_NOTFOUND )
+ {
+ if ( nPos < mpImplLB->GetEntryList()->GetMRUCount() )
+ nPos = mpImplLB->GetEntryList()->FindEntry( mpImplLB->GetEntryList()->GetEntryText( nPos ), MATCH_CASE, STRING_LEN, mpImplLB->GetEntryList()->GetMRUCount() );
+ nPos -= mpImplLB->GetEntryList()->GetMRUCount();
+ }
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ListBox::IsEntrySelected( const XubString& rStr ) const
+{
+ return IsEntryPosSelected( GetEntryPos( rStr ) );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ListBox::IsEntryPosSelected( USHORT nPos ) const
+{
+ return mpImplLB->GetEntryList()->IsEntryPosSelected( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SelectEntry( const XubString& rStr, BOOL bSelect )
+{
+ SelectEntryPos( GetEntryPos( rStr ), bSelect );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SelectEntryPos( USHORT nPos, BOOL bSelect )
+{
+ if ( nPos < mpImplLB->GetEntryList()->GetEntryCount() )
+ mpImplLB->SelectEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), bSelect );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetEntryData( USHORT nPos, void* pNewData )
+{
+ mpImplLB->SetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount(), pNewData );
+}
+
+// -----------------------------------------------------------------------
+
+void* ListBox::GetEntryData( USHORT nPos ) const
+{
+ return mpImplLB->GetEntryList()->GetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetTopEntry( USHORT nPos )
+{
+ mpImplLB->SetTopEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::GetTopEntry() const
+{
+ USHORT nPos = GetEntryCount() ? mpImplLB->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND;
+ if ( nPos < mpImplLB->GetEntryList()->GetMRUCount() )
+ nPos = 0;
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ListBox::IsTravelSelect() const
+{
+ return mpImplLB->IsTravelSelect();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ListBox::IsInDropDown() const
+{
+ return mpFloatWin && mpFloatWin->IsInPopupMode();
+}
+
+// -----------------------------------------------------------------------
+
+long ListBox::CalcWindowSizePixel( USHORT nLines ) const
+{
+ return mpImplLB->GetEntryHeight() * nLines;
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::EnableMultiSelection( BOOL bMulti )
+{
+ mpImplLB->EnableMultiSelection( bMulti );
+
+ // WB_SIMPLEMODE:
+ // Die MultiListBox verhlt sich wie eine normale ListBox.
+ // Die Mehrfachselektion kann nur ber entsprechende Zusatztasten erfolgen.
+
+ BOOL bSimpleMode = ( GetStyle() & WB_SIMPLEMODE ) ? TRUE : FALSE;
+ mpImplLB->SetMultiSelectionSimpleMode( bSimpleMode );
+
+ // ohne Focus ist das Traveln in einer MultiSelection nicht zu sehen:
+ if ( mpFloatWin )
+ mpImplLB->GetMainWindow()->AllowGrabFocus( bMulti );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ListBox::IsMultiSelectionEnabled() const
+{
+ return mpImplLB->IsMultiSelectionEnabled();
+}
+
+// -----------------------------------------------------------------------
+
+Size ListBox::CalcMinimumSize() const
+{
+ Size aSz;
+ if ( !IsDropDownBox() )
+ {
+ aSz = mpImplLB->CalcSize( mpImplLB->GetEntryList()->GetEntryCount() );
+ }
+ else
+ {
+ aSz.Height() = mpImplLB->CalcSize( 1 ).Height();
+ aSz.Width() = mpImplLB->GetMaxEntryWidth();
+ aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
+ }
+
+ aSz = CalcWindowSize( aSz );
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+Size ListBox::CalcAdjustedSize( const Size& rPrefSize ) const
+{
+ Size aSz = rPrefSize;
+ long nLeft, nTop, nRight, nBottom;
+ ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
+ aSz.Height() -= nTop+nBottom;
+ if ( !IsDropDownBox() )
+ {
+ long nEntryHeight = CalcSize( 1, 1 ).Height();
+ long nLines = aSz.Height() / nEntryHeight;
+ if ( nLines < 1 )
+ nLines = 1;
+ aSz.Height() = nLines * nEntryHeight;
+ }
+ else
+ {
+ aSz.Height() = mnDDHeight;
+ }
+ aSz.Height() += nTop+nBottom;
+
+ aSz = CalcWindowSize( aSz );
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+Size ListBox::CalcSize( USHORT nColumns, USHORT nLines ) const
+{
+ // ggf. werden ScrollBars eingeblendet
+ Size aMinSz = CalcMinimumSize();
+// aMinSz = ImplCalcOutSz( aMinSz );
+
+ Size aSz;
+
+ // Hoehe
+ if ( nLines )
+ {
+ if ( !IsDropDownBox() )
+ aSz.Height() = mpImplLB->CalcSize( nLines ).Height();
+ else
+ aSz.Height() = mnDDHeight;
+ }
+ else
+ aSz.Height() = aMinSz.Height();
+
+ // Breite
+ if ( nColumns )
+ aSz.Width() = nColumns * GetTextWidth( XubString( 'X' ) );
+ else
+ aSz.Width() = aMinSz.Width();
+
+ if ( IsDropDownBox() )
+ aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
+
+ if ( !IsDropDownBox() )
+ {
+ if ( aSz.Width() < aMinSz.Width() )
+ aSz.Height() += GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( aSz.Height() < aMinSz.Height() )
+ aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
+ }
+
+ aSz = CalcWindowSize( aSz );
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::GetMaxVisColumnsAndLines( USHORT& rnCols, USHORT& rnLines ) const
+{
+ long nCharWidth = GetTextWidth( UniString( 'x' ) );
+ if ( !IsDropDownBox() )
+ {
+ Size aOutSz = mpImplLB->GetMainWindow()->GetOutputSizePixel();
+ rnCols = (USHORT) (aOutSz.Width()/nCharWidth);
+ rnLines = (USHORT) (aOutSz.Height()/mpImplLB->GetEntryHeight());
+ }
+ else
+ {
+ Size aOutSz = mpImplWin->GetOutputSizePixel();
+ rnCols = (USHORT) (aOutSz.Width()/nCharWidth);
+ rnLines = 1;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ListBox, ImplUserDrawHdl, UserDrawEvent*, pEvent )
+{
+ UserDraw( *pEvent );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::UserDraw( const UserDrawEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+#if SUPD < 593
+void ListBox::DrawEntry( const UserDrawEvent& rEvt, BOOL bDrawImage, BOOL bDrawText )
+{
+ if ( rEvt.GetDevice() == mpImplLB->GetMainWindow() )
+ mpImplLB->GetMainWindow()->DrawEntry( rEvt.GetItemId(), bDrawImage, bDrawText );
+ else if ( rEvt.GetDevice() == mpImplWin )
+ mpImplWin->DrawEntry( bDrawImage, bDrawText );
+}
+#endif
+
+void ListBox::DrawEntry( const UserDrawEvent& rEvt, BOOL bDrawImage, BOOL bDrawText, BOOL bDrawTextAtImagePos )
+{
+ if ( rEvt.GetDevice() == mpImplLB->GetMainWindow() )
+ mpImplLB->GetMainWindow()->DrawEntry( rEvt.GetItemId(), bDrawImage, bDrawText, bDrawTextAtImagePos );
+ else if ( rEvt.GetDevice() == mpImplWin )
+ mpImplWin->DrawEntry( bDrawImage, bDrawText, bDrawTextAtImagePos );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetUserItemSize( const Size& rSz )
+{
+ mpImplLB->GetMainWindow()->SetUserItemSize( rSz );
+ if ( mpImplWin )
+ mpImplWin->SetUserItemSize( rSz );
+}
+
+// -----------------------------------------------------------------------
+
+const Size& ListBox::GetUserItemSize() const
+{
+ return mpImplLB->GetMainWindow()->GetUserItemSize();
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::EnableUserDraw( BOOL bUserDraw )
+{
+ mpImplLB->GetMainWindow()->EnableUserDraw( bUserDraw );
+ if ( mpImplWin )
+ mpImplWin->EnableUserDraw( bUserDraw );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ListBox::IsUserDrawEnabled() const
+{
+ return mpImplLB->GetMainWindow()->IsUserDrawEnabled();
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetReadOnly( BOOL bReadOnly )
+{
+ if ( mpImplLB->IsReadOnly() != bReadOnly )
+ {
+ mpImplLB->SetReadOnly( bReadOnly );
+ StateChanged( STATE_CHANGE_READONLY );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ListBox::IsReadOnly() const
+{
+ return mpImplLB->IsReadOnly();
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetSeparatorPos( USHORT n )
+{
+ mpImplLB->SetSeparatorPos( n );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetSeparatorPos()
+{
+ mpImplLB->SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::GetSeparatorPos() const
+{
+ return mpImplLB->GetSeparatorPos();
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetMRUEntries( const XubString& rEntries, xub_Unicode cSep )
+{
+ mpImplLB->SetMRUEntries( rEntries, cSep );
+}
+
+// -----------------------------------------------------------------------
+
+XubString ListBox::GetMRUEntries( xub_Unicode cSep ) const
+{
+ return mpImplLB->GetMRUEntries( cSep );
+}
+
+// -----------------------------------------------------------------------
+
+void ListBox::SetMaxMRUCount( USHORT n )
+{
+ mpImplLB->SetMaxMRUCount( n );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ListBox::GetMaxMRUCount() const
+{
+ return mpImplLB->GetMaxMRUCount();
+}
+
+// =======================================================================
+
+MultiListBox::MultiListBox( Window* pParent, WinBits nStyle ) :
+ ListBox( WINDOW_MULTILISTBOX )
+{
+ ImplInit( pParent, nStyle );
+ EnableMultiSelection( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+MultiListBox::MultiListBox( Window* pParent, const ResId& rResId ) :
+ ListBox( WINDOW_MULTILISTBOX )
+{
+ rResId.SetRT( RSC_MULTILISTBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+ EnableMultiSelection( TRUE );
+}
diff --git a/vcl/source/control/makefile.mk b/vcl/source/control/makefile.mk
new file mode 100644
index 000000000000..ba03559c2b71
--- /dev/null
+++ b/vcl/source/control/makefile.mk
@@ -0,0 +1,119 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=vcl
+TARGET=ctrl
+
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+.IF "$(COM)"=="ICC"
+CDEFS+=-D_STD_NO_NAMESPACE -D_VOS_NO_NAMESPACE -D_UNO_NO_NAMESPACE
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/button.obj \
+ $(SLO)$/ctrl.obj \
+ $(SLO)$/combobox.obj \
+ $(SLO)$/edit.obj \
+ $(SLO)$/field.obj \
+ $(SLO)$/field2.obj \
+ $(SLO)$/fixbrd.obj \
+ $(SLO)$/fixed.obj \
+ $(SLO)$/group.obj \
+ $(SLO)$/ilstbox.obj \
+ $(SLO)$/imgctrl.obj \
+ $(SLO)$/longcurr.obj \
+ $(SLO)$/lstbox.obj \
+ $(SLO)$/morebtn.obj \
+ $(SLO)$/menubtn.obj \
+ $(SLO)$/scrbar.obj \
+ $(SLO)$/slider.obj \
+ $(SLO)$/spinfld.obj \
+ $(SLO)$/spinbtn.obj \
+ $(SLO)$/tabctrl.obj
+
+.IF "$(remote)"!=""
+EXCEPTIONSFILES= \
+ $(SLO)$/button.obj \
+ $(SLO)$/ctrl.obj \
+ $(SLO)$/edit.obj \
+ $(SLO)$/field.obj \
+ $(SLO)$/field2.obj \
+ $(SLO)$/longcurr.obj \
+ $(SLO)$/ilstbox.obj \
+ $(SLO)$/tabctrl.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
diff --git a/vcl/source/control/menubtn.cxx b/vcl/source/control/menubtn.cxx
new file mode 100644
index 000000000000..6891577b0b54
--- /dev/null
+++ b/vcl/source/control/menubtn.cxx
@@ -0,0 +1,285 @@
+/*************************************************************************
+ *
+ * $RCSfile: menubtn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_MENUBTN_CXX
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_MENU_HXX
+#include <menu.hxx>
+#endif
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_MENUBTN_HXX
+#include <menubtn.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define IMAGEBUTTON_BORDER_OFF1 11
+#define IMAGEBUTTON_BORDER_OFF2 16
+
+// =======================================================================
+
+void MenuButton::ImplInitData()
+{
+ mnDDStyle = PUSHBUTTON_DROPDOWN_MENUBUTTON;
+
+ mpMenuTimer = NULL;
+ mpMenu = NULL;
+ mpOwnMenu = NULL;
+ mnCurItemId = 0;
+ mnMenuMode = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void MenuButton::ImplInit( Window* pParent, WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOTABSTOP) )
+ nStyle |= WB_TABSTOP;
+
+ PushButton::ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void MenuButton::ImplExecuteMenu()
+{
+ Activate();
+
+ if ( mpMenu )
+ {
+ Point aPos( 0, 1 );
+ Size aSize = GetSizePixel();
+ Rectangle aRect( aPos, aSize );
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if ( !((GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) ||
+ !(rStyleSettings.GetOptions() & STYLE_OPTION_MACSTYLE)) )
+ {
+ aRect.Left() += 2;
+ aRect.Top() += 2;
+ aRect.Right() -= 2;
+ aRect.Bottom() -= 2;
+ }
+ SetPressed( TRUE );
+ EndSelection();
+ mnCurItemId = mpMenu->Execute( this, aRect, POPUPMENU_EXECUTE_DOWN );
+ SetPressed( FALSE );
+ if ( mnCurItemId )
+ {
+ Select();
+ mnCurItemId = 0;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+MenuButton::MenuButton( Window* pParent, WinBits nWinBits ) :
+ PushButton( WINDOW_MENUBUTTON )
+{
+ ImplInitData();
+ ImplInit( pParent, nWinBits );
+}
+
+// -----------------------------------------------------------------------
+
+MenuButton::MenuButton( Window* pParent, const ResId& rResId ) :
+ PushButton( WINDOW_MENUBUTTON )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_MENUBUTTON );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void MenuButton::ImplLoadRes( const ResId& rResId )
+{
+ Control::ImplLoadRes( rResId );
+
+ USHORT nObjMask = ReadShortRes();
+
+ if ( RSCMENUBUTTON_MENU & nObjMask )
+ {
+ mpOwnMenu = new PopupMenu( ResId( (RSHEADER_TYPE*)GetClassRes() ) );
+ SetPopupMenu( mpOwnMenu );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+MenuButton::~MenuButton()
+{
+ if ( mpMenuTimer )
+ delete mpMenuTimer;
+ if ( mpOwnMenu )
+ delete mpOwnMenu;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( MenuButton, ImplMenuTimeoutHdl, Timer*, EMPTYARG )
+{
+ // Abfragen, ob Button-Benutzung noch aktiv ist, da diese ja auch
+ // vorher abgebrochen wurden sein koennte
+ if ( IsTracking() )
+ {
+ if ( !(GetStyle() & WB_NOPOINTERFOCUS) )
+ GrabFocus();
+ ImplExecuteMenu();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void MenuButton::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( mnMenuMode & MENUBUTTON_MENUMODE_TIMED )
+ {
+ if ( !mpMenuTimer )
+ {
+ mpMenuTimer = new Timer;
+ mpMenuTimer->SetTimeoutHdl( LINK( this, MenuButton, ImplMenuTimeoutHdl ) );
+ }
+
+ mpMenuTimer->SetTimeout( GetSettings().GetMouseSettings().GetActionDelay() );
+ mpMenuTimer->Start();
+
+ PushButton::MouseButtonDown( rMEvt );
+ }
+ else
+ {
+ if ( PushButton::ImplHitTestPushButton( this, rMEvt.GetPosPixel(), 0 ) )
+ {
+ if ( !(GetStyle() & WB_NOPOINTERFOCUS) )
+ GrabFocus();
+ ImplExecuteMenu();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void MenuButton::KeyInput( const KeyEvent& rKEvt )
+{
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+ USHORT nCode = aKeyCode.GetCode();
+ if ( (nCode == KEY_DOWN) && aKeyCode.IsMod2() )
+ ImplExecuteMenu();
+ else if ( !(mnMenuMode & MENUBUTTON_MENUMODE_TIMED) &&
+ !aKeyCode.GetModifier() &&
+ ((nCode == KEY_RETURN) || (nCode == KEY_SPACE)) )
+ ImplExecuteMenu();
+ else
+ PushButton::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MenuButton::Activate()
+{
+ maActivateHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void MenuButton::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void MenuButton::SetMenuMode( USHORT nMode )
+{
+ // Fuer die 5.1-Auslieferung besser noch nicht inline, ansonsten kann
+ // diese Funktion zur 6.0 inline werden
+ mnMenuMode = nMode;
+}
+
+// -----------------------------------------------------------------------
+
+void MenuButton::SetPopupMenu( PopupMenu* pNewMenu )
+{
+ // Fuer die 5.1-Auslieferung besser noch nicht inline, ansonsten kann
+ // diese Funktion zur 6.0 inline werden
+ mpMenu = pNewMenu;
+}
diff --git a/vcl/source/control/morebtn.cxx b/vcl/source/control/morebtn.cxx
new file mode 100644
index 000000000000..6712e2e20399
--- /dev/null
+++ b/vcl/source/control/morebtn.cxx
@@ -0,0 +1,266 @@
+/*************************************************************************
+ *
+ * $RCSfile: morebtn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_MOREBTN_CXX
+
+#ifndef _SV_MOREBTN_HXX
+#include <morebtn.hxx>
+#endif
+
+#ifndef _SV_RD_H
+#include <rc.h>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+// Muss mit der Laenge der folgenden Texte uebereinstimmen
+#define EXTRA_TEXTLEN 3
+
+static sal_Char const aImplMoreOpen[] = " >>";
+static sal_Char const aImplMoreClose[] = " <<";
+
+DECLARE_LIST( ImplMoreWindowList, Window* );
+
+// =======================================================================
+
+void MoreButton::ImplInit( Window* pParent, WinBits nStyle )
+{
+ mpItemList = NULL;
+ mnDelta = 0;
+ meUnit = MAP_PIXEL;
+ mbState = FALSE;
+
+ PushButton::ImplInit( pParent, nStyle );
+
+ SetText( Button::GetStandardText( BUTTON_MORE ) );
+ SetHelpText( Button::GetStandardHelpText( BUTTON_MORE ) );
+}
+
+// -----------------------------------------------------------------------
+
+MoreButton::MoreButton( Window* pParent, WinBits nStyle ) :
+ PushButton( WINDOW_MOREBUTTON )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+MoreButton::MoreButton( Window* pParent, const ResId& rResId ) :
+ PushButton( WINDOW_MOREBUTTON )
+{
+ rResId.SetRT( RSC_MOREBUTTON );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void MoreButton::ImplLoadRes( const ResId& rResId )
+{
+ PushButton::ImplLoadRes( rResId );
+
+ USHORT nObjMask = ReadShortRes();
+
+ if ( nObjMask & RSC_MOREBUTTON_STATE )
+ {
+ // Nicht Methode rufen, da Dialog nicht umgeschaltet werden soll
+ mbState = (BOOL)ReadShortRes();
+ SetText( GetText() );
+ }
+ if ( nObjMask & RSC_MOREBUTTON_MAPUNIT )
+ meUnit = (MapUnit)ReadShortRes();
+ if ( nObjMask & RSC_MOREBUTTON_DELTA )
+ // Groesse fuer Erweitern des Dialogs
+ mnDelta = ReadShortRes();
+}
+
+// -----------------------------------------------------------------------
+
+MoreButton::~MoreButton()
+{
+ if ( mpItemList )
+ delete mpItemList;
+}
+
+// -----------------------------------------------------------------------
+
+void MoreButton::Click()
+{
+ Window* pParent = GetParent();
+ Size aSize( pParent->GetSizePixel() );
+ Window* pWindow = (mpItemList) ? mpItemList->First() : NULL;
+ long nDeltaPixel = LogicToPixel( Size( 0, mnDelta ), meUnit ).Height();
+
+ // Status aendern
+ XubString aText = GetText();
+ mbState = !mbState;
+ SetText( aText );
+
+ // Hier den Click-Handler rufen, damit vorher die Controls initialisiert
+ // werden koennen
+ PushButton::Click();
+
+ // Je nach Status die Fenster updaten
+ if ( mbState )
+ {
+ // Fenster anzeigen
+ while ( pWindow )
+ {
+ pWindow->Show();
+ pWindow = mpItemList->Next();
+ }
+
+ // Dialogbox anpassen
+ Point aPos( pParent->GetPosPixel() );
+ Rectangle aDeskRect( pParent->ImplGetFrameWindow()->GetDesktopRectPixel() );
+
+ aSize.Height() += nDeltaPixel;
+ if ( (aPos.Y()+aSize.Height()) > aDeskRect.Bottom() )
+ {
+ aPos.Y() = aDeskRect.Bottom()-aSize.Height();
+
+ if ( aPos.Y() < aDeskRect.Top() )
+ aPos.Y() = aDeskRect.Top();
+
+ pParent->SetPosSizePixel( aPos, aSize );
+ }
+ else
+ pParent->SetSizePixel( aSize );
+ }
+ else
+ {
+ // Dialogbox anpassen
+ aSize.Height() -= nDeltaPixel;
+ pParent->SetSizePixel( aSize );
+
+ // Fenster nicht mehr anzeigen
+ while ( pWindow )
+ {
+ pWindow->Hide();
+ pWindow = mpItemList->Next();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void MoreButton::AddWindow( Window* pWindow )
+{
+ if ( !mpItemList )
+ mpItemList = new ImplMoreWindowList( 1024, 16, 16 );
+
+ mpItemList->Insert( pWindow, LIST_APPEND );
+
+ if ( mbState )
+ pWindow->Show();
+ else
+ pWindow->Hide();
+}
+
+// -----------------------------------------------------------------------
+
+void MoreButton::RemoveWindow( Window* pWindow )
+{
+ if ( mpItemList )
+ mpItemList->Remove( pWindow );
+}
+
+// -----------------------------------------------------------------------
+
+void MoreButton::SetText( const XubString& rText )
+{
+ XubString aText = rText;
+
+ if ( !mbState )
+ aText.AppendAscii( aImplMoreOpen );
+ else
+ aText.AppendAscii( aImplMoreClose );
+
+ PushButton::SetText( aText );
+}
+
+// -----------------------------------------------------------------------
+
+XubString MoreButton::GetText() const
+{
+ XubString aText = PushButton::GetText();
+
+ XubString aSubText = aText.Copy( aText.Len()-EXTRA_TEXTLEN, EXTRA_TEXTLEN );
+ if ( !mbState )
+ {
+ if ( aSubText.EqualsAscii( aImplMoreOpen ) )
+ aText.Erase( aText.Len()-EXTRA_TEXTLEN, EXTRA_TEXTLEN );
+ }
+ else
+ {
+ if ( aSubText.EqualsAscii( aImplMoreClose ) )
+ aText.Erase( aText.Len()-EXTRA_TEXTLEN, EXTRA_TEXTLEN );
+ }
+
+ return aText;
+}
diff --git a/vcl/source/control/scrbar.cxx b/vcl/source/control/scrbar.cxx
new file mode 100644
index 000000000000..e070b607dd74
--- /dev/null
+++ b/vcl/source/control/scrbar.cxx
@@ -0,0 +1,1245 @@
+/*************************************************************************
+ *
+ * $RCSfile: scrbar.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SCRBAR_CXX
+
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SOUND_HXX
+#include <sound.hxx>
+#endif
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_SCRBAR_HXX
+#include <scrbar.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+static long ImplMulDiv( long nNumber, long nNumerator, long nDenominator )
+{
+ double n = ((double)nNumber * (double)nNumerator) / (double)nDenominator;
+ return (long)n;
+}
+
+// =======================================================================
+
+#define SCRBAR_DRAW_BTN1 ((USHORT)0x0001)
+#define SCRBAR_DRAW_BTN2 ((USHORT)0x0002)
+#define SCRBAR_DRAW_PAGE1 ((USHORT)0x0004)
+#define SCRBAR_DRAW_PAGE2 ((USHORT)0x0008)
+#define SCRBAR_DRAW_THUMB ((USHORT)0x0010)
+#define SCRBAR_DRAW_ALL (SCRBAR_DRAW_BTN1 | SCRBAR_DRAW_BTN2 | \
+ SCRBAR_DRAW_PAGE1 | SCRBAR_DRAW_PAGE2 |\
+ SCRBAR_DRAW_THUMB)
+
+#define SCRBAR_STATE_BTN1_DOWN ((USHORT)0x0001)
+#define SCRBAR_STATE_BTN1_DISABLE ((USHORT)0x0002)
+#define SCRBAR_STATE_BTN2_DOWN ((USHORT)0x0004)
+#define SCRBAR_STATE_BTN2_DISABLE ((USHORT)0x0008)
+#define SCRBAR_STATE_PAGE1_DOWN ((USHORT)0x0010)
+#define SCRBAR_STATE_PAGE2_DOWN ((USHORT)0x0020)
+#define SCRBAR_STATE_THUMB_DOWN ((USHORT)0x0040)
+
+#define SCRBAR_MIN_THUMB 8
+
+#define SCRBAR_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT)
+
+// =======================================================================
+
+void ScrollBar::ImplInit( Window* pParent, WinBits nStyle )
+{
+ mpDDScrollTimer = NULL;
+ mnThumbPixRange = 0;
+ mnThumbPixPos = 0;
+ mnThumbPixSize = 0;
+ mnMinRange = 0;
+ mnMaxRange = 100;
+ mnThumbPos = 0;
+ mnVisibleSize = 0;
+ mnLineSize = 1;
+ mnPageSize = 1;
+ mnDelta = 0;
+ mnDragDraw = 0;
+ mnStateFlags = 0;
+ meScrollType = SCROLL_DONTKNOW;
+ meDDScrollType = SCROLL_DONTKNOW;
+ mbCalcSize = TRUE;
+ mbFullDrag = 0;
+ mbDDScroll = FALSE;
+
+ ImplInitStyle( nStyle );
+ Control::ImplInit( pParent, nStyle, NULL );
+
+ long nScrollSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ SetSizePixel( Size( nScrollSize, nScrollSize ) );
+ SetBackground();
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::ImplInitStyle( WinBits nStyle )
+{
+ if ( nStyle & WB_DRAG )
+ mbFullDrag = TRUE;
+ else
+ mbFullDrag = (GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SCROLL) != 0;
+}
+
+// -----------------------------------------------------------------------
+
+ScrollBar::ScrollBar( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_SCROLLBAR )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+ScrollBar::ScrollBar( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_SCROLLBAR )
+{
+ rResId.SetRT( RSC_SCROLLBAR );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+ScrollBar::~ScrollBar()
+{
+ if ( mpDDScrollTimer )
+ {
+ delete mpDDScrollTimer;
+ mpDDScrollTimer = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::ImplLoadRes( const ResId& rResId )
+{
+ Control::ImplLoadRes( rResId );
+
+ INT16 nMin = ReadShortRes();
+ INT16 nMax = ReadShortRes();
+ INT16 nThumbPos = ReadShortRes();
+ INT16 nPage = ReadShortRes();
+ INT16 nStep = ReadShortRes();
+ INT16 nVisibleSize = ReadShortRes();
+
+ SetRange( Range( nMin, nMax ) );
+ SetLineSize( nStep );
+ SetPageSize( nPage );
+ SetVisibleSize( nVisibleSize );
+ SetThumbPos( nThumbPos );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ScrollBar::ImplUpdateThumbRect( const Rectangle& rOldRect )
+{
+ Size aThumbRectSize = rOldRect.GetSize();
+/* !!! Wegen ueberlappenden Fenstern ... !!!
+ if ( aThumbRectSize == maThumbRect.GetSize() )
+ {
+ DrawOutDev( maThumbRect.TopLeft(), aThumbRectSize,
+ rOldRect.TopLeft(), aThumbRectSize );
+ return TRUE;
+ }
+ else
+*/
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::ImplUpdateRects( BOOL bUpdate )
+{
+ USHORT nOldStateFlags = mnStateFlags;
+ Rectangle aOldPage1Rect = maPage1Rect;
+ Rectangle aOldPage2Rect = maPage2Rect;
+ Rectangle aOldThumbRect = maThumbRect;
+
+ mnStateFlags &= ~SCRBAR_STATE_BTN1_DISABLE;
+ mnStateFlags &= ~SCRBAR_STATE_BTN2_DISABLE;
+
+ if ( mnThumbPixRange )
+ {
+ if ( GetStyle() & WB_HORZ )
+ {
+ maThumbRect.Left() = maBtn1Rect.Right()+1+mnThumbPixPos;
+ maThumbRect.Right() = maThumbRect.Left()+mnThumbPixSize-1;
+ if ( !mnThumbPixPos )
+ maPage1Rect.Right() = RECT_EMPTY;
+ else
+ maPage1Rect.Right() = maThumbRect.Left()-1;
+ if ( mnThumbPixPos >= (mnThumbPixRange-mnThumbPixSize) )
+ maPage2Rect.Right() = RECT_EMPTY;
+ else
+ {
+ maPage2Rect.Left() = maThumbRect.Right()+1;
+ maPage2Rect.Right() = maBtn2Rect.Left()-1;
+ }
+ }
+ else
+ {
+ maThumbRect.Top() = maBtn1Rect.Bottom()+1+mnThumbPixPos;
+ maThumbRect.Bottom() = maThumbRect.Top()+mnThumbPixSize-1;
+ if ( !mnThumbPixPos )
+ maPage1Rect.Bottom() = RECT_EMPTY;
+ else
+ maPage1Rect.Bottom() = maThumbRect.Top()-1;
+ if ( mnThumbPixPos >= (mnThumbPixRange-mnThumbPixSize) )
+ maPage2Rect.Bottom() = RECT_EMPTY;
+ else
+ {
+ maPage2Rect.Top() = maThumbRect.Bottom()+1;
+ maPage2Rect.Bottom() = maBtn2Rect.Top()-1;
+ }
+ }
+ }
+
+ if ( mnThumbPos == mnMinRange )
+ mnStateFlags |= SCRBAR_STATE_BTN1_DISABLE;
+ if ( mnThumbPos >= (mnMaxRange-mnVisibleSize) )
+ mnStateFlags |= SCRBAR_STATE_BTN2_DISABLE;
+
+ if ( bUpdate )
+ {
+ USHORT nDraw = 0;
+ if ( (nOldStateFlags & SCRBAR_STATE_BTN1_DISABLE) !=
+ (mnStateFlags & SCRBAR_STATE_BTN1_DISABLE) )
+ nDraw |= SCRBAR_DRAW_BTN1;
+ if ( (nOldStateFlags & SCRBAR_STATE_BTN2_DISABLE) !=
+ (mnStateFlags & SCRBAR_STATE_BTN2_DISABLE) )
+ nDraw |= SCRBAR_DRAW_BTN2;
+ if ( aOldPage1Rect != maPage1Rect )
+ nDraw |= SCRBAR_DRAW_PAGE1;
+ if ( aOldPage2Rect != maPage2Rect )
+ nDraw |= SCRBAR_DRAW_PAGE2;
+ if ( aOldThumbRect != maThumbRect )
+ {
+ if ( !ImplUpdateThumbRect( aOldThumbRect ) )
+ nDraw |= SCRBAR_DRAW_THUMB;
+ }
+ ImplDraw( nDraw );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ScrollBar::ImplCalcThumbPos( long nPixPos )
+{
+ // Position berechnen
+ long nCalcThumbPos;
+ nCalcThumbPos = ImplMulDiv( nPixPos, mnMaxRange-mnVisibleSize-mnMinRange,
+ mnThumbPixRange-mnThumbPixSize );
+ nCalcThumbPos += mnMinRange;
+ return nCalcThumbPos;
+}
+
+// -----------------------------------------------------------------------
+
+long ScrollBar::ImplCalcThumbPosPix( long nPos )
+{
+ long nCalcThumbPos;
+
+ // Position berechnen
+ nCalcThumbPos = ImplMulDiv( nPos-mnMinRange, mnThumbPixRange-mnThumbPixSize,
+ mnMaxRange-mnVisibleSize-mnMinRange );
+
+ // Am Anfang und Ende des ScrollBars versuchen wir die Anzeige korrekt
+ // anzuzeigen
+ if ( !nCalcThumbPos && (mnThumbPos > mnMinRange) )
+ nCalcThumbPos = 1;
+ if ( nCalcThumbPos &&
+ ((nCalcThumbPos+mnThumbPixSize) >= mnThumbPixRange) &&
+ (mnThumbPos < (mnMaxRange-mnVisibleSize)) )
+ nCalcThumbPos--;
+
+ return nCalcThumbPos;
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::ImplCalc( BOOL bUpdate )
+{
+ if ( mbCalcSize )
+ {
+ Size aSize = GetOutputSizePixel();
+ Size aBtnSize;
+
+ if ( GetStyle() & WB_HORZ )
+ {
+ if ( aSize.Height()*2 > aSize.Width()-SCRBAR_MIN_THUMB )
+ {
+ mnThumbPixRange = 0;
+ maBtn1Rect.Bottom() = aSize.Height()-1;
+ maBtn1Rect.Right() = aSize.Width()/2;
+ maBtn2Rect.Bottom() = maBtn1Rect.Bottom();
+ maBtn2Rect.Left() = maBtn1Rect.Right()+1;
+ maBtn2Rect.Right() = aSize.Width()-1;
+ }
+ else
+ {
+ mnThumbPixRange = aSize.Width()-(aSize.Height()*2);
+ aBtnSize = Size( aSize.Height(), aSize.Height() );
+ maBtn2Rect.Left() = aSize.Width()-aSize.Height();
+ maBtn1Rect.SetSize( aBtnSize );
+ maBtn2Rect.SetSize( aBtnSize );
+ maPage1Rect.Left() = maBtn1Rect.Right()+1;
+ maPage1Rect.Bottom() = maBtn1Rect.Bottom();
+ maPage2Rect.Bottom() = maBtn1Rect.Bottom();
+ maThumbRect.Bottom() = maBtn1Rect.Bottom();
+ }
+ }
+ else
+ {
+ if ( aSize.Width()*2 > aSize.Height()-SCRBAR_MIN_THUMB )
+ {
+ mnThumbPixRange = 0;
+ maBtn1Rect.Right() = aSize.Width()-1;
+ maBtn1Rect.Bottom() = aSize.Height()/2;
+ maBtn2Rect.Right() = maBtn1Rect.Right();
+ maBtn2Rect.Top() = maBtn1Rect.Bottom()+1;
+ maBtn2Rect.Bottom() = aSize.Height()-1;
+ }
+ else
+ {
+ mnThumbPixRange = aSize.Height()-(aSize.Width()*2);
+ aBtnSize = Size( aSize.Width(), aSize.Width() );
+ maBtn2Rect.Top() = aSize.Height()-aSize.Width();
+ maBtn1Rect.SetSize( aBtnSize );
+ maBtn2Rect.SetSize( aBtnSize );
+ maPage1Rect.Top() = maBtn1Rect.Bottom()+1;
+ maPage1Rect.Right() = maBtn1Rect.Right();
+ maPage2Rect.Right() = maBtn1Rect.Right();
+ maThumbRect.Right() = maBtn1Rect.Right();
+ }
+ }
+
+ if ( !mnThumbPixRange )
+ {
+ maPage1Rect.SetEmpty();
+ maPage2Rect.SetEmpty();
+ maThumbRect.SetEmpty();
+ }
+
+ mbCalcSize = FALSE;
+ }
+
+ if ( mnThumbPixRange )
+ {
+ // Werte berechnen
+ if ( (mnVisibleSize >= (mnMaxRange-mnMinRange)) ||
+ ((mnMaxRange-mnMinRange) <= 0) )
+ {
+ mnThumbPos = mnMinRange;
+ mnThumbPixPos = 0;
+ mnThumbPixSize = mnThumbPixRange;
+ }
+ else
+ {
+ if ( mnVisibleSize )
+ mnThumbPixSize = ImplMulDiv( mnThumbPixRange, mnVisibleSize, mnMaxRange-mnMinRange );
+ else
+ {
+ if ( GetStyle() & WB_HORZ )
+ mnThumbPixSize = maThumbRect.GetHeight();
+ else
+ mnThumbPixSize = maThumbRect.GetWidth();
+ }
+ if ( mnThumbPixSize < SCRBAR_MIN_THUMB )
+ mnThumbPixSize = SCRBAR_MIN_THUMB;
+ if ( mnThumbPixSize > mnThumbPixRange )
+ mnThumbPixSize = mnThumbPixRange;
+ mnThumbPixPos = ImplCalcThumbPosPix( mnThumbPos );
+ }
+ }
+
+ // Wenn neu ausgegeben werden soll und wir schon ueber eine
+ // Aktion einen Paint-Event ausgeloest bekommen haben, dann
+ // geben wir nicht direkt aus, sondern invalidieren nur alles
+ if ( bUpdate && HasPaintEvent() )
+ {
+ Invalidate();
+ bUpdate = FALSE;
+ }
+ ImplUpdateRects( bUpdate );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::ImplDraw( USHORT nDrawFlags )
+{
+ DecorationView aDecoView( this );
+ Rectangle aTempRect;
+ USHORT nStyle;
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SymbolType eSymbolType;
+ BOOL bEnabled = IsEnabled();
+
+ // Evt. noch offene Berechnungen nachholen
+ if ( mbCalcSize )
+ ImplCalc( FALSE );
+
+ if ( nDrawFlags & SCRBAR_DRAW_BTN1 )
+ {
+ nStyle = BUTTON_DRAW_NOLIGHTBORDER;
+ if ( mnStateFlags & SCRBAR_STATE_BTN1_DOWN )
+ nStyle |= BUTTON_DRAW_PRESSED;
+ aTempRect = aDecoView.DrawButton( maBtn1Rect, nStyle );
+ ImplCalcSymbolRect( aTempRect );
+ nStyle = 0;
+ if ( (mnStateFlags & SCRBAR_STATE_BTN1_DISABLE) || !bEnabled )
+ nStyle |= SYMBOL_DRAW_DISABLE;
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_SCROLLARROW )
+ {
+ if ( GetStyle() & WB_HORZ )
+ eSymbolType = SYMBOL_ARROW_LEFT;
+ else
+ eSymbolType = SYMBOL_ARROW_UP;
+ }
+ else
+ {
+ if ( GetStyle() & WB_HORZ )
+ eSymbolType = SYMBOL_SPIN_LEFT;
+ else
+ eSymbolType = SYMBOL_SPIN_UP;
+ }
+ aDecoView.DrawSymbol( aTempRect, eSymbolType, rStyleSettings.GetButtonTextColor(), nStyle );
+ }
+
+ if ( nDrawFlags & SCRBAR_DRAW_BTN2 )
+ {
+ nStyle = BUTTON_DRAW_NOLIGHTBORDER;
+ if ( mnStateFlags & SCRBAR_STATE_BTN2_DOWN )
+ nStyle |= BUTTON_DRAW_PRESSED;
+ aTempRect = aDecoView.DrawButton( maBtn2Rect, nStyle );
+ ImplCalcSymbolRect( aTempRect );
+ nStyle = 0;
+ if ( (mnStateFlags & SCRBAR_STATE_BTN2_DISABLE) || !bEnabled )
+ nStyle |= SYMBOL_DRAW_DISABLE;
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_SCROLLARROW )
+ {
+ if ( GetStyle() & WB_HORZ )
+ eSymbolType = SYMBOL_ARROW_RIGHT;
+ else
+ eSymbolType = SYMBOL_ARROW_DOWN;
+ }
+ else
+ {
+ if ( GetStyle() & WB_HORZ )
+ eSymbolType = SYMBOL_SPIN_RIGHT;
+ else
+ eSymbolType = SYMBOL_SPIN_DOWN;
+ }
+ aDecoView.DrawSymbol( aTempRect, eSymbolType, rStyleSettings.GetButtonTextColor(), nStyle );
+ }
+
+ SetLineColor();
+
+ if ( nDrawFlags & SCRBAR_DRAW_THUMB )
+ {
+ if ( !maThumbRect.IsEmpty() )
+ {
+ if ( bEnabled )
+ {
+ nStyle = BUTTON_DRAW_NOLIGHTBORDER;
+ if ( mnStateFlags & SCRBAR_STATE_THUMB_DOWN )
+ nStyle |= BUTTON_DRAW_PRESSED;
+ aTempRect = aDecoView.DrawButton( maThumbRect, nStyle );
+ // Im OS2-Look geben wir auch ein Muster auf dem Thumb aus
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_OS2STYLE )
+ {
+ if ( GetStyle() & WB_HORZ )
+ {
+ if ( aTempRect.GetWidth() > 6 )
+ {
+ long nX = aTempRect.Center().X();
+ nX -= 6;
+ if ( nX < aTempRect.Left() )
+ nX = aTempRect.Left();
+ for ( int i = 0; i < 6; i++ )
+ {
+ if ( nX > aTempRect.Right()-1 )
+ break;
+
+ SetLineColor( rStyleSettings.GetButtonTextColor() );
+ DrawLine( Point( nX, aTempRect.Top()+1 ),
+ Point( nX, aTempRect.Bottom()-1 ) );
+ nX++;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( nX, aTempRect.Top()+1 ),
+ Point( nX, aTempRect.Bottom()-1 ) );
+ nX++;
+ }
+ }
+ }
+ else
+ {
+ if ( aTempRect.GetHeight() > 6 )
+ {
+ long nY = aTempRect.Center().Y();
+ nY -= 6;
+ if ( nY < aTempRect.Top() )
+ nY = aTempRect.Top();
+ for ( int i = 0; i < 6; i++ )
+ {
+ if ( nY > aTempRect.Bottom()-1 )
+ break;
+
+ SetLineColor( rStyleSettings.GetButtonTextColor() );
+ DrawLine( Point( aTempRect.Left()+1, nY ),
+ Point( aTempRect.Right()-1, nY ) );
+ nY++;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( aTempRect.Left()+1, nY ),
+ Point( aTempRect.Right()-1, nY ) );
+ nY++;
+ }
+ }
+ }
+ SetLineColor();
+ }
+ }
+ else
+ {
+ SetFillColor( rStyleSettings.GetCheckedColor() );
+ DrawRect( maThumbRect );
+ }
+ }
+ }
+
+ if ( nDrawFlags & SCRBAR_DRAW_PAGE1 )
+ {
+ if ( mnStateFlags & SCRBAR_STATE_PAGE1_DOWN )
+ SetFillColor( rStyleSettings.GetShadowColor() );
+ else
+ SetFillColor( rStyleSettings.GetCheckedColor() );
+ DrawRect( maPage1Rect );
+ }
+ if ( nDrawFlags & SCRBAR_DRAW_PAGE2 )
+ {
+ if ( mnStateFlags & SCRBAR_STATE_PAGE2_DOWN )
+ SetFillColor( rStyleSettings.GetShadowColor() );
+ else
+ SetFillColor( rStyleSettings.GetCheckedColor() );
+ DrawRect( maPage2Rect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ScrollBar::ImplScroll( long nNewPos, BOOL bCallEndScroll )
+{
+ long nOldPos = mnThumbPos;
+ SetThumbPos( nNewPos );
+ long nDelta = mnThumbPos-nOldPos;
+ if ( nDelta )
+ {
+ mnDelta = nDelta;
+ Scroll();
+ if ( bCallEndScroll )
+ EndScroll();
+ mnDelta = 0;
+ }
+ return nDelta;
+}
+
+// -----------------------------------------------------------------------
+
+long ScrollBar::ImplDoAction( BOOL bCallEndScroll )
+{
+ long nDelta = 0;
+
+ switch ( meScrollType )
+ {
+ case SCROLL_LINEUP:
+ nDelta = ImplScroll( mnThumbPos-mnLineSize, bCallEndScroll );
+ break;
+
+ case SCROLL_LINEDOWN:
+ nDelta = ImplScroll( mnThumbPos+mnLineSize, bCallEndScroll );
+ break;
+
+ case SCROLL_PAGEUP:
+ nDelta = ImplScroll( mnThumbPos-mnPageSize, bCallEndScroll );
+ break;
+
+ case SCROLL_PAGEDOWN:
+ nDelta = ImplScroll( mnThumbPos+mnPageSize, bCallEndScroll );
+ break;
+ }
+
+ return nDelta;
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::ImplDoMouseAction( const Point& rMousePos, BOOL bCallAction )
+{
+ USHORT nOldStateFlags = mnStateFlags;
+ BOOL bAction = FALSE;
+
+ switch ( meScrollType )
+ {
+ case SCROLL_LINEUP:
+ if ( maBtn1Rect.IsInside( rMousePos ) )
+ {
+ bAction = bCallAction;
+ mnStateFlags |= SCRBAR_STATE_BTN1_DOWN;
+ }
+ else
+ mnStateFlags &= ~SCRBAR_STATE_BTN1_DOWN;
+ break;
+
+ case SCROLL_LINEDOWN:
+ if ( maBtn2Rect.IsInside( rMousePos ) )
+ {
+ bAction = bCallAction;
+ mnStateFlags |= SCRBAR_STATE_BTN2_DOWN;
+ }
+ else
+ mnStateFlags &= ~SCRBAR_STATE_BTN2_DOWN;
+ break;
+
+ case SCROLL_PAGEUP:
+ if ( maPage1Rect.IsInside( rMousePos ) )
+ {
+ bAction = bCallAction;
+ mnStateFlags |= SCRBAR_STATE_PAGE1_DOWN;
+ }
+ else
+ mnStateFlags &= ~SCRBAR_STATE_PAGE1_DOWN;
+ break;
+
+ case SCROLL_PAGEDOWN:
+ if ( maPage2Rect.IsInside( rMousePos ) )
+ {
+ bAction = bCallAction;
+ mnStateFlags |= SCRBAR_STATE_PAGE2_DOWN;
+ }
+ else
+ mnStateFlags &= ~SCRBAR_STATE_PAGE2_DOWN;
+ break;
+ }
+
+ if ( nOldStateFlags != mnStateFlags )
+ ImplDraw( mnDragDraw );
+ if ( bAction )
+ ImplDoAction( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScrollBar, ImplTimerHdl, Timer*, pTimer )
+{
+ pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
+ DoScroll( meDDScrollType );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ {
+ const Point& rMousePos = rMEvt.GetPosPixel();
+ USHORT nTrackFlags = 0;
+
+ if ( maBtn1Rect.IsInside( rMousePos ) )
+ {
+ if ( !(mnStateFlags & SCRBAR_STATE_BTN1_DISABLE) )
+ {
+ nTrackFlags = STARTTRACK_BUTTONREPEAT;
+ meScrollType = SCROLL_LINEUP;
+ mnDragDraw = SCRBAR_DRAW_BTN1;
+ }
+ else
+ Sound::Beep( SOUND_DISABLE, this );
+ }
+ else if ( maBtn2Rect.IsInside( rMousePos ) )
+ {
+ if ( !(mnStateFlags & SCRBAR_STATE_BTN2_DISABLE) )
+ {
+ nTrackFlags = STARTTRACK_BUTTONREPEAT;
+ meScrollType = SCROLL_LINEDOWN;
+ mnDragDraw = SCRBAR_DRAW_BTN2;
+ }
+ else
+ Sound::Beep( SOUND_DISABLE, this );
+ }
+ else if ( maThumbRect.IsInside( rMousePos ) )
+ {
+ if ( mnVisibleSize < mnMaxRange-mnMinRange )
+ {
+ nTrackFlags = 0;
+ meScrollType = SCROLL_DRAG;
+ mnDragDraw = SCRBAR_DRAW_THUMB;
+
+ // Zusaetzliche Daten berechnen
+ if ( GetStyle() & WB_HORZ )
+ mnMouseOff = rMousePos.X()-maThumbRect.Left();
+ else
+ mnMouseOff = rMousePos.Y()-maThumbRect.Top();
+
+ // Im OS2-Look geben wir den Thumb gedrueck aus
+ if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_OS2STYLE )
+ {
+ mnStateFlags |= SCRBAR_STATE_THUMB_DOWN;
+ ImplDraw( mnDragDraw );
+ }
+ }
+ else
+ Sound::Beep( SOUND_DISABLE, this );
+ }
+ else
+ {
+ nTrackFlags = STARTTRACK_BUTTONREPEAT;
+
+ if ( maPage1Rect.IsInside( rMousePos ) )
+ {
+ meScrollType = SCROLL_PAGEUP;
+ mnDragDraw = SCRBAR_DRAW_PAGE1;
+ }
+ else
+ {
+ meScrollType = SCROLL_PAGEDOWN;
+ mnDragDraw = SCRBAR_DRAW_PAGE2;
+ }
+ }
+
+ // Soll Tracking gestartet werden
+ if ( meScrollType != SCROLL_DONTKNOW )
+ {
+ // Startposition merken fuer Abbruch und EndScroll-Delta
+ mnStartPos = mnThumbPos;
+ ImplDoMouseAction( rMousePos );
+ StartTracking( nTrackFlags );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ // Button und PageRect-Status wieder herstellen
+ USHORT nOldStateFlags = mnStateFlags;
+ mnStateFlags &= ~(SCRBAR_STATE_BTN1_DOWN | SCRBAR_STATE_BTN2_DOWN |
+ SCRBAR_STATE_PAGE1_DOWN | SCRBAR_STATE_PAGE2_DOWN |
+ SCRBAR_STATE_THUMB_DOWN);
+ if ( nOldStateFlags != mnStateFlags )
+ ImplDraw( mnDragDraw );
+ mnDragDraw = 0;
+
+ // Bei Abbruch, die alte ThumbPosition wieder herstellen
+ if ( rTEvt.IsTrackingCanceled() )
+ {
+ long nOldPos = mnThumbPos;
+ SetThumbPos( mnStartPos );
+ mnDelta = mnThumbPos-nOldPos;
+ Scroll();
+ }
+
+ if ( meScrollType == SCROLL_DRAG )
+ {
+ // Wenn gedragt wurde, berechnen wir den Thumb neu, damit
+ // er wieder auf einer gerundeten ThumbPosition steht
+ ImplCalc();
+
+ if ( !mbFullDrag && (mnStartPos != mnThumbPos) )
+ {
+ mnDelta = mnThumbPos-mnStartPos;
+ Scroll();
+ mnDelta = 0;
+ }
+ }
+
+ mnDelta = mnThumbPos-mnStartPos;
+ EndScroll();
+ mnDelta = 0;
+ meScrollType = SCROLL_DONTKNOW;
+ }
+ else
+ {
+ const Point rMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+
+ // Dragging wird speziell behandelt
+ if ( meScrollType == SCROLL_DRAG )
+ {
+ long nMovePix;
+ if ( GetStyle() & WB_HORZ )
+ nMovePix = rMousePos.X()-(maThumbRect.Left()+mnMouseOff);
+ else
+ nMovePix = rMousePos.Y()-(maThumbRect.Top()+mnMouseOff);
+ // Nur wenn sich Maus in die Scrollrichtung bewegt, muessen
+ // wir etwas tun
+ if ( nMovePix )
+ {
+ mnThumbPixPos += nMovePix;
+ if ( mnThumbPixPos < 0 )
+ mnThumbPixPos = 0;
+ if ( mnThumbPixPos > (mnThumbPixRange-mnThumbPixSize) )
+ mnThumbPixPos = mnThumbPixRange-mnThumbPixSize;
+ long nOldPos = mnThumbPos;
+ mnThumbPos = ImplCalcThumbPos( mnThumbPixPos );
+ ImplUpdateRects();
+ if ( mbFullDrag && (nOldPos != mnThumbPos) )
+ {
+ mnDelta = mnThumbPos-nOldPos;
+ Scroll();
+ mnDelta = 0;
+ }
+ }
+ }
+ else
+ ImplDoMouseAction( rMousePos, rTEvt.IsTrackingRepeat() );
+
+ // Wenn ScrollBar-Werte so umgesetzt wurden, das es nichts
+ // mehr zum Tracking gibt, dann berechen wir hier ab
+ if ( !IsVisible() || (mnVisibleSize >= (mnMaxRange-mnMinRange)) )
+ EndTracking();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::KeyInput( const KeyEvent& rKEvt )
+{
+ if ( !rKEvt.GetKeyCode().GetModifier() )
+ {
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_HOME:
+ DoScroll( 0 );
+ break;
+
+ case KEY_END:
+ DoScroll( GetRangeMax() );
+ break;
+
+ case KEY_LEFT:
+ case KEY_UP:
+ DoScrollAction( SCROLL_LINEUP );
+ break;
+
+ case KEY_RIGHT:
+ case KEY_DOWN:
+ DoScrollAction( SCROLL_LINEDOWN );
+ break;
+
+ case KEY_PAGEUP:
+ DoScrollAction( SCROLL_PAGEUP );
+ break;
+
+ case KEY_PAGEDOWN:
+ DoScrollAction( SCROLL_PAGEDOWN );
+ break;
+
+ default:
+ Control::KeyInput( rKEvt );
+ break;
+ }
+ }
+ else
+ Control::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::Paint( const Rectangle& rRect )
+{
+ ImplDraw( SCRBAR_DRAW_ALL );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::Resize()
+{
+ mbCalcSize = TRUE;
+ if ( IsReallyVisible() )
+ ImplCalc( FALSE );
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ScrollBar::QueryDrop( DropEvent& rDEvt )
+{
+ if ( mbDDScroll )
+ DDScroll( rDEvt );
+ return Control::QueryDrop( rDEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ImplCalc( FALSE );
+ else if ( nType == STATE_CHANGE_DATA )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplCalc( TRUE );
+ }
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplCalc( FALSE );
+ Invalidate();
+ }
+ }
+ else if ( nType == STATE_CHANGE_ENABLE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ ImplInitStyle( GetStyle() );
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ if ( (GetPrevStyle() & SCRBAR_VIEW_STYLE) !=
+ (GetStyle() & SCRBAR_VIEW_STYLE) )
+ {
+ mbCalcSize = TRUE;
+ ImplCalc( FALSE );
+ Invalidate();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::Scroll()
+{
+ maScrollHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::EndScroll()
+{
+ maEndScrollHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+long ScrollBar::DoScroll( long nNewPos )
+{
+ if ( meScrollType != SCROLL_DONTKNOW )
+ return 0;
+
+ meScrollType = SCROLL_DRAG;
+ long nDelta = ImplScroll( nNewPos, TRUE );
+ meScrollType = SCROLL_DONTKNOW;
+ return nDelta;
+}
+
+// -----------------------------------------------------------------------
+
+long ScrollBar::DoScrollAction( ScrollType eScrollType )
+{
+ if ( (meScrollType != SCROLL_DONTKNOW) ||
+ (eScrollType == SCROLL_DONTKNOW) ||
+ (eScrollType == SCROLL_DRAG) )
+ return 0;
+
+ meScrollType = eScrollType;
+ long nDelta = ImplDoAction( TRUE );
+ meScrollType = SCROLL_DONTKNOW;
+ return nDelta;
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::DDScroll( const DropEvent& rDEvt )
+{
+ if ( rDEvt.IsLeaveWindow() )
+ meDDScrollType = SCROLL_DONTKNOW;
+ else
+ {
+ const Point& rMousePos = rDEvt.GetPosPixel();
+ if ( maBtn1Rect.IsInside( rMousePos ) )
+ {
+ if ( !(mnStateFlags & SCRBAR_STATE_BTN1_DISABLE) )
+ meDDScrollType = SCROLL_LINEUP;
+ }
+ else if ( maBtn2Rect.IsInside( rMousePos ) )
+ {
+ if ( !(mnStateFlags & SCRBAR_STATE_BTN2_DISABLE) )
+ meDDScrollType = SCROLL_LINEDOWN;
+ }
+ else if ( maThumbRect.IsInside( rMousePos ) )
+ meDDScrollType = SCROLL_DONTKNOW;
+ else
+ {
+ if ( maPage1Rect.IsInside( rMousePos ) )
+ meDDScrollType = SCROLL_PAGEUP;
+ else
+ meDDScrollType = SCROLL_PAGEDOWN;
+ }
+ }
+
+ if ( meDDScrollType == SCROLL_DONTKNOW )
+ {
+ if ( mpDDScrollTimer )
+ {
+ delete mpDDScrollTimer;
+ mpDDScrollTimer = NULL;
+ meDDScrollType = SCROLL_DONTKNOW;
+ }
+ }
+ else
+ {
+ if ( !mpDDScrollTimer )
+ {
+ mpDDScrollTimer = new Timer;
+ mpDDScrollTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() );
+ mpDDScrollTimer->SetTimeoutHdl( LINK( this, ScrollBar, ImplTimerHdl ) );
+ mpDDScrollTimer->Start();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::SetRangeMin( long nNewRange )
+{
+ SetRange( Range( nNewRange, GetRangeMax() ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::SetRangeMax( long nNewRange )
+{
+ SetRange( Range( GetRangeMin(), nNewRange ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::SetRange( const Range& rRange )
+{
+ // Range einpassen
+ Range aRange = rRange;
+ aRange.Justify();
+ long nNewMinRange = aRange.Min();
+ long nNewMaxRange = aRange.Max();
+
+ // Wenn Range sich unterscheidet, dann neuen setzen
+ if ( (mnMinRange != nNewMinRange) ||
+ (mnMaxRange != nNewMaxRange) )
+ {
+ mnMinRange = nNewMinRange;
+ mnMaxRange = nNewMaxRange;
+
+ // Thumb einpassen
+ if ( mnThumbPos > mnMaxRange-mnVisibleSize )
+ mnThumbPos = mnMaxRange-mnVisibleSize;
+ if ( mnThumbPos < mnMinRange )
+ mnThumbPos = mnMinRange;
+
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::SetThumbPos( long nNewThumbPos )
+{
+ if ( nNewThumbPos > mnMaxRange-mnVisibleSize )
+ nNewThumbPos = mnMaxRange-mnVisibleSize;
+ if ( nNewThumbPos < mnMinRange )
+ nNewThumbPos = mnMinRange;
+
+ if ( mnThumbPos != nNewThumbPos )
+ {
+ mnThumbPos = nNewThumbPos;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBar::SetVisibleSize( long nNewSize )
+{
+ if ( mnVisibleSize != nNewSize )
+ {
+ mnVisibleSize = nNewSize;
+
+ // Thumb einpassen
+ if ( mnThumbPos > mnMaxRange-mnVisibleSize )
+ mnThumbPos = mnMaxRange-mnVisibleSize;
+ if ( mnThumbPos < mnMinRange )
+ mnThumbPos = mnMinRange;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// =======================================================================
+
+void ScrollBarBox::ImplInit( Window* pParent, WinBits nStyle )
+{
+ Window::ImplInit( pParent, nStyle, NULL );
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ long nScrollSize = rStyleSettings.GetScrollBarSize();
+ SetSizePixel( Size( nScrollSize, nScrollSize ) );
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+ScrollBarBox::ScrollBarBox( Window* pParent, WinBits nStyle ) :
+ Window( WINDOW_SCROLLBARBOX )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+ScrollBarBox::ScrollBarBox( Window* pParent, const ResId& rResId ) :
+ Window( WINDOW_SCROLLBARBOX )
+{
+ rResId.SetRT( RSC_SCROLLBAR );
+ ImplInit( pParent, ImplInitRes( rResId ) );
+ ImplLoadRes( rResId );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBarBox::ImplInitSettings()
+{
+ // Hack, damit man auch DockingWindows ohne Hintergrund bauen kann
+ // und noch nicht alles umgestellt ist
+ if ( IsBackground() )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else
+ aColor = GetSettings().GetStyleSettings().GetFaceColor();
+ SetBackground( aColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBarBox::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollBarBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
diff --git a/vcl/source/control/slider.cxx b/vcl/source/control/slider.cxx
new file mode 100644
index 000000000000..3d8fca3c2501
--- /dev/null
+++ b/vcl/source/control/slider.cxx
@@ -0,0 +1,1024 @@
+/*************************************************************************
+ *
+ * $RCSfile: slider.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SLIDER_CXX
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_SLIDER_HXX
+#include <slider.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+static long ImplMulDiv( long nNumber, long nNumerator, long nDenominator )
+{
+ double n = ((double)nNumber * (double)nNumerator) / (double)nDenominator;
+ return (long)n;
+}
+
+// =======================================================================
+
+#define SLIDER_DRAW_THUMB ((USHORT)0x0001)
+#define SLIDER_DRAW_CHANNEL1 ((USHORT)0x0002)
+#define SLIDER_DRAW_CHANNEL2 ((USHORT)0x0004)
+#define SLIDER_DRAW_CHANNEL (SLIDER_DRAW_CHANNEL1 | SLIDER_DRAW_CHANNEL2)
+#define SLIDER_DRAW_ALL (SLIDER_DRAW_THUMB | SLIDER_DRAW_CHANNEL)
+
+#define SLIDER_STATE_CHANNEL1_DOWN ((USHORT)0x0001)
+#define SLIDER_STATE_CHANNEL2_DOWN ((USHORT)0x0002)
+#define SLIDER_STATE_THUMB_DOWN ((USHORT)0x0004)
+
+#define SLIDER_THUMB_SIZE 9
+#define SLIDER_THUMB_HALFSIZE 4
+#define SLIDER_CHANNEL_OFFSET 0
+#define SLIDER_CHANNEL_SIZE 4
+#define SLIDER_CHANNEL_HALFSIZE 2
+
+#define SLIDER_HEIGHT 16
+
+#define SLIDER_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT)
+
+// =======================================================================
+
+void Slider::ImplInit( Window* pParent, WinBits nStyle )
+{
+ mnThumbPixOffset = 0;
+ mnThumbPixRange = 0;
+ mnThumbPixPos = 0; // between mnThumbPixOffset and mnThumbPixOffset+mnThumbPixRange
+ mnChannelPixOffset = 0;
+ mnChannelPixRange = 0;
+ mnChannelPixTop = 0;
+ mnChannelPixBottom = 0;
+
+ mnMinRange = 0;
+ mnMaxRange = 100;
+ mnThumbPos = 0;
+ mnLineSize = 1;
+ mnPageSize = 1;
+ mnDelta = 0;
+ mnDragDraw = 0;
+ mnStateFlags = 0;
+ meScrollType = SCROLL_DONTKNOW;
+ mbCalcSize = TRUE;
+ mbFullDrag = TRUE;
+
+ ImplInitStyle( nStyle );
+ Control::ImplInit( pParent, nStyle, NULL );
+
+ ImplInitSettings();
+ SetSizePixel( CalcWindowSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::ImplInitStyle( WinBits nStyle )
+{
+}
+
+// -----------------------------------------------------------------------
+
+Slider::Slider( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_SLIDER )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+Slider::Slider( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_SLIDER )
+{
+ rResId.SetRT( RSC_SCROLLBAR );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::ImplLoadRes( const ResId& rResId )
+{
+ Control::ImplLoadRes( rResId );
+
+ INT16 nMin = ReadShortRes();
+ INT16 nMax = ReadShortRes();
+ INT16 nThumbPos = ReadShortRes();
+ INT16 nPage = ReadShortRes();
+ INT16 nStep = ReadShortRes();
+ INT16 nVisibleSize = ReadShortRes();
+
+ SetRange( Range( nMin, nMax ) );
+ SetLineSize( nStep );
+ SetPageSize( nPage );
+ SetThumbPos( nThumbPos );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::ImplInitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Window* pParent = GetParent();
+ if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::ImplUpdateRects( BOOL bUpdate )
+{
+ Rectangle aOldThumbRect = maThumbRect;
+
+ if ( mnThumbPixRange )
+ {
+ if ( GetStyle() & WB_HORZ )
+ {
+ maThumbRect.Left() = mnThumbPixPos-SLIDER_THUMB_HALFSIZE;
+ maThumbRect.Right() = maThumbRect.Left()+SLIDER_THUMB_SIZE-1;
+ if ( mnChannelPixOffset < maThumbRect.Left() )
+ {
+ maChannel1Rect.Left() = mnChannelPixOffset;
+ maChannel1Rect.Right() = maThumbRect.Left()-1;
+ maChannel1Rect.Top() = mnChannelPixTop;
+ maChannel1Rect.Bottom() = mnChannelPixBottom;
+ }
+ else
+ maChannel1Rect.SetEmpty();
+ if ( mnChannelPixOffset+mnChannelPixRange-1 > maThumbRect.Right() )
+ {
+ maChannel2Rect.Left() = maThumbRect.Right()+1;
+ maChannel2Rect.Right() = mnChannelPixOffset+mnChannelPixRange-1;
+ maChannel2Rect.Top() = mnChannelPixTop;
+ maChannel2Rect.Bottom() = mnChannelPixBottom;
+ }
+ else
+ maChannel2Rect.SetEmpty();
+ }
+ else
+ {
+ maThumbRect.Top() = mnThumbPixPos-SLIDER_THUMB_HALFSIZE;
+ maThumbRect.Bottom() = maThumbRect.Top()+SLIDER_THUMB_SIZE-1;
+ if ( mnChannelPixOffset < maThumbRect.Top() )
+ {
+ maChannel1Rect.Top() = mnChannelPixOffset;
+ maChannel1Rect.Bottom() = maThumbRect.Top()-1;
+ maChannel1Rect.Left() = mnChannelPixTop;
+ maChannel1Rect.Right() = mnChannelPixBottom;
+ }
+ else
+ maChannel1Rect.SetEmpty();
+ if ( mnChannelPixOffset+mnChannelPixRange-1 > maThumbRect.Bottom() )
+ {
+ maChannel2Rect.Top() = maThumbRect.Bottom()+1;
+ maChannel2Rect.Bottom() = mnChannelPixOffset+mnChannelPixRange-1;
+ maChannel2Rect.Left() = mnChannelPixTop;
+ maChannel2Rect.Right() = mnChannelPixBottom;
+ }
+ else
+ maChannel2Rect.SetEmpty();
+ }
+ }
+ else
+ {
+ maChannel1Rect.SetEmpty();
+ maChannel2Rect.SetEmpty();
+ maThumbRect.SetEmpty();
+ }
+
+ if ( bUpdate )
+ {
+ if ( aOldThumbRect != maThumbRect )
+ {
+ Region aInvalidRegion( aOldThumbRect );
+ aInvalidRegion.Union( maThumbRect );
+ Invalidate( aInvalidRegion );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long Slider::ImplCalcThumbPos( long nPixPos )
+{
+ // Position berechnen
+ long nCalcThumbPos;
+ nCalcThumbPos = ImplMulDiv( nPixPos-mnThumbPixOffset, mnMaxRange-mnMinRange, mnThumbPixRange-1 );
+ nCalcThumbPos += mnMinRange;
+ return nCalcThumbPos;
+}
+
+// -----------------------------------------------------------------------
+
+long Slider::ImplCalcThumbPosPix( long nPos )
+{
+ // Position berechnen
+ long nCalcThumbPos;
+ nCalcThumbPos = ImplMulDiv( nPos-mnMinRange, mnThumbPixRange-1, mnMaxRange-mnMinRange );
+ // Am Anfang und Ende des Sliders versuchen wir die Anzeige korrekt
+ // anzuzeigen
+ if ( !nCalcThumbPos && (mnThumbPos > mnMinRange) )
+ nCalcThumbPos = 1;
+ if ( nCalcThumbPos &&
+ (nCalcThumbPos == mnThumbPixRange-1) &&
+ (mnThumbPos < mnMaxRange) )
+ nCalcThumbPos--;
+ return nCalcThumbPos+mnThumbPixOffset;
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::ImplCalc( BOOL bUpdate )
+{
+ BOOL bInvalidateAll = FALSE;
+
+ if ( mbCalcSize )
+ {
+ long nOldChannelPixOffset = mnChannelPixOffset;
+ long nOldChannelPixRange = mnChannelPixRange;
+ long nOldChannelPixTop = mnChannelPixTop;
+ long nOldChannelPixBottom = mnChannelPixBottom;
+ long nCalcWidth;
+ long nCalcHeight;
+
+ maChannel1Rect.SetEmpty();
+ maChannel2Rect.SetEmpty();
+ maThumbRect.SetEmpty();
+
+ Size aSize = GetOutputSizePixel();
+ if ( GetStyle() & WB_HORZ )
+ {
+ nCalcWidth = aSize.Width();
+ nCalcHeight = aSize.Height();
+ maThumbRect.Top() = 0;
+ maThumbRect.Bottom()= aSize.Height()-1;
+ }
+ else
+ {
+ nCalcWidth = aSize.Height();
+ nCalcHeight = aSize.Width();
+ maThumbRect.Left() = 0;
+ maThumbRect.Right() = aSize.Width()-1;
+ }
+
+ if ( nCalcWidth >= SLIDER_THUMB_SIZE )
+ {
+ mnThumbPixOffset = SLIDER_THUMB_HALFSIZE;
+ mnThumbPixRange = nCalcWidth-(SLIDER_THUMB_HALFSIZE*2);
+ mnThumbPixPos = 0;
+ mnChannelPixOffset = SLIDER_CHANNEL_OFFSET;
+ mnChannelPixRange = nCalcWidth-(SLIDER_CHANNEL_OFFSET*2);
+ mnChannelPixTop = (nCalcHeight/2)-SLIDER_CHANNEL_HALFSIZE;
+ mnChannelPixBottom = mnChannelPixTop+SLIDER_CHANNEL_SIZE-1;
+ }
+ else
+ {
+ mnThumbPixRange = 0;
+ mnChannelPixRange = 0;
+ }
+
+ if ( (nOldChannelPixOffset != mnChannelPixOffset) ||
+ (nOldChannelPixRange != mnChannelPixRange) ||
+ (nOldChannelPixTop != mnChannelPixTop) ||
+ (nOldChannelPixBottom != mnChannelPixBottom) )
+ bInvalidateAll = TRUE;
+
+ mbCalcSize = FALSE;
+ }
+
+ if ( mnThumbPixRange )
+ mnThumbPixPos = ImplCalcThumbPosPix( mnThumbPos );
+
+ if ( bUpdate && bInvalidateAll )
+ {
+ Invalidate();
+ bUpdate = FALSE;
+ }
+ ImplUpdateRects( bUpdate );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::ImplDraw( USHORT nDrawFlags )
+{
+ DecorationView aDecoView( this );
+ USHORT nStyle;
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ BOOL bEnabled = IsEnabled();
+
+ // Evt. noch offene Berechnungen nachholen
+ if ( mbCalcSize )
+ ImplCalc( FALSE );
+
+ if ( (nDrawFlags & SLIDER_DRAW_CHANNEL1) && !maChannel1Rect.IsEmpty() )
+ {
+ long nRectSize;
+ Rectangle aRect = maChannel1Rect;
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ if ( GetStyle() & WB_HORZ )
+ {
+ DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-1 ) );
+ DrawLine( aRect.TopLeft(), aRect.TopRight() );
+ }
+ else
+ {
+ DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
+ DrawLine( aRect.TopLeft(), aRect.BottomLeft() );
+ }
+ SetLineColor( rStyleSettings.GetLightColor() );
+ if ( GetStyle() & WB_HORZ )
+ {
+ DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
+ nRectSize = aRect.GetWidth();
+ }
+ else
+ {
+ DrawLine( aRect.TopRight(), aRect.BottomRight() );
+ nRectSize = aRect.GetHeight();
+ }
+
+ if ( nRectSize > 1 )
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ if ( GetStyle() & WB_HORZ )
+ aRect.Bottom()--;
+ else
+ aRect.Right()--;
+ SetLineColor();
+ if ( mnStateFlags & SLIDER_STATE_CHANNEL1_DOWN )
+ SetFillColor( rStyleSettings.GetShadowColor() );
+ else
+ SetFillColor( rStyleSettings.GetCheckedColor() );
+ DrawRect( aRect );
+ }
+ }
+
+ if ( (nDrawFlags & SLIDER_DRAW_CHANNEL2) && !maChannel2Rect.IsEmpty() )
+ {
+ long nRectSize;
+ Rectangle aRect = maChannel2Rect;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ if ( GetStyle() & WB_HORZ )
+ {
+ DrawLine( aRect.TopRight(), aRect.BottomRight() );
+ DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
+ nRectSize = aRect.GetWidth();
+ }
+ else
+ {
+ DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
+ DrawLine( aRect.TopRight(), aRect.BottomRight() );
+ nRectSize = aRect.GetHeight();
+ }
+
+ if ( nRectSize > 1 )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ if ( GetStyle() & WB_HORZ )
+ DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
+ else
+ DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-1 ) );
+
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( GetStyle() & WB_HORZ )
+ aRect.Top()++;
+ else
+ aRect.Left()++;
+ SetLineColor();
+ if ( mnStateFlags & SLIDER_STATE_CHANNEL2_DOWN )
+ SetFillColor( rStyleSettings.GetShadowColor() );
+ else
+ SetFillColor( rStyleSettings.GetCheckedColor() );
+ DrawRect( aRect );
+ }
+ }
+
+ if ( nDrawFlags & SLIDER_DRAW_THUMB )
+ {
+ if ( !maThumbRect.IsEmpty() )
+ {
+ if ( bEnabled )
+ {
+ nStyle = 0;
+ if ( mnStateFlags & SLIDER_STATE_THUMB_DOWN )
+ nStyle |= BUTTON_DRAW_PRESSED;
+ aDecoView.DrawButton( maThumbRect, nStyle );
+ }
+ else
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ SetFillColor( rStyleSettings.GetCheckedColor() );
+ DrawRect( maThumbRect );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Slider::ImplIsPageUp( const Point& rPos )
+{
+ Size aSize = GetOutputSizePixel();
+ Rectangle aRect = maChannel1Rect;
+ if ( GetStyle() & WB_HORZ )
+ {
+ aRect.Top() = 0;
+ aRect.Bottom() = aSize.Height()-1;
+ }
+ else
+ {
+ aRect.Left() = 0;
+ aRect.Right() = aSize.Width()-1;
+ }
+ return aRect.IsInside( rPos );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Slider::ImplIsPageDown( const Point& rPos )
+{
+ Size aSize = GetOutputSizePixel();
+ Rectangle aRect = maChannel2Rect;
+ if ( GetStyle() & WB_HORZ )
+ {
+ aRect.Top() = 0;
+ aRect.Bottom() = aSize.Height()-1;
+ }
+ else
+ {
+ aRect.Left() = 0;
+ aRect.Right() = aSize.Width()-1;
+ }
+ return aRect.IsInside( rPos );
+}
+
+// -----------------------------------------------------------------------
+
+long Slider::ImplSlide( long nNewPos, BOOL bCallEndSlide )
+{
+ long nOldPos = mnThumbPos;
+ SetThumbPos( nNewPos );
+ long nDelta = mnThumbPos-nOldPos;
+ if ( nDelta )
+ {
+ mnDelta = nDelta;
+ Slide();
+ if ( bCallEndSlide )
+ EndSlide();
+ mnDelta = 0;
+ }
+ return nDelta;
+}
+
+// -----------------------------------------------------------------------
+
+long Slider::ImplDoAction( BOOL bCallEndSlide )
+{
+ long nDelta = 0;
+
+ switch ( meScrollType )
+ {
+ case SCROLL_LINEUP:
+ nDelta = ImplSlide( mnThumbPos-mnLineSize, bCallEndSlide );
+ break;
+
+ case SCROLL_LINEDOWN:
+ nDelta = ImplSlide( mnThumbPos+mnLineSize, bCallEndSlide );
+ break;
+
+ case SCROLL_PAGEUP:
+ nDelta = ImplSlide( mnThumbPos-mnPageSize, bCallEndSlide );
+ break;
+
+ case SCROLL_PAGEDOWN:
+ nDelta = ImplSlide( mnThumbPos+mnPageSize, bCallEndSlide );
+ break;
+ }
+
+ return nDelta;
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::ImplDoMouseAction( const Point& rMousePos, BOOL bCallAction )
+{
+ USHORT nOldStateFlags = mnStateFlags;
+ BOOL bAction = FALSE;
+
+ switch ( meScrollType )
+ {
+ case SCROLL_PAGEUP:
+ if ( ImplIsPageUp( rMousePos ) )
+ {
+ bAction = bCallAction;
+ mnStateFlags |= SLIDER_STATE_CHANNEL1_DOWN;
+ }
+ else
+ mnStateFlags &= ~SLIDER_STATE_CHANNEL1_DOWN;
+ break;
+
+ case SCROLL_PAGEDOWN:
+ if ( ImplIsPageDown( rMousePos ) )
+ {
+ bAction = bCallAction;
+ mnStateFlags |= SLIDER_STATE_CHANNEL2_DOWN;
+ }
+ else
+ mnStateFlags &= ~SLIDER_STATE_CHANNEL2_DOWN;
+ break;
+ }
+
+ if ( bAction )
+ {
+ if ( ImplDoAction( FALSE ) )
+ {
+ // Update the channel complete
+ if ( mnDragDraw & SLIDER_DRAW_CHANNEL )
+ {
+ Update();
+ ImplDraw( mnDragDraw );
+ }
+ }
+ }
+ else if ( nOldStateFlags != mnStateFlags )
+ ImplDraw( mnDragDraw );
+}
+
+// -----------------------------------------------------------------------
+
+long Slider::ImplDoSlide( long nNewPos )
+{
+ if ( meScrollType != SCROLL_DONTKNOW )
+ return 0;
+
+ meScrollType = SCROLL_DRAG;
+ long nDelta = ImplSlide( nNewPos, TRUE );
+ meScrollType = SCROLL_DONTKNOW;
+ return nDelta;
+}
+
+// -----------------------------------------------------------------------
+
+long Slider::ImplDoSlideAction( ScrollType eScrollType )
+{
+ if ( (meScrollType != SCROLL_DONTKNOW) ||
+ (eScrollType == SCROLL_DONTKNOW) ||
+ (eScrollType == SCROLL_DRAG) )
+ return 0;
+
+ meScrollType = eScrollType;
+ long nDelta = ImplDoAction( TRUE );
+ meScrollType = SCROLL_DONTKNOW;
+ return nDelta;
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ {
+ const Point& rMousePos = rMEvt.GetPosPixel();
+ USHORT nTrackFlags = 0;
+
+ if ( maThumbRect.IsInside( rMousePos ) )
+ {
+ nTrackFlags = 0;
+ meScrollType = SCROLL_DRAG;
+ mnDragDraw = SLIDER_DRAW_THUMB;
+
+ // Zusaetzliche Daten berechnen
+ Point aCenterPos = maThumbRect.Center();
+ if ( GetStyle() & WB_HORZ )
+ mnMouseOff = rMousePos.X()-aCenterPos.X();
+ else
+ mnMouseOff = rMousePos.Y()-aCenterPos.Y();
+
+ // Im OS2-Look geben wir den Thumb gedrueckt aus
+ if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_OS2STYLE )
+ {
+ mnStateFlags |= SLIDER_STATE_THUMB_DOWN;
+ ImplDraw( SLIDER_DRAW_THUMB );
+ }
+ }
+ else if ( ImplIsPageUp( rMousePos ) )
+ {
+ nTrackFlags = STARTTRACK_BUTTONREPEAT;
+ meScrollType = SCROLL_PAGEUP;
+ mnDragDraw = SLIDER_DRAW_CHANNEL;
+ }
+ else if ( ImplIsPageDown( rMousePos ) )
+ {
+ nTrackFlags = STARTTRACK_BUTTONREPEAT;
+ meScrollType = SCROLL_PAGEDOWN;
+ mnDragDraw = SLIDER_DRAW_CHANNEL;
+ }
+
+ // Soll Tracking gestartet werden
+ if ( meScrollType != SCROLL_DONTKNOW )
+ {
+ // Startposition merken fuer Abbruch und EndScroll-Delta
+ mnStartPos = mnThumbPos;
+ ImplDoMouseAction( rMousePos );
+ Update();
+ StartTracking( nTrackFlags );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ // Button und PageRect-Status wieder herstellen
+ USHORT nOldStateFlags = mnStateFlags;
+ mnStateFlags &= ~(SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN |
+ SLIDER_STATE_THUMB_DOWN);
+ if ( nOldStateFlags != mnStateFlags )
+ ImplDraw( mnDragDraw );
+ mnDragDraw = 0;
+
+ // Bei Abbruch, die alte ThumbPosition wieder herstellen
+ if ( rTEvt.IsTrackingCanceled() )
+ {
+ long nOldPos = mnThumbPos;
+ SetThumbPos( mnStartPos );
+ mnDelta = mnThumbPos-nOldPos;
+ Slide();
+ }
+
+ if ( meScrollType == SCROLL_DRAG )
+ {
+ // Wenn gedragt wurde, berechnen wir den Thumb neu, damit
+ // er wieder auf einer gerundeten ThumbPosition steht
+ ImplCalc();
+ Update();
+
+ if ( !mbFullDrag && (mnStartPos != mnThumbPos) )
+ {
+ mnDelta = mnThumbPos-mnStartPos;
+ Slide();
+ mnDelta = 0;
+ }
+ }
+
+ mnDelta = mnThumbPos-mnStartPos;
+ EndSlide();
+ mnDelta = 0;
+ meScrollType = SCROLL_DONTKNOW;
+ }
+ else
+ {
+ const Point rMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+
+ // Dragging wird speziell behandelt
+ if ( meScrollType == SCROLL_DRAG )
+ {
+ long nMovePix;
+ Point aCenterPos = maThumbRect.Center();
+ if ( GetStyle() & WB_HORZ )
+ nMovePix = rMousePos.X()-(aCenterPos.X()+mnMouseOff);
+ else
+ nMovePix = rMousePos.Y()-(aCenterPos.Y()+mnMouseOff);
+ // Nur wenn sich Maus in die Scrollrichtung bewegt, muessen
+ // wir etwas tun
+ if ( nMovePix )
+ {
+ mnThumbPixPos += nMovePix;
+ if ( mnThumbPixPos < mnThumbPixOffset )
+ mnThumbPixPos = mnThumbPixOffset;
+ if ( mnThumbPixPos > (mnThumbPixOffset+mnThumbPixRange-1) )
+ mnThumbPixPos = mnThumbPixOffset+mnThumbPixRange-1;
+ long nOldPos = mnThumbPos;
+ mnThumbPos = ImplCalcThumbPos( mnThumbPixPos );
+ if ( nOldPos != mnThumbPos )
+ {
+ ImplUpdateRects();
+ Update();
+ if ( mbFullDrag && (nOldPos != mnThumbPos) )
+ {
+ mnDelta = mnThumbPos-nOldPos;
+ Slide();
+ mnDelta = 0;
+ }
+ }
+ }
+ }
+ else
+ ImplDoMouseAction( rMousePos, rTEvt.IsTrackingRepeat() );
+
+ // Wenn Slider-Werte so umgesetzt wurden, das es nichts
+ // mehr zum Tracking gibt, dann berechen wir hier ab
+ if ( !IsVisible() )
+ EndTracking();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::KeyInput( const KeyEvent& rKEvt )
+{
+ if ( !rKEvt.GetKeyCode().GetModifier() )
+ {
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_HOME:
+ ImplDoSlide( GetRangeMin() );
+ break;
+ case KEY_END:
+ ImplDoSlide( GetRangeMax() );
+ break;
+
+ case KEY_LEFT:
+ case KEY_UP:
+ ImplDoSlideAction( SCROLL_LINEUP );
+ break;
+
+ case KEY_RIGHT:
+ case KEY_DOWN:
+ ImplDoSlideAction( SCROLL_LINEDOWN );
+ break;
+
+ case KEY_PAGEUP:
+ ImplDoSlideAction( SCROLL_PAGEUP );
+ break;
+
+ case KEY_PAGEDOWN:
+ ImplDoSlideAction( SCROLL_PAGEDOWN );
+ break;
+
+ default:
+ Control::KeyInput( rKEvt );
+ break;
+ }
+ }
+ else
+ Control::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::Paint( const Rectangle& rRect )
+{
+ ImplDraw( SLIDER_DRAW_ALL );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::Resize()
+{
+ mbCalcSize = TRUE;
+ if ( IsReallyVisible() )
+ ImplCalc( FALSE );
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::RequestHelp( const HelpEvent& rHEvt )
+{
+ Control::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ImplCalc( FALSE );
+ else if ( nType == STATE_CHANGE_DATA )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplCalc( TRUE );
+ }
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplCalc( FALSE );
+ Invalidate();
+ }
+ }
+ else if ( nType == STATE_CHANGE_ENABLE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ ImplInitStyle( GetStyle() );
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ if ( (GetPrevStyle() & SLIDER_VIEW_STYLE) !=
+ (GetStyle() & SLIDER_VIEW_STYLE) )
+ {
+ mbCalcSize = TRUE;
+ ImplCalc( FALSE );
+ Invalidate();
+ }
+ }
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::Slide()
+{
+ maSlideHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::EndSlide()
+{
+ maEndSlideHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::SetRangeMin( long nNewRange )
+{
+ SetRange( Range( nNewRange, GetRangeMax() ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::SetRangeMax( long nNewRange )
+{
+ SetRange( Range( GetRangeMin(), nNewRange ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::SetRange( const Range& rRange )
+{
+ // Range einpassen
+ Range aRange = rRange;
+ aRange.Justify();
+ long nNewMinRange = aRange.Min();
+ long nNewMaxRange = aRange.Max();
+
+ // Wenn Range sich unterscheidet, dann neuen setzen
+ if ( (mnMinRange != nNewMinRange) ||
+ (mnMaxRange != nNewMaxRange) )
+ {
+ mnMinRange = nNewMinRange;
+ mnMaxRange = nNewMaxRange;
+
+ // Thumb einpassen
+ if ( mnThumbPos > mnMaxRange )
+ mnThumbPos = mnMaxRange;
+ if ( mnThumbPos < mnMinRange )
+ mnThumbPos = mnMinRange;
+
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Slider::SetThumbPos( long nNewThumbPos )
+{
+ if ( nNewThumbPos < mnMinRange )
+ nNewThumbPos = mnMinRange;
+ if ( nNewThumbPos > mnMaxRange )
+ nNewThumbPos = mnMaxRange;
+
+ if ( mnThumbPos != nNewThumbPos )
+ {
+ mnThumbPos = nNewThumbPos;
+ StateChanged( STATE_CHANGE_DATA );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size Slider::CalcWindowSizePixel()
+{
+ long nWidth = mnMaxRange-mnMinRange+(SLIDER_THUMB_HALFSIZE*2)+1;
+ long nHeight = SLIDER_HEIGHT;
+ Size aSize;
+ if ( GetStyle() & WB_HORZ )
+ {
+ aSize.Width() = nWidth;
+ aSize.Height() = nHeight;
+ }
+ else
+ {
+ aSize.Height() = nWidth;
+ aSize.Width() = nHeight;
+ }
+ return aSize;
+}
diff --git a/vcl/source/control/spinbtn.cxx b/vcl/source/control/spinbtn.cxx
new file mode 100644
index 000000000000..d2d91f1158c4
--- /dev/null
+++ b/vcl/source/control/spinbtn.cxx
@@ -0,0 +1,313 @@
+/*************************************************************************
+ *
+ * $RCSfile: spinbtn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SPIN_CXX
+
+#ifndef _SV_RCID_H
+#include <rcid.h>
+#endif
+#ifndef _SV_SPIN_H
+#include <spin.h>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SPIN_HXX
+#include <spin.hxx>
+#endif
+
+// =======================================================================
+
+void SpinButton::ImplInit( Window* pParent, WinBits nStyle )
+{
+ mbUpperIn = FALSE;
+ mbLowerIn = FALSE;
+ mbInitialUp = FALSE;
+ mbInitialDown = FALSE;
+
+ if ( nStyle & WB_REPEAT )
+ {
+ mbRepeat = TRUE;
+
+ maRepeatTimer.SetTimeout( SPIN_DELAY );
+ maRepeatTimer.SetTimeoutHdl( LINK( this, SpinButton, ImplTimeout ) );
+ }
+ else
+ mbRepeat = FALSE;
+
+ if ( nStyle & WB_HSCROLL )
+ mbHorz = TRUE;
+ else
+ mbHorz = FALSE;
+
+ Control::ImplInit( pParent, nStyle, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+SpinButton::SpinButton( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_SPINBUTTON )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+SpinButton::SpinButton( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_SPINBUTTON )
+{
+ rResId.SetRT( RSC_SPINBUTTON );
+ ImplInit( pParent, ImplInitRes( rResId ) );
+ ImplLoadRes( rResId );
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+SpinButton::~SpinButton()
+{
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( SpinButton, ImplTimeout, Timer*, pTimer )
+{
+ if ( pTimer->GetTimeout() == SPIN_DELAY )
+ {
+ pTimer->SetTimeout( SPIN_SPEED );
+ pTimer->Start();
+ }
+ else
+ {
+ if ( mbInitialUp )
+ Up();
+ else
+ Down();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SpinButton::Up()
+{
+ maUpHdlLink.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void SpinButton::Down()
+{
+ maDownHdlLink.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void SpinButton::Resize()
+{
+ Size aSize( GetOutputSizePixel() );
+ Point aTmpPoint;
+ Rectangle aRect( aTmpPoint, aSize );
+ if ( mbHorz )
+ {
+ maUpperRect = Rectangle( 0, 0, aSize.Width()/2, aSize.Height()-1 );
+ maLowerRect = Rectangle( maUpperRect.TopRight(), aRect.BottomRight() );
+ }
+ else
+ {
+ maUpperRect = Rectangle( 0, 0, aSize.Width()-1, aSize.Height()/2 );
+ maLowerRect = Rectangle( maUpperRect.BottomLeft(), aRect.BottomRight() );
+ }
+
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void SpinButton::Paint( const Rectangle& )
+{
+ BOOL bEnable = IsEnabled();
+ ImplDrawSpinButton( this, maUpperRect, maLowerRect, mbUpperIn, mbLowerIn,
+ bEnable, bEnable, mbHorz );
+}
+
+// -----------------------------------------------------------------------
+
+void SpinButton::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( maUpperRect.IsInside( rMEvt.GetPosPixel() ) )
+ {
+ mbUpperIn = TRUE;
+ mbInitialUp = TRUE;
+ Invalidate( maUpperRect );
+ }
+ else if ( maLowerRect.IsInside( rMEvt.GetPosPixel() ) )
+ {
+ mbLowerIn = TRUE;
+ mbInitialDown = TRUE;
+ Invalidate( maLowerRect );
+ }
+
+ if ( mbUpperIn || mbLowerIn )
+ {
+ Update();
+ CaptureMouse();
+ if ( mbRepeat )
+ maRepeatTimer.Start();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SpinButton::MouseButtonUp( const MouseEvent& )
+{
+ ReleaseMouse();
+
+ if ( mbUpperIn )
+ {
+ mbUpperIn = FALSE;
+ Invalidate( maUpperRect );
+ Update();
+ Up();
+ }
+ else if ( mbLowerIn )
+ {
+ mbLowerIn = FALSE;
+ Invalidate( maLowerRect );
+ Update();
+ Down();
+ }
+
+ mbInitialUp = mbInitialDown = FALSE;
+
+ if ( mbRepeat )
+ {
+ maRepeatTimer.Stop();
+ maRepeatTimer.SetTimeout( SPIN_DELAY );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SpinButton::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( !rMEvt.IsLeft() || (!mbInitialUp && !mbInitialDown) )
+ return;
+
+ if ( !maUpperRect.IsInside( rMEvt.GetPosPixel() ) &&
+ mbUpperIn && mbInitialUp )
+ {
+ mbUpperIn = FALSE;
+ maRepeatTimer.Stop();
+ Invalidate( maUpperRect );
+ Update();
+ }
+ else if ( !maLowerRect.IsInside( rMEvt.GetPosPixel() ) &&
+ mbLowerIn & mbInitialDown )
+ {
+ mbLowerIn = FALSE;
+ maRepeatTimer.Stop();
+ Invalidate( maLowerRect );
+ Update();
+ }
+ else if ( maUpperRect.IsInside( rMEvt.GetPosPixel() ) &&
+ !mbUpperIn && mbInitialUp )
+ {
+ mbUpperIn = TRUE;
+ if ( mbRepeat )
+ maRepeatTimer.Start();
+ Invalidate( maUpperRect );
+ Update();
+ }
+ else if ( maLowerRect.IsInside( rMEvt.GetPosPixel() ) &&
+ !mbLowerIn && mbInitialDown )
+ {
+ mbLowerIn = TRUE;
+ if ( mbRepeat )
+ maRepeatTimer.Start();
+ Invalidate( maLowerRect );
+ Update();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SpinButton::KeyInput( const KeyEvent& rKEvt )
+{
+ KeyCode aCode = rKEvt.GetKeyCode();
+
+ if ( aCode.GetCode() == KEY_UP )
+ Up();
+ else if( aCode.GetCode() == KEY_DOWN )
+ Down();
+ else
+ Control::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void SpinButton::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_ENABLE )
+ Invalidate();
+ Control::StateChanged( nType );
+}
diff --git a/vcl/source/control/spinfld.cxx b/vcl/source/control/spinfld.cxx
new file mode 100644
index 000000000000..d87d20865726
--- /dev/null
+++ b/vcl/source/control/spinfld.cxx
@@ -0,0 +1,791 @@
+/*************************************************************************
+ *
+ * $RCSfile: spinfld.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SPINFLD_CXX
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_SPIN_H
+#include <spin.h>
+#endif
+#ifndef _SV_SPINFLD_HXX
+#include <spinfld.hxx>
+#endif
+
+// =======================================================================
+
+void ImplDrawSpinButton( OutputDevice* pOutDev,
+ const Rectangle& rUpperRect,
+ const Rectangle& rLowerRect,
+ BOOL bUpperIn, BOOL bLowerIn,
+ BOOL bUpperEnabled, BOOL bLowerEnabled, BOOL bHorz )
+{
+ DecorationView aDecoView( pOutDev );
+
+ USHORT nStyle = BUTTON_DRAW_NOLEFTLIGHTBORDER;
+ USHORT nSymStyle = 0;
+
+ SymbolType eType1, eType2;
+
+ const StyleSettings& rStyleSettings = pOutDev->GetSettings().GetStyleSettings();
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_SPINARROW )
+ {
+ if ( bHorz )
+ {
+ eType1 = SYMBOL_ARROW_LEFT;
+ eType2 = SYMBOL_ARROW_RIGHT;
+ }
+ else
+ {
+ eType1 = SYMBOL_ARROW_UP;
+ eType2 = SYMBOL_ARROW_DOWN;
+ }
+ }
+ else
+ {
+ if ( bHorz )
+ {
+ eType1 = SYMBOL_SPIN_LEFT;
+ eType2 = SYMBOL_SPIN_RIGHT;
+ }
+ else
+ {
+ eType1 = SYMBOL_SPIN_UP;
+ eType2 = SYMBOL_SPIN_DOWN;
+ }
+ }
+
+ // Oberen/linken Button malen
+ USHORT nTempStyle = nStyle;
+ if ( bUpperIn )
+ nTempStyle |= BUTTON_DRAW_PRESSED;
+ Rectangle aUpRect = aDecoView.DrawButton( rUpperRect, nTempStyle );
+
+ // Unteren/rechten Button malen
+ if ( bLowerIn )
+ nStyle |= BUTTON_DRAW_PRESSED;
+ Rectangle aLowRect = aDecoView.DrawButton( rLowerRect, nStyle );
+
+ // Zusaetzliche Default-Kante wollen wir auch ausnutzen
+ aUpRect.Left()--;
+ aUpRect.Top()--;
+ aUpRect.Right()++;
+ aUpRect.Bottom()++;
+ aLowRect.Left()--;
+ aLowRect.Top()--;
+ aLowRect.Right()++;
+ aLowRect.Bottom()++;
+
+ // Wir malen auch in die Kante rein, damit man etwas erkennen kann,
+ // wenn das Rechteck zu klein ist
+ if ( aUpRect.GetHeight() < 4 )
+ {
+ aUpRect.Right()++;
+ aUpRect.Bottom()++;
+ aLowRect.Right()++;
+ aLowRect.Bottom()++;
+ }
+
+ // Symbolgroesse berechnen
+ long nTempSize1 = aUpRect.GetWidth();
+ long nTempSize2 = aLowRect.GetWidth();
+ if ( Abs( nTempSize1-nTempSize2 ) == 1 )
+ {
+ if ( nTempSize1 > nTempSize2 )
+ aUpRect.Left()++;
+ else
+ aLowRect.Left()++;
+ }
+ nTempSize1 = aUpRect.GetHeight();
+ nTempSize2 = aLowRect.GetHeight();
+ if ( Abs( nTempSize1-nTempSize2 ) == 1 )
+ {
+ if ( nTempSize1 > nTempSize2 )
+ aUpRect.Top()++;
+ else
+ aLowRect.Top()++;
+ }
+
+ nTempStyle = nSymStyle;
+ if ( !bUpperEnabled )
+ nTempStyle |= SYMBOL_DRAW_DISABLE;
+ aDecoView.DrawSymbol( aUpRect, eType1, rStyleSettings.GetButtonTextColor(), nTempStyle );
+
+ if ( !bLowerEnabled )
+ nSymStyle |= SYMBOL_DRAW_DISABLE;
+ aDecoView.DrawSymbol( aLowRect, eType2, rStyleSettings.GetButtonTextColor(), nSymStyle );
+}
+
+// =======================================================================
+
+void SpinField::ImplInitData()
+{
+ mpEdit = NULL;
+ mbSpin = FALSE;
+ mbRepeat = FALSE;
+ mbUpperIn = FALSE;
+ mbLowerIn = FALSE;
+ mbInitialUp = FALSE;
+ mbInitialDown = FALSE;
+ mbNoSelect = FALSE;
+ mbInDropDown = FALSE;
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::ImplInit( Window* pParent, WinBits nWinStyle )
+{
+ Edit::ImplInit( pParent, nWinStyle );
+
+ if ( nWinStyle & (WB_SPIN|WB_DROPDOWN) )
+ {
+ mbSpin = TRUE;
+ mpEdit = new Edit( this, WB_NOBORDER );
+ mpEdit->SetPosPixel( Point() );
+ mpEdit->Show();
+ SetSubEdit( mpEdit );
+
+ maRepeatTimer.SetTimeoutHdl( LINK( this, SpinField, ImplTimeout ) );
+ maRepeatTimer.SetTimeout( SPIN_DELAY );
+ if ( nWinStyle & WB_REPEAT )
+ mbRepeat = TRUE;
+
+ SetCompoundControl( TRUE );
+ }
+}
+
+// --------------------------------------------------------------------
+
+SpinField::SpinField( WindowType nTyp ) :
+ Edit( nTyp )
+{
+ ImplInitData();
+}
+
+// --------------------------------------------------------------------
+
+SpinField::SpinField( Window* pParent, WinBits nWinStyle ) :
+ Edit( WINDOW_SPINFIELD )
+{
+ ImplInitData();
+ ImplInit( pParent, nWinStyle );
+}
+
+// --------------------------------------------------------------------
+
+SpinField::SpinField( Window* pParent, const ResId& rResId ) :
+ Edit( WINDOW_SPINFIELD )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_SPINFIELD );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// --------------------------------------------------------------------
+
+SpinField::~SpinField()
+{
+ delete mpEdit;
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::Up()
+{
+ maUpHdlLink.Call( this );
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::Down()
+{
+ maDownHdlLink.Call( this );
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::First()
+{
+ maFirstHdlLink.Call( this );
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::Last()
+{
+ maLastHdlLink.Call( this );
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( !HasFocus() && ( !mpEdit || !mpEdit->HasFocus() ) )
+ {
+ mbNoSelect = TRUE;
+ GrabFocus();
+ }
+
+ if ( !IsReadOnly() )
+ {
+ if ( maUpperRect.IsInside( rMEvt.GetPosPixel() ) )
+ {
+ mbUpperIn = TRUE;
+ mbInitialUp = TRUE;
+ Invalidate( maUpperRect );
+ }
+ else if ( maLowerRect.IsInside( rMEvt.GetPosPixel() ) )
+ {
+ mbLowerIn = TRUE;
+ mbInitialDown = TRUE;
+ Invalidate( maLowerRect );
+ }
+ else if ( maDropDownRect.IsInside( rMEvt.GetPosPixel() ) )
+ {
+ // Rechts daneben liegt der DropDownButton:
+ mbInDropDown = ShowDropDown( mbInDropDown ? FALSE : TRUE );
+ Paint( Rectangle( Point(), GetOutputSizePixel() ) );
+ }
+
+ if ( mbUpperIn || mbLowerIn )
+ {
+ Update();
+ CaptureMouse();
+ if ( mbRepeat )
+ maRepeatTimer.Start();
+ return;
+ }
+ }
+
+ Edit::MouseButtonDown( rMEvt );
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ ReleaseMouse();
+ mbInitialUp = mbInitialDown = FALSE;
+ maRepeatTimer.Stop();
+ maRepeatTimer.SetTimeout( SPIN_DELAY );
+
+ if ( mbUpperIn )
+ {
+ mbUpperIn = FALSE;
+ Invalidate( maUpperRect );
+ Update();
+ Up();
+ }
+ else if ( mbLowerIn )
+ {
+ mbLowerIn = FALSE;
+ Invalidate( maLowerRect );
+ Update();
+ Down();
+ }
+
+ Edit::MouseButtonUp( rMEvt );
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ {
+ if ( mbInitialUp )
+ {
+ BOOL bNewUpperIn = maUpperRect.IsInside( rMEvt.GetPosPixel() );
+ if ( bNewUpperIn != mbUpperIn )
+ {
+ if ( bNewUpperIn )
+ {
+ if ( mbRepeat )
+ maRepeatTimer.Start();
+ }
+ else
+ maRepeatTimer.Stop();
+
+ mbUpperIn = bNewUpperIn;
+ Invalidate( maUpperRect );
+ Update();
+ }
+ }
+ else if ( mbInitialDown )
+ {
+ BOOL bNewLowerIn = maLowerRect.IsInside( rMEvt.GetPosPixel() );
+ if ( bNewLowerIn != mbLowerIn )
+ {
+ if ( bNewLowerIn )
+ {
+ if ( mbRepeat )
+ maRepeatTimer.Start();
+ }
+ else
+ maRepeatTimer.Stop();
+
+ mbLowerIn = bNewLowerIn;
+ Invalidate( maLowerRect );
+ Update();
+ }
+ }
+ }
+
+ Edit::MouseMove( rMEvt );
+}
+
+// --------------------------------------------------------------------
+
+long SpinField::Notify( NotifyEvent& rNEvt )
+{
+ long nDone = 0;
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent& rKEvt = *rNEvt.GetKeyEvent();
+ if ( !IsReadOnly() )
+ {
+ USHORT nMod = rKEvt.GetKeyCode().GetModifier();
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_UP:
+ {
+ if ( !nMod )
+ {
+ Up();
+ nDone = 1;
+ }
+ }
+ break;
+ case KEY_DOWN:
+ {
+ if ( !nMod )
+ {
+ Down();
+ nDone = 1;
+ }
+ else if ( ( nMod == KEY_MOD2 ) && !mbInDropDown && ( GetStyle() & WB_DROPDOWN ) )
+ {
+ mbInDropDown = ShowDropDown( TRUE );
+ Paint( Rectangle( Point(), GetOutputSizePixel() ) );
+ nDone = 1;
+ }
+ }
+ break;
+ case KEY_PAGEUP:
+ {
+ if ( !nMod )
+ {
+ Last();
+ nDone = 1;
+ }
+ }
+ break;
+ case KEY_PAGEDOWN:
+ {
+ if ( !nMod )
+ {
+ First();
+ nDone = 1;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if ( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ if ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
+ if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
+ {
+ if ( pData->GetDelta() < 0L )
+ Down();
+ else
+ Up();
+ nDone = 1;
+ }
+ }
+ }
+
+ return nDone ? nDone : Edit::Notify( rNEvt );
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::Command( const CommandEvent& rCEvt )
+{
+ Edit::Command( rCEvt );
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::Paint( const Rectangle& rRect )
+{
+ if ( mbSpin )
+ {
+ BOOL bEnable = IsEnabled();
+ ImplDrawSpinButton( this, maUpperRect, maLowerRect,
+ mbUpperIn, mbLowerIn, bEnable, bEnable );
+ }
+
+ if ( GetStyle() & WB_DROPDOWN )
+ {
+ DecorationView aView( this );
+
+ USHORT nStyle = BUTTON_DRAW_NOLIGHTBORDER;
+ if ( mbInDropDown )
+ nStyle |= BUTTON_DRAW_PRESSED;
+ Rectangle aInnerRect = aView.DrawButton( maDropDownRect, nStyle );
+
+ SymbolType eSymbol = SYMBOL_SPIN_DOWN;
+ if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_SPINUPDOWN )
+ eSymbol = SYMBOL_SPIN_UPDOWN;
+
+ nStyle = IsEnabled() ? 0 : SYMBOL_DRAW_DISABLE;
+ aView.DrawSymbol( aInnerRect, eSymbol, GetSettings().GetStyleSettings().GetButtonTextColor(), nStyle );
+ }
+
+ Edit::Paint( rRect );
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::ImplCalcButtonAreas( OutputDevice* pDev, const Size& rOutSz, Rectangle& rDDArea, Rectangle& rSpinUpArea, Rectangle& rSpinDownArea )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Size aSize = rOutSz;
+ Size aDropDownSize;
+
+ if ( GetStyle() & WB_DROPDOWN )
+ {
+ long nW = rStyleSettings.GetScrollBarSize();
+ nW = GetDrawPixel( pDev, nW );
+ aDropDownSize = Size( CalcZoom( nW ), aSize.Height() );
+ aSize.Width() -= aDropDownSize.Width();
+ rDDArea = Rectangle( Point( aSize.Width(), 0 ), aDropDownSize );
+ rDDArea.Top()--;
+ }
+ else
+ rDDArea.SetEmpty();
+
+ // Je nach Hoehe, die groessen Berechnen
+ if ( GetStyle() & WB_SPIN )
+ {
+ long nBottom1 = aSize.Height()/2;
+ long nTop2 = nBottom1;
+ if ( !(aSize.Height() & 0x01) )
+ nBottom1--;
+
+ aSize.Width() -= CalcZoom( GetDrawPixel( pDev, rStyleSettings.GetSpinSize() ) );
+ rSpinUpArea = Rectangle( aSize.Width(), 0, rOutSz.Width()-aDropDownSize.Width()-1, nBottom1 );
+ rSpinDownArea = Rectangle( rSpinUpArea.Left(), nTop2, rSpinUpArea.Right(), aSize.Height()-1 );
+ }
+ else
+ {
+ rSpinUpArea.SetEmpty();
+ rSpinDownArea.SetEmpty();
+ }
+}
+
+// --------------------------------------------------------------------
+
+void SpinField::Resize()
+{
+ if ( mbSpin )
+ {
+ Size aSize = GetOutputSizePixel();
+
+ if ( GetStyle() & (WB_SPIN|WB_DROPDOWN) )
+ {
+ ImplCalcButtonAreas( this, aSize, maDropDownRect, maUpperRect, maLowerRect );
+ aSize.Width() -= maDropDownRect.GetWidth();
+ aSize.Width() -= maUpperRect.GetWidth();
+ }
+
+ mpEdit->SetSizePixel( aSize );
+
+ if ( GetStyle() & WB_SPIN )
+ Invalidate( Rectangle( maUpperRect.TopLeft(), maLowerRect.BottomRight() ) );
+ if ( GetStyle() & WB_DROPDOWN )
+ Invalidate( maDropDownRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SpinField::StateChanged( StateChangedType nType )
+{
+ Edit::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_ENABLE )
+ {
+ if ( mbSpin || ( GetStyle() & WB_DROPDOWN ) )
+ {
+ mpEdit->Enable( IsEnabled() );
+
+ if ( mbSpin )
+ {
+ Invalidate( maLowerRect );
+ Invalidate( maUpperRect );
+ }
+ if ( GetStyle() & WB_DROPDOWN )
+ Invalidate( maDropDownRect );
+ }
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ if ( GetStyle() & WB_REPEAT )
+ mbRepeat = TRUE;
+ else
+ mbRepeat = FALSE;
+ }
+ else if ( nType == STATE_CHANGE_ZOOM )
+ {
+ Resize();
+ if ( mpEdit )
+ mpEdit->SetZoom( GetZoom() );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ if ( mpEdit )
+ mpEdit->SetControlFont( GetControlFont() );
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ if ( mpEdit )
+ mpEdit->SetControlForeground( GetControlForeground() );
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ if ( mpEdit )
+ mpEdit->SetControlBackground( GetControlBackground() );
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SpinField::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Edit::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ Resize();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SpinField::EndDropDown()
+{
+ mbInDropDown = FALSE;
+ Paint( Rectangle( Point(), GetOutputSizePixel() ) );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SpinField::ShowDropDown( BOOL bShow )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Size SpinField::CalcMinimumSize() const
+{
+ Size aSz = Edit::CalcMinimumSize();
+
+ if ( GetStyle() & WB_DROPDOWN )
+ aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( GetStyle() & WB_SPIN )
+ aSz.Width() += GetSettings().GetStyleSettings().GetSpinSize();
+
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+Size SpinField::CalcSize( USHORT nChars ) const
+{
+ Size aSz = Edit::CalcSize( nChars );
+
+ if ( GetStyle() & WB_DROPDOWN )
+ aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( GetStyle() & WB_SPIN )
+ aSz.Width() += GetSettings().GetStyleSettings().GetSpinSize();
+
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SpinField::GetMaxVisChars() const
+{
+ long nOutWidth = mpEdit->GetOutputSizePixel().Width();
+ long nCharWidth = GetTextWidth( XubString( 'x' ) );
+ return nCharWidth ? (USHORT)(nOutWidth/nCharWidth) : 0;
+}
+
+// --------------------------------------------------------------------
+
+IMPL_LINK( SpinField, ImplTimeout, Timer*, pTimer )
+{
+ if ( pTimer->GetTimeout() == SPIN_DELAY )
+ {
+ pTimer->SetTimeout( SPIN_SPEED );
+ pTimer->Start();
+ }
+ else
+ {
+ if ( mbInitialUp )
+ Up();
+ else
+ Down();
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SpinField::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
+{
+ Edit::Draw( pDev, rPos, rSize, nFlags );
+
+ WinBits nStyle = GetStyle();
+ if ( !(nFlags & WINDOW_DRAW_NOCONTROLS ) && ( nStyle & (WB_SPIN|WB_DROPDOWN) ) )
+ {
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ OutDevType eOutDevType = pDev->GetOutDevType();
+ AllSettings aOldSettings = pDev->GetSettings();
+
+ pDev->Push();
+ pDev->SetMapMode();
+
+ if ( eOutDevType == OUTDEV_PRINTER )
+ {
+ StyleSettings aStyleSettings = aOldSettings.GetStyleSettings();
+ aStyleSettings.SetFaceColor( COL_LIGHTGRAY );
+ aStyleSettings.SetButtonTextColor( COL_BLACK );
+ AllSettings aSettings( aOldSettings );
+ aSettings.SetStyleSettings( aStyleSettings );
+ pDev->SetSettings( aSettings );
+ }
+
+ Rectangle aDD, aUp, aDown;
+ ImplCalcButtonAreas( pDev, aSize, aDD, aUp, aDown );
+ aDD.Move( aPos.X(), aPos.Y() );
+ aUp.Move( aPos.X(), aPos.Y() );
+ aUp.Top()++;
+ aDown.Move( aPos.X(), aPos.Y() );
+
+ Color aButtonTextColor;
+ if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
+ aButtonTextColor = Color( COL_BLACK );
+ else
+ aButtonTextColor = GetSettings().GetStyleSettings().GetButtonTextColor();
+
+ if ( GetStyle() & WB_DROPDOWN )
+ {
+ DecorationView aView( pDev );
+ USHORT nStyle = BUTTON_DRAW_NOLIGHTBORDER;
+ Rectangle aInnerRect = aView.DrawButton( aDD, nStyle );
+ SymbolType eSymbol = SYMBOL_SPIN_DOWN;
+ if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_SPINUPDOWN )
+ eSymbol = SYMBOL_SPIN_UPDOWN;
+
+ nStyle = ( IsEnabled() || ( nFlags & WINDOW_DRAW_NODISABLE ) ) ? 0 : SYMBOL_DRAW_DISABLE;
+ aView.DrawSymbol( aInnerRect, eSymbol, aButtonTextColor, nStyle );
+ }
+
+ if ( GetStyle() & WB_SPIN )
+ {
+ ImplDrawSpinButton( pDev, aUp, aDown, FALSE, FALSE, TRUE, TRUE );
+ }
+
+ pDev->Pop();
+ pDev->SetSettings( aOldSettings );
+ }
+}
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
new file mode 100644
index 000000000000..5165acb84e8a
--- /dev/null
+++ b/vcl/source/control/tabctrl.cxx
@@ -0,0 +1,1772 @@
+/*************************************************************************
+ *
+ * $RCSfile: tabctrl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:36 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_TABCTRL_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_APP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_ACCESS_HXX
+#include <access.hxx>
+#endif
+#ifndef _SV_MENU_HXX
+#include <menu.hxx>
+#endif
+#ifndef _SV_BUTTON_HXX
+#include <button.hxx>
+#endif
+#ifndef _SV_TABPAGE_HXX
+#include <tabpage.hxx>
+#endif
+#ifndef _SV_TABCTRL_HXX
+#include <tabctrl.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+struct ImplTabCtrlData
+{
+ PushButton* mpLeftBtn;
+ PushButton* mpRightBtn;
+};
+
+// -----------------------------------------------------------------------
+
+struct ImplTabItem
+{
+ USHORT mnId;
+ USHORT mnTabPageResId;
+ TabPage* mpTabPage;
+ String maText;
+ String maFormatText;
+ String maHelpText;
+ ULONG mnHelpId;
+ Rectangle maRect;
+ USHORT mnLine;
+ BOOL mbFullVisible;
+};
+
+DECLARE_LIST( ImplTabItemList, ImplTabItem* );
+
+// -----------------------------------------------------------------------
+
+#define TABCOLORCOUNT 10
+
+static ColorData aImplTabColorAry[TABCOLORCOUNT] =
+{
+ RGB_COLORDATA( 80, 216, 248 ),
+ RGB_COLORDATA( 128, 216, 168 ),
+ RGB_COLORDATA( 128, 144, 248 ),
+ RGB_COLORDATA( 208, 180, 168 ),
+ RGB_COLORDATA( 248, 252, 168 ),
+ RGB_COLORDATA( 168, 144, 168 ),
+ RGB_COLORDATA( 248, 144, 80 ),
+ RGB_COLORDATA( 248, 216, 80 ),
+ RGB_COLORDATA( 248, 180, 168 ),
+ RGB_COLORDATA( 248, 216, 168 )
+};
+
+// -----------------------------------------------------------------------
+
+#define TAB_OFFSET 3
+#define TAB_TABOFFSET_X 3
+#define TAB_TABOFFSET_Y 3
+#define TAB_BORDER_LEFT 1
+#define TAB_BORDER_TOP 1
+#define TAB_BORDER_RIGHT 2
+#define TAB_BORDER_BOTTOM 2
+
+// Fuer die Ermittlung von den Tab-Positionen
+#define TAB_PAGERECT 0xFFFF
+
+// =======================================================================
+
+void TabControl::ImplInit( Window* pParent, WinBits nStyle )
+{
+ if ( !(nStyle & WB_NOTABSTOP) )
+ nStyle |= WB_TABSTOP;
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+ if ( !(nStyle & WB_NODIALOGCONTROL) )
+ nStyle |= WB_DIALOGCONTROL;
+
+ Control::ImplInit( pParent, nStyle, NULL );
+
+ mpItemList = new ImplTabItemList( 8, 8 );
+ mpTabCtrlData = NULL;
+ mnLastWidth = 0;
+ mnLastHeight = 0;
+ mnBtnSize = 0;
+ mnMaxPageWidth = 0;
+ mnActPageId = 0;
+ mnCurPageId = 0;
+ mnFirstPagePos = 0;
+ mnLastFirstPagePos = 0;
+ mbFormat = TRUE;
+ mbRestoreHelpId = FALSE;
+ mbRestoreUnqId = FALSE;
+ mbSingleLine = FALSE;
+ mbScroll = FALSE;
+ mbColored = FALSE;
+
+ if ( GetSettings().GetStyleSettings().GetTabControlStyle() & STYLE_TABCONTROL_SINGLELINE )
+ mbSingleLine = TRUE;
+
+ if ( mbSingleLine )
+ {
+ mpTabCtrlData = new ImplTabCtrlData;
+ mpTabCtrlData->mpLeftBtn = NULL;
+ mpTabCtrlData->mpRightBtn = NULL;
+ }
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetAppFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetButtonTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Window* pParent = GetParent();
+ if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+ }
+
+ // Sollen TabReiter farbig dargestellt werden
+ mbColored = (rStyleSettings.GetTabControlStyle() & STYLE_TABCONTROL_COLOR) != 0;
+ ImplScrollBtnsColor();
+}
+
+// -----------------------------------------------------------------------
+
+TabControl::TabControl( Window* pParent, WinBits nStyle ) :
+ Control( WINDOW_TABCONTROL )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+TabControl::TabControl( Window* pParent, const ResId& rResId ) :
+ Control( WINDOW_TABCONTROL )
+{
+ rResId.SetRT( RSC_TABCONTROL );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplLoadRes( const ResId& rResId )
+{
+ Control::ImplLoadRes( rResId );
+
+ USHORT nObjMask = ReadShortRes();
+
+ if ( nObjMask & RSC_TABCONTROL_ITEMLIST )
+ {
+ USHORT nEle = ReadShortRes();
+
+ // Item hinzufuegen
+ for( USHORT i = 0; i < nEle; i++ )
+ {
+ InsertPage( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+TabControl::~TabControl()
+{
+ // Alle Items loeschen
+ ImplTabItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Itemlist loeschen
+ delete mpItemList;
+
+ // TabCtrl-Daten loeschen
+ if ( mpTabCtrlData )
+ {
+ if ( mpTabCtrlData->mpLeftBtn )
+ delete mpTabCtrlData->mpLeftBtn;
+ if ( mpTabCtrlData->mpRightBtn )
+ delete mpTabCtrlData->mpRightBtn;
+ delete mpTabCtrlData;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ImplTabItem* TabControl::ImplGetItem( USHORT nId ) const
+{
+ ImplTabItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nId )
+ return pItem;
+
+ pItem = mpItemList->Next();
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplScrollBtnsColor()
+{
+ if ( mpTabCtrlData && mpTabCtrlData->mpLeftBtn )
+ {
+ if ( mbColored )
+ {
+ Color aScrollBtnColor( COL_LIGHTBLUE );
+ mpTabCtrlData->mpLeftBtn->SetControlForeground( aScrollBtnColor );
+ mpTabCtrlData->mpRightBtn->SetControlForeground( aScrollBtnColor );
+ }
+ else
+ {
+ mpTabCtrlData->mpLeftBtn->SetControlForeground();
+ mpTabCtrlData->mpRightBtn->SetControlForeground();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplSetScrollBtnsState()
+{
+ if ( mbScroll )
+ {
+ mpTabCtrlData->mpLeftBtn->Enable( mnFirstPagePos != 0 );
+ mpTabCtrlData->mpRightBtn->Enable( mnFirstPagePos < mnLastFirstPagePos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplPosScrollBtns()
+{
+ if ( mbScroll )
+ {
+ if ( !mpTabCtrlData->mpLeftBtn )
+ {
+ mpTabCtrlData->mpLeftBtn = new PushButton( this, WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOPOINTERFOCUS | WB_REPEAT );
+ mpTabCtrlData->mpLeftBtn->SetSymbol( SYMBOL_PREV );
+ mpTabCtrlData->mpLeftBtn->SetClickHdl( LINK( this, TabControl, ImplScrollBtnHdl ) );
+ }
+ if ( !mpTabCtrlData->mpRightBtn )
+ {
+ mpTabCtrlData->mpRightBtn = new PushButton( this, WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOPOINTERFOCUS | WB_REPEAT );
+ mpTabCtrlData->mpRightBtn->SetSymbol( SYMBOL_NEXT );
+ mpTabCtrlData->mpRightBtn->SetClickHdl( LINK( this, TabControl, ImplScrollBtnHdl ) );
+ }
+
+ Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
+ aRect.Left() -= TAB_OFFSET;
+ aRect.Top() -= TAB_OFFSET;
+ aRect.Right() += TAB_OFFSET;
+ aRect.Bottom() += TAB_OFFSET;
+ long nX = aRect.Right()-mnBtnSize+1;
+ long nY = aRect.Top()-mnBtnSize;
+ mpTabCtrlData->mpRightBtn->SetPosSizePixel( nX, nY, mnBtnSize, mnBtnSize );
+ nX -= mnBtnSize;
+ mpTabCtrlData->mpLeftBtn->SetPosSizePixel( nX, nY, mnBtnSize, mnBtnSize );
+ ImplScrollBtnsColor();
+ ImplSetScrollBtnsState();
+ mpTabCtrlData->mpLeftBtn->Show();
+ mpTabCtrlData->mpRightBtn->Show();
+ }
+ else
+ {
+ if ( mpTabCtrlData )
+ {
+ if ( mpTabCtrlData->mpLeftBtn )
+ mpTabCtrlData->mpLeftBtn->Hide();
+ if ( mpTabCtrlData->mpRightBtn )
+ mpTabCtrlData->mpRightBtn->Hide();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size TabControl::ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth ) const
+{
+ pItem->maFormatText = pItem->maText;
+ Size aSize( GetCtrlTextWidth( pItem->maFormatText ), GetTextHeight() );
+ aSize.Width() += TAB_TABOFFSET_X*2;
+ aSize.Height() += TAB_TABOFFSET_Y*2;
+
+ // Evt. den Text kuerzen
+ if ( aSize.Width()+4 >= nMaxWidth )
+ {
+ XubString aAppendStr( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
+ pItem->maFormatText += aAppendStr;
+ do
+ {
+ pItem->maFormatText.Erase( pItem->maFormatText.Len()-aAppendStr.Len()-1, 1 );
+ aSize.Width() = GetCtrlTextWidth( pItem->maFormatText );
+ aSize.Width() += TAB_TABOFFSET_X*2;
+ }
+ while ( (aSize.Width()+4 >= nMaxWidth) && (pItem->maFormatText.Len() > aAppendStr.Len()) );
+ if ( aSize.Width()+4 >= nMaxWidth )
+ {
+ pItem->maFormatText.Assign( '.' );
+ aSize.Width() = 1;
+ }
+ }
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle TabControl::ImplGetTabRect( USHORT nPos, long nWidth, long nHeight )
+{
+ Size aWinSize = Control::GetOutputSizePixel();
+ if ( nWidth == -1 )
+ nWidth = aWinSize.Width();
+ if ( nHeight == -1 )
+ nHeight = aWinSize.Height();
+
+ if ( !mpItemList->Count() )
+ {
+ return Rectangle( Point( TAB_OFFSET, TAB_OFFSET ),
+ Size( nWidth-TAB_OFFSET*2, nHeight-TAB_OFFSET*2 ) );
+ }
+
+ if ( nPos == TAB_PAGERECT )
+ {
+ USHORT nLastPos;
+ if ( mbSingleLine )
+ nLastPos = mnFirstPagePos;
+ else
+ {
+ if ( mnCurPageId )
+ nLastPos = GetPagePos( mnCurPageId );
+ else
+ nLastPos = 0;
+ }
+ Rectangle aRect = ImplGetTabRect( nLastPos, nWidth, nHeight );
+ aRect = Rectangle( Point( TAB_OFFSET, aRect.Bottom()+TAB_OFFSET ),
+ Size( nWidth-TAB_OFFSET*2,
+ nHeight-aRect.Bottom()-TAB_OFFSET*2 ) );
+ return aRect;
+ }
+
+ nWidth -= 1;
+
+ if ( (nWidth <= 0) || (nHeight <= 0) )
+ return Rectangle();
+
+ Font aFont = GetFont();
+ FontWeight eWeight = aFont.GetWeight();
+ if ( eWeight != WEIGHT_BOLD )
+ aFont.SetWeight( WEIGHT_BOLD );
+ if ( !aFont.IsTransparent() )
+ aFont.SetTransparent( TRUE );
+
+ if ( mbFormat || (mnLastWidth != nWidth) || (mnLastHeight != nHeight) )
+ {
+ if ( eWeight != WEIGHT_BOLD )
+ SetFont( aFont );
+
+ ImplTabItem* pItem;
+ Size aSize;
+ long nX = 2;
+ long nY = 2;
+ long nMaxWidth = nWidth;
+ USHORT nPos = 0;
+
+ if ( (mnMaxPageWidth > 0) && (mnMaxPageWidth < nMaxWidth) )
+ nMaxWidth = mnMaxPageWidth;
+
+ mbScroll = FALSE;
+ if ( mbSingleLine )
+ {
+ // Zuerst ermitteln wir, ob wir scrollen muessen
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ aSize = ImplGetItemSize( pItem, nMaxWidth );
+ pItem->maRect = Rectangle( Point( nX, nY ), aSize );
+ pItem->mnLine = 1;
+ pItem->mbFullVisible = TRUE;
+ nX += aSize.Width();
+
+ if ( (nX > nWidth-2) && (nWidth > 4) )
+ mbScroll = TRUE;
+
+ pItem = mpItemList->Next();
+ }
+
+ // Wenn wir Scrollen muessen, dann muessen die Reiter
+ // entsprechend angeordnet werden
+ if ( mbScroll )
+ {
+ // Zuerst ermitteln wir den letzten TabReiter, bei dem
+ // die restlichen noch sichtbar bleiben und passen
+ // gegebenenfalls den ersten sichtbaren Writer an
+ mnBtnSize = GetTextHeight()+(TAB_TABOFFSET_Y*2);
+ long nMaxWidth = nWidth-(mnBtnSize*2);
+ long nTempWidth = 0;
+ USHORT nPageCount = GetPageCount();
+ mnLastFirstPagePos = nPageCount;
+ pItem = mpItemList->Last();
+ while ( pItem )
+ {
+ nTempWidth += pItem->maRect.GetSize().Width();
+ if ( nTempWidth > nMaxWidth )
+ break;
+
+ mnLastFirstPagePos--;
+ pItem = mpItemList->Prev();
+ }
+ if ( mnLastFirstPagePos > nPageCount-1 )
+ mnLastFirstPagePos = nPageCount-1;
+ if ( mnFirstPagePos > mnLastFirstPagePos )
+ mnFirstPagePos = mnLastFirstPagePos;
+
+ // Jetzt die TabReiter anordnen und die Reiter ausblenden,
+ // die nicht zu sehen sind
+ nPos = 0;
+ nX = 2;
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( (nPos < mnFirstPagePos) ||
+ ((nX > nWidth-2) && (nWidth > 4)) )
+ {
+ pItem->mbFullVisible = FALSE;
+ pItem->maRect.SetEmpty();
+ }
+ else
+ {
+ aSize = pItem->maRect.GetSize();
+ pItem->maRect = Rectangle( Point( nX, nY ), aSize );
+ nX += aSize.Width();
+ }
+
+ if ( nX > nMaxWidth )
+ pItem->mbFullVisible = FALSE;
+
+ pItem = mpItemList->Next();
+ nPos++;
+ }
+ }
+ else
+ mnFirstPagePos = 0;
+ }
+ else
+ {
+ USHORT nLines = 0;
+ USHORT nCurLine = 0;
+ long nLineWidthAry[100];
+ USHORT nLinePosAry[100];
+
+ nLineWidthAry[0] = 0;
+ nLinePosAry[0] = 0;
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ aSize = ImplGetItemSize( pItem, nMaxWidth );
+
+ if ( ((nX+aSize.Width()) > nWidth-2) && (nWidth > 4) )
+ {
+ if ( nLines == 99 )
+ break;
+
+ nX = 2;
+ nY += aSize.Height();
+ nLines++;
+ nLineWidthAry[nLines] = 0;
+ nLinePosAry[nLines] = nPos;
+ }
+
+ pItem->maRect = Rectangle( Point( nX, nY ), aSize );
+ pItem->mnLine = nLines;
+ pItem->mbFullVisible = TRUE;
+
+ nLineWidthAry[nLines] += aSize.Width();
+ nX += aSize.Width();
+
+ if ( pItem->mnId == mnCurPageId )
+ nCurLine = nLines;
+
+ pItem = mpItemList->Next();
+ nPos++;
+ }
+
+ if ( nLines )
+ {
+ long nDX;
+ long nModDX;
+ long nIDX;
+ USHORT i;
+ USHORT n;
+ long nLineHeightAry[100];
+ long nIH = mpItemList->GetObject( 0 )->maRect.Bottom()-2;
+
+ i = 0;
+ while ( i < nLines+1 )
+ {
+ if ( i <= nCurLine )
+ nLineHeightAry[i] = nIH*(nLines-(nCurLine-i));
+ else
+ nLineHeightAry[i] = nIH*(i-nCurLine-1);
+ i++;
+ }
+
+ i = 0;
+ n = 0;
+ nLinePosAry[nLines+1] = (USHORT)mpItemList->Count();
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( i == nLinePosAry[n] )
+ {
+ if ( n == nLines+1 )
+ break;
+
+ nIDX = 0;
+ nDX = (nWidth-2-nLineWidthAry[n]) / (nLinePosAry[n+1]-i);
+ nModDX = (nWidth-2-nLineWidthAry[n]) % (nLinePosAry[n+1]-i);
+ n++;
+ }
+
+ pItem->maRect.Left() += nIDX;
+ pItem->maRect.Right() += nIDX+nDX;
+ pItem->maRect.Top() = nLineHeightAry[n-1];
+ pItem->maRect.Bottom() = nLineHeightAry[n-1]+nIH;
+ nIDX += nDX;
+
+ if ( nModDX )
+ {
+ nIDX++;
+ pItem->maRect.Right()++;
+ nModDX--;
+ }
+
+ pItem = mpItemList->Next();
+ i++;
+ }
+ }
+ }
+
+ mnLastWidth = nWidth;
+ mnLastHeight = nHeight;
+ mbFormat = FALSE;
+
+ ImplPosScrollBtns();
+ }
+
+ return mpItemList->GetObject( nPos )->maRect;
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplChangeTabPage( USHORT nId, USHORT nOldId )
+{
+ ImplTabItem* pOldItem = ImplGetItem( nOldId );
+ ImplTabItem* pItem = ImplGetItem( nId );
+ TabPage* pOldPage = (pOldItem) ? pOldItem->mpTabPage : NULL;
+ TabPage* pPage = (pItem) ? pItem->mpTabPage : NULL;
+ Window* pCtrlParent = GetParent();
+
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ USHORT nPos = GetPagePos( nId );
+ Rectangle aRect = ImplGetTabRect( nPos );
+
+ if ( !pOldItem || (pOldItem->mnLine != pItem->mnLine) )
+ {
+ aRect.Left() = 0;
+ aRect.Top() = 0;
+ aRect.Right() = Control::GetOutputSizePixel().Width();
+ }
+ else
+ {
+ aRect.Left() -= 3;
+ aRect.Top() -= 2;
+ aRect.Right() += 3;
+ Invalidate( aRect );
+ nPos = GetPagePos( nOldId );
+ aRect = ImplGetTabRect( nPos );
+ aRect.Left() -= 3;
+ aRect.Top() -= 2;
+ aRect.Right() += 3;
+ }
+ Invalidate( aRect );
+ }
+
+ if ( pOldPage == pPage )
+ return;
+
+ Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
+
+ if ( pOldPage )
+ {
+ if ( mbRestoreHelpId )
+ pCtrlParent->SetHelpId( 0 );
+ if ( mbRestoreUnqId )
+ pCtrlParent->SetUniqueId( 0 );
+ pOldPage->DeactivatePage();
+ }
+
+ if ( pPage )
+ {
+ pPage->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() );
+
+ // Hier Page aktivieren, damit die Controls entsprechend umgeschaltet
+ // werden koennen und HilfeId gegebenenfalls beim Parent umsetzen
+ if ( !GetHelpId() )
+ {
+ mbRestoreHelpId = TRUE;
+ pCtrlParent->SetHelpId( pPage->GetHelpId() );
+ }
+ if ( !pCtrlParent->GetUniqueId() )
+ {
+ mbRestoreUnqId = TRUE;
+ pCtrlParent->SetUniqueId( pPage->GetUniqueId() );
+ }
+
+ pPage->ActivatePage();
+
+ if ( pOldPage && pOldPage->HasChildPathFocus() )
+ {
+ USHORT n = 0;
+ Window* pFirstChild = pPage->ImplGetDlgWindow( n, DLGWINDOW_FIRST );
+ if ( pFirstChild )
+ pFirstChild->ImplControlFocus( GETFOCUS_INIT );
+ else
+ GrabFocus();
+ }
+
+ pPage->Show();
+
+ if( Application::GetAccessHdlCount() && pPage->IsReallyVisible() )
+ Application::AccessNotify( AccessNotification( ACCESS_EVENT_DLGCONTROLS, GetParent() ) );
+ }
+
+ if ( pOldPage )
+ pOldPage->Hide();
+
+ Invalidate( aRect );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabControl::ImplPosCurTabPage()
+{
+ // Aktuelle TabPage resizen/positionieren
+ ImplTabItem* pItem = ImplGetItem( GetCurPageId() );
+ if ( pItem && pItem->mpTabPage )
+ {
+ Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
+ pItem->mpTabPage->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplActivateTabPage( BOOL bNext )
+{
+ USHORT nCurPos = GetPagePos( GetCurPageId() );
+
+ if ( bNext )
+ nCurPos = (nCurPos + 1) % GetPageCount();
+ else
+ {
+ if ( !nCurPos )
+ nCurPos = GetPageCount()-1;
+ else
+ nCurPos--;
+ }
+
+ SelectTabPage( GetPageId( nCurPos ) );
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplSetFirstPagePos( USHORT nPagePos )
+{
+ if ( !mbSingleLine )
+ return;
+
+ if ( mbFormat )
+ mnFirstPagePos = nPagePos;
+ else
+ {
+ if ( nPagePos > mnLastFirstPagePos )
+ nPagePos = mnLastFirstPagePos;
+
+ if ( nPagePos != mnFirstPagePos )
+ {
+ // Neu auszugebene Rechteck berechnen
+ Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
+ aRect.Bottom() = aRect.Top();
+ aRect.Left() = 0;
+ aRect.Top() = 0;
+ aRect.Right() = Control::GetOutputSizePixel().Width();
+
+ mbFormat = TRUE;
+ mnFirstPagePos = nPagePos;
+ Invalidate( aRect, INVALIDATE_NOCHILDREN );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplShowFocus()
+{
+ if ( !GetPageCount() )
+ return;
+
+ USHORT nCurPos = GetPagePos( mnCurPageId );
+ Rectangle aRect = ImplGetTabRect( nCurPos );
+ ImplTabItem* pItem = mpItemList->GetObject( nCurPos );
+ Size aTabSize = aRect.GetSize();
+ long nTextHeight = GetTextHeight();
+ long nTextWidth = GetCtrlTextWidth( pItem->maFormatText );
+ USHORT nOff;
+
+ if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_MONO) )
+ nOff = 1;
+ else
+ nOff = 0;
+
+ aRect.Left() = aRect.Left()+((aTabSize.Width()-nTextWidth)/2)-nOff-1-1;
+ aRect.Top() = aRect.Top()+((aTabSize.Height()-nTextHeight)/2)-1-1;
+ aRect.Right() = aRect.Left()+nTextWidth+2;
+ aRect.Bottom() = aRect.Top()+nTextHeight+2;
+ ShowFocus( aRect );
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect )
+{
+ if ( pItem->maRect.IsEmpty() )
+ return;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aRect = pItem->maRect;
+ long nLeftBottom = aRect.Bottom();
+ long nRightBottom = aRect.Bottom();
+ BOOL bLeftBorder = TRUE;
+ BOOL bRightBorder = TRUE;
+ USHORT nOff;
+
+ USHORT nOff2 = 0;
+ USHORT nOff3 = 0;
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ nOff = 1;
+ else
+ nOff = 0;
+
+ // Wenn wir die aktuelle Page sind, muessen wir etwas mehr zeichnen
+ if ( pItem->mnId == mnCurPageId )
+ {
+ nOff2 = 2;
+ nOff3 = 1;
+ }
+ else
+ {
+ Point aLeftTestPos = aRect.BottomLeft();
+ Point aRightTestPos = aRect.BottomRight();
+ if ( aLeftTestPos.Y() == rCurRect.Bottom() )
+ {
+ aLeftTestPos.X() -= 2;
+ if ( rCurRect.IsInside( aLeftTestPos ) )
+ bLeftBorder = FALSE;
+ aRightTestPos.X() += 2;
+ if ( rCurRect.IsInside( aRightTestPos ) )
+ bRightBorder = FALSE;
+ }
+ else
+ {
+ if ( rCurRect.IsInside( aLeftTestPos ) )
+ nLeftBottom -= 2;
+ if ( rCurRect.IsInside( aRightTestPos ) )
+ nRightBottom -= 2;
+ }
+ }
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ if ( mbColored )
+ {
+ USHORT nPos = (USHORT)mpItemList->GetPos( pItem );
+ Color aOldFillColor = GetFillColor();
+ SetLineColor();
+ SetFillColor( aImplTabColorAry[nPos%TABCOLORCOUNT] );
+ Rectangle aColorRect;
+ aColorRect.Left() = aRect.Left()-nOff2+1;
+ aColorRect.Top() = aRect.Top()-nOff2+1;
+ aColorRect.Right() = aRect.Right()+nOff2-3;
+ aColorRect.Bottom() = nLeftBottom;
+ if ( pItem->mnId != mnCurPageId )
+ aColorRect.Bottom()--;
+ DrawRect( aColorRect );
+ SetFillColor( aOldFillColor );
+ }
+
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawPixel( Point( aRect.Left()+1-nOff2, aRect.Top()+1-nOff2 ) );
+ if ( bLeftBorder )
+ {
+ DrawLine( Point( aRect.Left()-nOff2, aRect.Top()+2-nOff2 ),
+ Point( aRect.Left()-nOff2, nLeftBottom-1 ) );
+ }
+ DrawLine( Point( aRect.Left()+2-nOff2, aRect.Top()-nOff2 ),
+ Point( aRect.Right()+nOff2-3, aRect.Top()-nOff2 ) );
+
+ if ( bRightBorder )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( aRect.Right()+nOff2-2, aRect.Top()+1-nOff2 ),
+ Point( aRect.Right()+nOff2-2, nRightBottom-1 ) );
+
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point( aRect.Right()+nOff2-1, aRect.Top()+3-nOff2 ),
+ Point( aRect.Right()+nOff2-1, nRightBottom-1 ) );
+ }
+ }
+ else
+ {
+ SetLineColor( Color( COL_BLACK ) );
+ DrawPixel( Point( aRect.Left()+1-nOff2, aRect.Top()+1-nOff2 ) );
+ DrawPixel( Point( aRect.Right()+nOff2-2, aRect.Top()+1-nOff2 ) );
+ if ( bLeftBorder )
+ {
+ DrawLine( Point( aRect.Left()-nOff2, aRect.Top()+2-nOff2 ),
+ Point( aRect.Left()-nOff2, nLeftBottom-1 ) );
+ }
+ DrawLine( Point( aRect.Left()+2-nOff2, aRect.Top()-nOff2 ),
+ Point( aRect.Right()-3, aRect.Top()-nOff2 ) );
+ if ( bRightBorder )
+ {
+ DrawLine( Point( aRect.Right()+nOff2-1, aRect.Top()+2-nOff2 ),
+ Point( aRect.Right()+nOff2-1, nRightBottom-1 ) );
+ }
+ }
+
+ Size aTabSize = aRect.GetSize();
+ long nTextHeight = GetTextHeight();
+ long nTextWidth = GetCtrlTextWidth( pItem->maFormatText );
+ DrawCtrlText( Point( aRect.Left()+((aTabSize.Width()-nTextWidth)/2)-nOff-nOff3,
+ aRect.Top()+((aTabSize.Height()-nTextHeight)/2)-nOff3 ),
+ pItem->maFormatText );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( TabControl, ImplScrollBtnHdl, PushButton*, pBtn )
+{
+ if ( pBtn == mpTabCtrlData->mpRightBtn )
+ ImplSetFirstPagePos( mnFirstPagePos+1 );
+ else
+ ImplSetFirstPagePos( mnFirstPagePos-1 );
+ ImplSetScrollBtnsState();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ SelectTabPage( GetPageId( rMEvt.GetPosPixel() ) );
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::KeyInput( const KeyEvent& rKEvt )
+{
+ if ( GetPageCount() > 1 )
+ {
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( (nKeyCode == KEY_LEFT) || (nKeyCode == KEY_RIGHT) )
+ {
+ BOOL bNext = (nKeyCode == KEY_RIGHT);
+ ImplActivateTabPage( bNext );
+ }
+ }
+
+ Control::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::Paint( const Rectangle& rRect )
+{
+ HideFocus();
+
+ // Hier wird gegebenenfalls auch neu formatiert
+ Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
+
+ // Fonts entsprechend setzen
+ Font aFont( GetFont() );
+ Font aLightFont = aFont;
+ aFont.SetTransparent( TRUE );
+ aFont.SetWeight( WEIGHT_BOLD );
+ aLightFont.SetTransparent( TRUE );
+ aLightFont.SetWeight( WEIGHT_LIGHT );
+
+ // Aktuelles Item ermitteln
+ ImplTabItem* pPrevCurItem = NULL;
+ ImplTabItem* pCurItem = NULL;
+ ImplTabItem* pItem = mpItemList->First();
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == mnCurPageId )
+ {
+ pCurItem = pItem;
+ break;
+ }
+
+ pItem = mpItemList->Next();
+ }
+
+ // Border um TabPage zeichnen
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aCurRect;
+ long nTopOff = 1;
+ aRect.Left() -= TAB_OFFSET;
+ aRect.Top() -= TAB_OFFSET;
+ aRect.Right() += TAB_OFFSET;
+ aRect.Bottom() += TAB_OFFSET;
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ SetLineColor( rStyleSettings.GetLightColor() );
+ else
+ SetLineColor( Color( COL_BLACK ) );
+ if ( pCurItem && !pCurItem->maRect.IsEmpty() )
+ {
+ aCurRect = pCurItem->maRect;
+ DrawLine( aRect.TopLeft(), Point( aCurRect.Left()-2, aRect.Top() ) );
+ if ( aCurRect.Right()+1 < aRect.Right() )
+ DrawLine( Point( aCurRect.Right(), aRect.Top() ), aRect.TopRight() );
+ else
+ nTopOff = 0;
+ }
+ else
+ DrawLine( aRect.TopLeft(), aRect.TopRight() );
+ DrawLine( aRect.TopLeft(), aRect.BottomLeft() );
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( 1, aRect.Bottom()-1 ),
+ Point( aRect.Right()-1, aRect.Bottom()-1 ) );
+ DrawLine( Point( aRect.Right()-1, aRect.Top()+nTopOff ),
+ Point( aRect.Right()-1, aRect.Bottom()-1 ) );
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point( 0, aRect.Bottom() ),
+ Point( aRect.Right(), aRect.Bottom() ) );
+ DrawLine( Point( aRect.Right(), aRect.Top()+nTopOff ),
+ Point( aRect.Right(), aRect.Bottom() ) );
+ }
+ else
+ {
+ DrawLine( aRect.TopRight(), aRect.BottomRight() );
+ DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
+ }
+
+ // Alle Items bis auf das aktuelle Zeichnen (nicht fett)
+ SetFont( aLightFont );
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem != pCurItem )
+ ImplDrawItem( pItem, aCurRect );
+ pItem = mpItemList->Next();
+ }
+
+ // aktuelles Item zeichnen wir fett
+ SetFont( aFont );
+ if ( pCurItem )
+ ImplDrawItem( pCurItem, aCurRect );
+
+ if ( HasFocus() )
+ ImplShowFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::Resize()
+{
+ if ( !IsReallyShown() )
+ return;
+
+ mbFormat = TRUE;
+
+ // Aktuelle TabPage resizen/positionieren
+ BOOL bTabPage = ImplPosCurTabPage();
+ // Feststellen, was invalidiert werden muss
+ Size aNewSize = Control::GetOutputSizePixel();
+ long nWidthTest = aNewSize.Width();
+ BOOL bSmallInvalidate = TRUE;
+ BOOL bWidthChanged = (nWidthTest != mnLastWidth);
+ if ( mbScroll )
+ bSmallInvalidate = FALSE;
+ else if ( bWidthChanged )
+ {
+ if ( mnLastWidth < nWidthTest )
+ nWidthTest = mnLastWidth;
+
+ ImplTabItem* pItem;
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( !pItem->mbFullVisible ||
+ (pItem->maRect.Right()-2 >= nWidthTest) )
+ {
+ bSmallInvalidate = FALSE;
+ break;
+ }
+
+ pItem = mpItemList->Next();
+ }
+ }
+
+ if ( bSmallInvalidate )
+ {
+ Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
+ aRect.Left() -= TAB_OFFSET+TAB_BORDER_LEFT;
+ aRect.Top() -= TAB_OFFSET+TAB_BORDER_TOP;
+ aRect.Right() += TAB_OFFSET+TAB_BORDER_RIGHT;
+ aRect.Bottom() += TAB_OFFSET+TAB_BORDER_BOTTOM;
+ if ( bTabPage )
+ Invalidate( aRect, INVALIDATE_NOCHILDREN );
+ else
+ Invalidate( aRect );
+ }
+ else
+ {
+ if ( bTabPage )
+ Invalidate( INVALIDATE_NOCHILDREN );
+ else
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::GetFocus()
+{
+ ImplShowFocus();
+ SetInputContext( InputContext( GetFont() ) );
+ Control::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::LoseFocus()
+{
+ HideFocus();
+ Control::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::RequestHelp( const HelpEvent& rHEvt )
+{
+ USHORT nItemId = GetPageId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+
+ if ( nItemId )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ {
+ XubString aStr = GetHelpText( nItemId );
+ if ( aStr.Len() )
+ {
+ Rectangle aItemRect = ImplGetTabRect( GetPagePos( nItemId ) );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ return;
+ }
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
+ {
+ ULONG nHelpId = GetHelpId( nItemId );
+ if ( nHelpId )
+ {
+ // Wenn eine Hilfe existiert, dann ausloesen
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nHelpId );
+ return;
+ }
+ }
+
+ // Bei Quick- oder Ballloon-Help zeigen wir den Text an,
+ // wenn dieser abgeschnitten ist
+ if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
+ {
+ ImplTabItem* pItem = ImplGetItem( nItemId );
+ const XubString& rStr = pItem->maText;
+ if ( rStr != pItem->maFormatText )
+ {
+ Rectangle aItemRect = ImplGetTabRect( GetPagePos( nItemId ) );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ if ( rStr.Len() )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, rStr );
+ else
+ Help::ShowQuickHelp( this, aItemRect, rStr );
+ return;
+ }
+ }
+ }
+ }
+
+ Control::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::Command( const CommandEvent& rCEvt )
+{
+ if ( (rCEvt.GetCommand() == COMMAND_CONTEXTMENU) && (GetPageCount() > 1) )
+ {
+ Point aMenuPos;
+ BOOL bMenu;
+ if ( rCEvt.IsMouseEvent() )
+ {
+ aMenuPos = rCEvt.GetMousePosPixel();
+ bMenu = GetPageId( aMenuPos ) != 0;
+ }
+ else
+ {
+ aMenuPos = ImplGetTabRect( GetPagePos( mnCurPageId ) ).Center();
+ bMenu = TRUE;
+ }
+
+ if ( bMenu )
+ {
+ PopupMenu aMenu;
+ ImplTabItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ aMenu.InsertItem( pItem->mnId, pItem->maText, MIB_CHECKABLE | MIB_RADIOCHECK );
+ if ( pItem->mnId == mnCurPageId )
+ aMenu.CheckItem( pItem->mnId );
+ aMenu.SetHelpId( pItem->mnId, pItem->mnHelpId );
+ pItem = mpItemList->Next();
+ }
+
+ USHORT nId = aMenu.Execute( this, aMenuPos );
+ if ( nId && (nId != mnCurPageId) )
+ SelectTabPage( nId );
+ return;
+ }
+ }
+
+ Control::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ImplPosCurTabPage();
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long TabControl::Notify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) && (GetPageCount() > 1) )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( aKeyCode.IsMod1() )
+ {
+ if ( aKeyCode.IsShift() || (nKeyCode == KEY_PAGEUP) )
+ {
+ if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEUP) )
+ {
+ ImplActivateTabPage( FALSE );
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEDOWN) )
+ {
+ ImplActivateTabPage( TRUE );
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return Control::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::ActivatePage()
+{
+ maActivateHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+long TabControl::DeactivatePage()
+{
+ if ( maDeactivateHdl.IsSet() )
+ return maDeactivateHdl.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::SetTabPageSizePixel( const Size& rSize )
+{
+ Size aNewSize( rSize );
+ aNewSize.Width() += TAB_OFFSET*2;
+ Rectangle aRect = ImplGetTabRect( TAB_PAGERECT,
+ aNewSize.Width(), aNewSize.Height() );
+ aNewSize.Height() += aRect.Top()+TAB_OFFSET;
+ Window::SetOutputSizePixel( aNewSize );
+}
+
+// -----------------------------------------------------------------------
+
+Size TabControl::GetTabPageSizePixel() const
+{
+ Rectangle aRect = ((TabControl*)this)->ImplGetTabRect( TAB_PAGERECT );
+ return aRect.GetSize();
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::InsertPage( const ResId& rResId, USHORT nPos )
+{
+ GetRes( rResId.SetRT( RSC_TABCONTROLITEM ) );
+
+ USHORT nObjMask = ReadShortRes();
+ USHORT nItemId = 1;
+
+ // ID
+ if ( nObjMask & RSC_TABCONTROLITEM_ID )
+ nItemId = ReadShortRes();
+
+ // Text
+ XubString aTmpStr;
+ if( nObjMask & RSC_TABCONTROLITEM_TEXT )
+ aTmpStr = ReadStringRes();
+ InsertPage( nItemId, aTmpStr, nPos );
+
+ // PageResID
+ if ( nObjMask & RSC_TABCONTROLITEM_PAGERESID )
+ {
+ ImplTabItem* pItem = mpItemList->GetObject( GetPagePos( nItemId ) );
+ pItem->mnTabPageResId = ReadShortRes();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::InsertPage( USHORT nPageId, const XubString& rText,
+ USHORT nPos )
+{
+ DBG_ASSERT( nPageId, "TabControl::InsertPage(): PageId == 0" );
+ DBG_ASSERT( GetPagePos( nPageId ) == TAB_PAGE_NOTFOUND,
+ "TabControl::InsertPage(): PageId already exists" );
+
+ // CurPageId gegebenenfalls setzen
+ if ( !mnCurPageId )
+ mnCurPageId = nPageId;
+
+ // PageItem anlegen
+ ImplTabItem* pItem = new ImplTabItem;
+ pItem->mnId = nPageId;
+ pItem->mpTabPage = NULL;
+ pItem->mnTabPageResId = 0;
+ pItem->mnHelpId = 0;
+ pItem->maText = rText;
+ pItem->mbFullVisible = FALSE;
+
+ // In die StarView-Liste eintragen
+ mpItemList->Insert( pItem, nPos );
+
+ mbFormat = TRUE;
+ if ( IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::RemovePage( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ // Existiert Item
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ // Item-Daten loeschen und Windows-Item entfernen
+ ImplTabItem* pItem = mpItemList->Remove( nPos );
+ if ( pItem->mnId == mnCurPageId )
+ mnCurPageId = 0;
+ delete pItem;
+
+ mbFormat = TRUE;
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::Clear()
+{
+ // Alle Items loeschen
+ ImplTabItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Item-Daten loeschen
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Items aus der Liste loeschen
+ mpItemList->Clear();
+ mnCurPageId = 0;
+
+ mbFormat = TRUE;
+ if ( IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabControl::GetPageCount() const
+{
+ return (USHORT)mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabControl::GetPageId( USHORT nPos ) const
+{
+ ImplTabItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem )
+ return pItem->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabControl::GetPagePos( USHORT nPageId ) const
+{
+ ImplTabItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nPageId )
+ return (USHORT)mpItemList->GetCurPos();
+
+ pItem = mpItemList->Next();
+ }
+
+ return TAB_PAGE_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabControl::GetPageId( const Point& rPos ) const
+{
+ USHORT i = 0;
+ while ( i < mpItemList->Count() )
+ {
+ if ( ((TabControl*)this)->ImplGetTabRect( i ).IsInside( rPos ) )
+ return mpItemList->GetObject( i )->mnId;
+ i++;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::SetCurPageId( USHORT nPageId )
+{
+ if ( nPageId == mnCurPageId )
+ {
+ if ( mnActPageId )
+ mnActPageId = nPageId;
+ return;
+ }
+
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+ if ( pItem )
+ {
+ if ( mnActPageId )
+ mnActPageId = nPageId;
+ else
+ {
+ if ( pItem->maRect.IsEmpty() || !pItem->mbFullVisible )
+ SetFirstPageId( nPageId );
+ mbFormat = TRUE;
+ USHORT nOldId = mnCurPageId;
+ mnCurPageId = nPageId;
+ ImplChangeTabPage( nPageId, nOldId );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabControl::GetCurPageId() const
+{
+ if ( mnActPageId )
+ return mnActPageId;
+ else
+ return mnCurPageId;
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::SetFirstPageId( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( (nPos != TAB_PAGE_NOTFOUND) && (nPos != mnFirstPagePos) )
+ ImplSetFirstPagePos( nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::SelectTabPage( USHORT nPageId )
+{
+ if ( nPageId && (nPageId != mnCurPageId) )
+ {
+ if ( DeactivatePage() )
+ {
+ mnActPageId = nPageId;
+ ActivatePage();
+ // Page koennte im Activate-Handler umgeschaltet wurden sein
+ nPageId = mnActPageId;
+ mnActPageId = 0;
+ SetCurPageId( nPageId );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::SetTabPage( USHORT nPageId, TabPage* pTabPage )
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+
+ if ( pItem && (pItem->mpTabPage != pTabPage) )
+ {
+ if ( pTabPage )
+ {
+ DBG_ASSERT( !pTabPage->IsVisible(), "TabControl::SetTabPage() - Page is visible" );
+
+ if ( IsDefaultSize() )
+ SetTabPageSizePixel( pTabPage->GetSizePixel() );
+
+ // Erst hier setzen, damit Resize nicht TabPage umpositioniert
+ pItem->mpTabPage = pTabPage;
+ if ( pItem->mnId == mnCurPageId )
+ ImplChangeTabPage( pItem->mnId, 0 );
+ }
+ else
+ pItem->mpTabPage = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+TabPage* TabControl::GetTabPage( USHORT nPageId ) const
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+
+ if ( pItem )
+ return pItem->mpTabPage;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabControl::GetTabPageResId( USHORT nPageId ) const
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+
+ if ( pItem )
+ return pItem->mnTabPageResId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::SetPageText( USHORT nPageId, const XubString& rText )
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+
+ if ( pItem )
+ {
+ pItem->maText = rText;
+ mbFormat = TRUE;
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString TabControl::GetPageText( USHORT nPageId ) const
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+
+ if ( pItem )
+ return pItem->maText;
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::SetHelpText( USHORT nPageId, const XubString& rText )
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+
+ if ( pItem )
+ pItem->maHelpText = rText;
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& TabControl::GetHelpText( USHORT nPageId ) const
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+
+ if ( pItem )
+ {
+ if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId );
+ }
+
+ return pItem->maHelpText;
+ }
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::SetHelpId( USHORT nPageId, ULONG nHelpId )
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+
+ if ( pItem )
+ pItem->mnHelpId = nHelpId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG TabControl::GetHelpId( USHORT nPageId ) const
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+
+ if ( pItem )
+ return pItem->mnHelpId;
+ else
+ return 0;
+}
diff --git a/vcl/source/gdi/alpha.cxx b/vcl/source/gdi/alpha.cxx
new file mode 100644
index 000000000000..9e00d0044787
--- /dev/null
+++ b/vcl/source/gdi/alpha.cxx
@@ -0,0 +1,353 @@
+/*************************************************************************
+ *
+ * $RCSfile: alpha.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_ALPHA_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_COLOR_HXX
+#include <color.hxx>
+#endif
+#ifndef _SV_ALPHA_HXX
+#include <alpha.hxx>
+#endif
+
+// -------------
+// - AlphaMask -
+// -------------
+
+AlphaMask::AlphaMask()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+AlphaMask::AlphaMask( const Bitmap& rBitmap ) :
+ Bitmap( rBitmap )
+{
+ if( !!rBitmap )
+ Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
+}
+
+// -----------------------------------------------------------------------------
+
+AlphaMask::AlphaMask( const AlphaMask& rAlphaMask ) :
+ Bitmap( rAlphaMask )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+AlphaMask::AlphaMask( const Size& rSizePixel, BYTE* pEraseTransparency ) :
+ Bitmap( rSizePixel, 8, &Bitmap::GetGreyPalette( 256 ) )
+{
+ if( pEraseTransparency )
+ Bitmap::Erase( Color( *pEraseTransparency, *pEraseTransparency, *pEraseTransparency ) );
+}
+
+// -----------------------------------------------------------------------------
+
+AlphaMask::~AlphaMask()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+AlphaMask& AlphaMask::operator=( const Bitmap& rBitmap )
+{
+ *(Bitmap*) this = rBitmap;
+
+ if( !!rBitmap )
+ Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------------
+
+const Bitmap& AlphaMask::ImplGetBitmap() const
+{
+ return( (const Bitmap&) *this );
+}
+
+// -----------------------------------------------------------------------------
+
+void AlphaMask::ImplSetBitmap( const Bitmap& rBitmap )
+{
+ *(Bitmap*) this = rBitmap;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Crop( const Rectangle& rRectPixel )
+{
+ return Bitmap::Crop( rRectPixel );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Expand( ULONG nDX, ULONG nDY, BYTE* pInitTransparency )
+{
+ Color aColor;
+
+ if( pInitTransparency )
+ aColor = Color( *pInitTransparency, *pInitTransparency, *pInitTransparency );
+
+ return Bitmap::Expand( nDX, nDY, pInitTransparency ? &aColor : NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Erase( BYTE cTransparency )
+{
+ return Bitmap::Erase( Color( cTransparency, cTransparency, cTransparency ) );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Invert()
+{
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pAcc && pAcc->GetBitCount() == 8 )
+ {
+ BitmapColor aCol( 0 );
+ const long nWidth = pAcc->Width(), nHeight = pAcc->Height();
+ BYTE* pMap = new BYTE[ 256 ];
+
+ for( long i = 0; i < 256; i++ )
+ pMap[ i ] = ~(BYTE) i;
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aCol.SetIndex( pMap[ pAcc->GetPixel( nY, nX ).GetIndex() ] );
+ pAcc->SetPixel( nY, nX, aCol );
+ }
+ }
+
+ delete[] pMap;
+ bRet = TRUE;
+ }
+
+ if( pAcc )
+ ReleaseAccess( pAcc );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Mirror( ULONG nMirrorFlags )
+{
+ return Bitmap::Mirror( nMirrorFlags );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Scale( const Size& rNewSize, ULONG nScaleFlag )
+{
+ BOOL bRet = Bitmap::Scale( rNewSize, nScaleFlag );
+
+ if( bRet && ( nScaleFlag == BMP_SCALE_INTERPOLATE ) )
+ Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Scale( const double& rScaleX, const double& rScaleY, ULONG nScaleFlag )
+{
+ BOOL bRet = Bitmap::Scale( rScaleX, rScaleY, nScaleFlag );
+
+ if( bRet && ( nScaleFlag == BMP_SCALE_INTERPOLATE ) )
+ Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Rotate( long nAngle10, BYTE cFillTransparency )
+{
+ return Bitmap::Rotate( nAngle10, Color( cFillTransparency, cFillTransparency, cFillTransparency ) );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Replace( const Bitmap& rMask, BYTE cReplaceTransparency )
+{
+ BitmapReadAccess* pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pMaskAcc && pAcc )
+ {
+ const BitmapColor aReplace( cReplaceTransparency );
+ const long nWidth = Min( pMaskAcc->Width(), pAcc->Width() );
+ const long nHeight = Min( pMaskAcc->Height(), pAcc->Height() );
+ const BitmapColor aMaskWhite( pMaskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX = 0L; nX < nWidth; nX++ )
+ if( pMaskAcc->GetPixel( nY, nX ) == aMaskWhite )
+ pAcc->SetPixel( nY, nX, aReplace );
+ }
+
+ ( (Bitmap&) rMask ).ReleaseAccess( pMaskAcc );
+ ReleaseAccess( pAcc );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Replace( BYTE cSearchTransparency, BYTE cReplaceTransparency, ULONG nTol )
+{
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ DBG_ASSERT( !nTol, "AlphaMask::Replace: nTol not used yet" );
+
+ if( pAcc && pAcc->GetBitCount() == 8 )
+ {
+ const long nWidth = pAcc->Width(), nHeight = pAcc->Height();
+
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ Scanline pScan = pAcc->GetScanline( nY );
+
+ for( long nX = 0L; nX < nWidth; nX++, pScan++ )
+ {
+ if( *pScan == cSearchTransparency )
+ *pScan = cReplaceTransparency;
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aReplace( cReplaceTransparency );
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pAcc->GetPixel( nY, nX ).GetIndex() == cSearchTransparency )
+ pAcc->SetPixel( nY, nX, aReplace );
+ }
+ }
+ }
+
+ bRet = TRUE;
+ }
+
+ if( pAcc )
+ ReleaseAccess( pAcc );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AlphaMask::Replace( BYTE* pSearchTransparencies, BYTE* pReplaceTransparencies,
+ ULONG nColorCount, ULONG* pTols )
+{
+ Color* pSearchColors = new Color[ nColorCount ];
+ Color* pReplaceColors = new Color[ nColorCount ];
+ BOOL bRet;
+
+ for( ULONG i = 0; i < nColorCount; i++ )
+ {
+ const BYTE cSearchTransparency = pSearchTransparencies[ i ];
+ const BYTE cReplaceTransparency = pReplaceTransparencies[ i ];
+
+ pSearchColors[ i ] = Color( cSearchTransparency, cSearchTransparency, cSearchTransparency );
+ pReplaceColors[ i ] = Color( cReplaceTransparency, cReplaceTransparency, cReplaceTransparency );
+ }
+
+ bRet = Bitmap::Replace( pSearchColors, pReplaceColors, nColorCount, pTols ) &&
+ Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
+
+ delete[] pSearchColors;
+ delete[] pReplaceColors;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void AlphaMask::ReleaseAccess( BitmapReadAccess* pAccess )
+{
+ if( pAccess )
+ {
+ Bitmap::ReleaseAccess( pAccess );
+ Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
+ }
+}
diff --git a/vcl/source/gdi/animate.cxx b/vcl/source/gdi/animate.cxx
new file mode 100644
index 000000000000..2a1c7e26ad2b
--- /dev/null
+++ b/vcl/source/gdi/animate.cxx
@@ -0,0 +1,992 @@
+/*************************************************************************
+ *
+ * $RCSfile: animate.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_ANIMATE_CXX
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _RTL_CRC_H_
+#include <rtl/crc.h>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_IMPANMVW_HXX
+#include <impanmvw.hxx>
+#endif
+#ifndef _SV_ANIMATE_HXX
+#include <animate.hxx>
+#endif
+
+DBG_NAME( Animation );
+
+// -----------
+// - Defines -
+// -----------
+
+#define MIN_TIMEOUT 2L
+#define INC_TIMEOUT 0L
+
+// -----------
+// - statics -
+// -----------
+
+ULONG Animation::mnAnimCount = 0UL;
+
+// -------------------
+// - AnimationBitmap -
+// -------------------
+
+ULONG AnimationBitmap::GetChecksum() const
+{
+ sal_uInt32 nCrc = aBmpEx.GetChecksum();
+ SVBT32 aBT32;
+
+ LongToSVBT32( aPosPix.X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( aPosPix.Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( aSizePix.Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( aSizePix.Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( (long) nWait, aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( (long) eDisposal, aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( (long) bUserInput, aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ return nCrc;
+}
+
+// -------------
+// - Animation -
+// -------------
+
+Animation::Animation() :
+ mbIsInAnimation ( FALSE ),
+ meCycleMode ( CYCLE_NORMAL ),
+ mnLoopCount ( 0 ),
+ mnLoops ( 0 ),
+ mnPos ( 0 ),
+ mbLoopTerminated ( FALSE ),
+ mbIsWaiting ( FALSE )
+{
+ DBG_CTOR( Animation, NULL );
+ maTimer.SetTimeoutHdl( LINK( this, Animation, ImplTimeoutHdl ) );
+ mpViewList = new List;
+}
+
+// -----------------------------------------------------------------------
+
+Animation::Animation( const Animation& rAnimation ) :
+ maGlobalSize ( rAnimation.maGlobalSize ),
+ maBitmapEx ( rAnimation.maBitmapEx ),
+ meCycleMode ( rAnimation.meCycleMode ),
+ mbIsInAnimation ( FALSE ),
+ mnLoopCount ( rAnimation.mnLoopCount ),
+ mnPos ( rAnimation.mnPos ),
+ mbLoopTerminated ( rAnimation.mbLoopTerminated ),
+ mbIsWaiting ( rAnimation.mbIsWaiting )
+{
+ DBG_CTOR( Animation, NULL );
+
+ for( long i = 0, nCount = rAnimation.maList.Count(); i < nCount; i++ )
+ maList.Insert( new AnimationBitmap( *(AnimationBitmap*) rAnimation.maList.GetObject( i ) ), LIST_APPEND );
+
+ maTimer.SetTimeoutHdl( LINK( this, Animation, ImplTimeoutHdl ) );
+ mpViewList = new List;
+ mnLoops = mbLoopTerminated ? 0 : mnLoopCount;
+}
+
+// -----------------------------------------------------------------------
+
+Animation::~Animation()
+{
+ DBG_DTOR( Animation, NULL );
+
+ if( mbIsInAnimation )
+ Stop();
+
+ for( void* pStepBmp = maList.First(); pStepBmp; pStepBmp = maList.Next() )
+ delete (AnimationBitmap*) pStepBmp;
+
+ for( void* pView = mpViewList->First(); pView; pView = mpViewList->Next() )
+ delete (ImplAnimView*) pView;
+
+ delete mpViewList;
+}
+
+// -----------------------------------------------------------------------
+
+Animation& Animation::operator=( const Animation& rAnimation )
+{
+ Clear();
+
+ for( long i = 0, nCount = rAnimation.maList.Count(); i < nCount; i++ )
+ maList.Insert( new AnimationBitmap( *(AnimationBitmap*) rAnimation.maList.GetObject( i ) ), LIST_APPEND );
+
+ maGlobalSize = rAnimation.maGlobalSize;
+ maBitmapEx = rAnimation.maBitmapEx;
+ meCycleMode = rAnimation.meCycleMode;
+ mnLoopCount = rAnimation.mnLoopCount;
+ mnPos = rAnimation.mnPos;
+ mbLoopTerminated = rAnimation.mbLoopTerminated;
+ mbIsWaiting = rAnimation.mbIsWaiting;
+ mnLoops = mbLoopTerminated ? 0 : mnLoopCount;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::operator==( const Animation& rAnimation ) const
+{
+ const ULONG nCount = maList.Count();
+ BOOL bRet = FALSE;
+
+ if( rAnimation.maList.Count() == nCount &&
+ rAnimation.maBitmapEx == maBitmapEx &&
+ rAnimation.maGlobalSize == maGlobalSize &&
+ rAnimation.meCycleMode == meCycleMode )
+ {
+ bRet = TRUE;
+
+ for( ULONG n = 0; n < nCount; n++ )
+ {
+ if( ( *(AnimationBitmap*) maList.GetObject( n ) ) !=
+ ( *(AnimationBitmap*) rAnimation.maList.GetObject( n ) ) )
+ {
+ bRet = FALSE;
+ break;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Animation::IsEqual( const Animation& rAnimation ) const
+{
+ const ULONG nCount = maList.Count();
+ BOOL bRet = FALSE;
+
+ if( rAnimation.maList.Count() == nCount &&
+ rAnimation.maBitmapEx.IsEqual( maBitmapEx ) &&
+ rAnimation.maGlobalSize == maGlobalSize &&
+ rAnimation.meCycleMode == meCycleMode )
+ {
+ for( ULONG n = 0; ( n < nCount ) && !bRet; n++ )
+ if( ( (AnimationBitmap*) maList.GetObject( n ) )->IsEqual( *(AnimationBitmap*) rAnimation.maList.GetObject( n ) ) )
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Animation::IsEmpty() const
+{
+ return( maBitmapEx.IsEmpty() && !maList.Count() );
+}
+
+// ------------------------------------------------------------------
+
+void Animation::SetEmpty()
+{
+ maTimer.Stop();
+ mbIsInAnimation = FALSE;
+ maGlobalSize = Size();
+ maBitmapEx.SetEmpty();
+
+ for( void* pStepBmp = maList.First(); pStepBmp; pStepBmp = maList.Next() )
+ delete (AnimationBitmap*) pStepBmp;
+ maList.Clear();
+
+ for( void* pView = mpViewList->First(); pView; pView = mpViewList->Next() )
+ delete (ImplAnimView*) pView;
+ mpViewList->Clear();
+}
+
+// -----------------------------------------------------------------------
+
+void Animation::Clear()
+{
+ SetEmpty();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::IsTransparent() const
+{
+ Point aPoint;
+ Rectangle aRect( aPoint, maGlobalSize );
+ BOOL bRet = FALSE;
+
+ // Falls irgendein 'kleines' Bildchen durch den Hintergrund
+ // ersetzt werden soll, muessen wir 'transparent' sein, um
+ // richtig dargestellt zu werden, da die Appl. aus Optimierungsgruenden
+ // kein Invalidate auf nicht-transp. Grafiken ausfuehren
+ for( long i = 0, nCount = maList.Count(); i < nCount; i++ )
+ {
+ const AnimationBitmap* pAnimBmp = (AnimationBitmap*) maList.GetObject( i );
+
+ if( DISPOSE_BACK == pAnimBmp->eDisposal && Rectangle( pAnimBmp->aPosPix, pAnimBmp->aSizePix ) != aRect )
+ {
+ bRet = TRUE;
+ break;
+ }
+ }
+
+ if( !bRet )
+ bRet = maBitmapEx.IsTransparent();
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Animation::GetSizeBytes() const
+{
+ ULONG nSizeBytes = GetBitmapEx().GetSizeBytes();
+
+ for( long i = 0, nCount = maList.Count(); i < nCount; i++ )
+ {
+ const AnimationBitmap* pAnimBmp = (AnimationBitmap*) maList.GetObject( i );
+ nSizeBytes += pAnimBmp->aBmpEx.GetSizeBytes();
+ }
+
+ return nSizeBytes;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Animation::GetChecksum() const
+{
+ SVBT32 aBT32;
+ sal_uInt32 nCrc = GetBitmapEx().GetChecksum();
+
+ LongToSVBT32( maList.Count(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( maGlobalSize.Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( maGlobalSize.Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( (long) meCycleMode, aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ for( long i = 0, nCount = maList.Count(); i < nCount; i++ )
+ {
+ LongToSVBT32( ( (AnimationBitmap*) maList.GetObject( i ) )->GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+
+ return nCrc;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::Start( OutputDevice* pOut, const Point& rDestPt, long nExtraData,
+ OutputDevice* pFirstFrameOutDev )
+{
+ return Start( pOut, rDestPt, pOut->PixelToLogic( maGlobalSize ), nExtraData, pFirstFrameOutDev );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::Start( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz, long nExtraData,
+ OutputDevice* pFirstFrameOutDev )
+{
+ BOOL bRet = FALSE;
+
+ if( maList.Count() )
+ {
+ if( ( pOut->GetOutDevType() == OUTDEV_WINDOW ) && !mbLoopTerminated &&
+ ( ANIMATION_TIMEOUT_ON_CLICK != ( (AnimationBitmap*) maList.GetObject( mnPos ) )->nWait ) )
+ {
+ ImplAnimView* pView;
+ ImplAnimView* pMatch = NULL;
+
+ for( pView = (ImplAnimView*) mpViewList->First(); pView; pView = (ImplAnimView*) mpViewList->Next() )
+ {
+ if( pView->ImplMatches( pOut, nExtraData ) )
+ {
+ if( pView->ImplGetOutPos() == rDestPt &&
+ pView->ImplGetOutSizePix() == pOut->LogicToPixel( rDestSz ) )
+ {
+ pView->ImplRepaint();
+ pMatch = pView;
+ }
+ else
+ {
+ delete (ImplAnimView*) mpViewList->Remove( pView );
+ pView = NULL;
+ }
+
+ break;
+ }
+ }
+
+ if( !mpViewList->Count() )
+ {
+ maTimer.Stop();
+ mbIsInAnimation = FALSE;
+ mnPos = 0UL;
+ }
+
+ if( !pMatch )
+ mpViewList->Insert( new ImplAnimView( this, pOut, rDestPt, rDestSz, nExtraData, pFirstFrameOutDev ), LIST_APPEND );
+
+ if( !mbIsInAnimation )
+ {
+ ImplRestartTimer( ( (AnimationBitmap*) maList.GetObject( mnPos ) )->nWait );
+ mbIsInAnimation = TRUE;
+ }
+ }
+ else
+ Draw( pOut, rDestPt, rDestSz );
+
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void Animation::Stop( OutputDevice* pOut, long nExtraData )
+{
+ ImplAnimView* pView = (ImplAnimView*) mpViewList->First();
+
+ while( pView )
+ {
+ if( pView->ImplMatches( pOut, nExtraData ) )
+ {
+ delete (ImplAnimView*) mpViewList->Remove( pView );
+ pView = (ImplAnimView*) mpViewList->GetCurObject();
+ }
+ else
+ pView = (ImplAnimView*) mpViewList->Next();
+ }
+
+ if( !mpViewList->Count() )
+ {
+ maTimer.Stop();
+ mbIsInAnimation = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Animation::Draw( OutputDevice* pOut, const Point& rDestPt ) const
+{
+ Draw( pOut, rDestPt, pOut->PixelToLogic( maGlobalSize ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Animation::Draw( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz ) const
+{
+ const ULONG nCount = maList.Count();
+
+ if( nCount )
+ {
+ AnimationBitmap* pObj = (AnimationBitmap*) maList.GetObject( Min( mnPos, (long) nCount - 1L ) );
+
+ if( pOut->GetConnectMetaFile() || ( pOut->GetOutDevType() == OUTDEV_PRINTER ) )
+ ( (AnimationBitmap*) maList.GetObject( 0 ) )->aBmpEx.Draw( pOut, rDestPt, rDestSz );
+ else if( ANIMATION_TIMEOUT_ON_CLICK == pObj->nWait )
+ pObj->aBmpEx.Draw( pOut, rDestPt, rDestSz );
+ else
+ {
+ const ULONG nOldPos = mnPos;
+ ( (Animation*) this )->mnPos = mbLoopTerminated ? ( nCount - 1UL ) : mnPos;
+ delete new ImplAnimView( (Animation*) this, pOut, rDestPt, rDestSz, 0 );
+ ( (Animation*) this )->mnPos = nOldPos;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Animation::ImplRestartTimer( ULONG nTimeout )
+{
+#ifdef REMOTE_APPSERVER
+ nTimeout = nTimeout > 40 ? nTimeout : 40;
+#endif
+ maTimer.SetTimeout( Max( nTimeout, MIN_TIMEOUT + ( mnAnimCount - 1 ) * INC_TIMEOUT ) * 10L );
+ maTimer.Start();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Animation, ImplTimeoutHdl, Timer*, pTimer )
+{
+ const ULONG nAnimCount = maList.Count();
+
+ if( nAnimCount )
+ {
+ ImplAnimView* pView;
+ BOOL bGlobalPause = TRUE;
+
+ if( maNotifyLink.IsSet() )
+ {
+ AInfo* pAInfo;
+
+ // create AInfo-List
+ for( pView = (ImplAnimView*) mpViewList->First(); pView; pView = (ImplAnimView*) mpViewList->Next() )
+ maAInfoList.Insert( pView->ImplCreateAInfo() );
+
+ maNotifyLink.Call( this );
+
+ // set view state from AInfo structure
+ for( pAInfo = (AInfo*) maAInfoList.First(); pAInfo; pAInfo = (AInfo*) maAInfoList.Next() )
+ {
+ if( !pAInfo->pViewData )
+ {
+ pView = new ImplAnimView( this, pAInfo->pOutDev,
+ pAInfo->aStartOrg, pAInfo->aStartSize, pAInfo->nExtraData );
+
+ mpViewList->Insert( pView, LIST_APPEND );
+ }
+ else
+ pView = (ImplAnimView*) pAInfo->pViewData;
+
+ pView->ImplPause( pAInfo->bPause );
+ pView->ImplSetMarked( TRUE );
+ }
+
+ // delete AInfo structures
+ for( pAInfo = (AInfo*) maAInfoList.First(); pAInfo; pAInfo = (AInfo*) maAInfoList.Next() )
+ delete (AInfo*) pAInfo;
+ maAInfoList.Clear();
+
+ // delete all unmarked views and reset marked state
+ pView = (ImplAnimView*) mpViewList->First();
+ while( pView )
+ {
+ if( !pView->ImplIsMarked() )
+ {
+ delete (ImplAnimView*) mpViewList->Remove( pView );
+ pView = (ImplAnimView*) mpViewList->GetCurObject();
+ }
+ else
+ {
+ if( !pView->ImplIsPause() )
+ bGlobalPause = FALSE;
+
+ pView->ImplSetMarked( FALSE );
+ pView = (ImplAnimView*) mpViewList->Next();
+ }
+ }
+ }
+ else
+ bGlobalPause = FALSE;
+
+ if( !mpViewList->Count() )
+ Stop();
+ else if( bGlobalPause )
+ ImplRestartTimer( 10 );
+ else
+ {
+ AnimationBitmap* pStepBmp = (AnimationBitmap*) maList.GetObject( ++mnPos );
+
+ if( !pStepBmp )
+ {
+ if( mnLoops == 1 )
+ {
+ Stop();
+ mbLoopTerminated = TRUE;
+ mnPos = nAnimCount - 1UL;
+ maBitmapEx = ( (AnimationBitmap*) maList.GetObject( mnPos ) )->aBmpEx;
+ return 0L;
+ }
+ else
+ {
+ if( mnLoops )
+ mnLoops--;
+
+ mnPos = 0;
+ pStepBmp = (AnimationBitmap*) maList.GetObject( mnPos );
+ }
+ }
+
+ // Paint all views; after painting check, if view is
+ // marked; in this case remove view, because area of output
+ // lies out of display area of window; mark state is
+ // set from view itself
+ pView = (ImplAnimView*) mpViewList->First();
+ while( pView )
+ {
+ pView->ImplDraw( mnPos );
+
+ if( pView->ImplIsMarked() )
+ {
+ delete (ImplAnimView*) mpViewList->Remove( pView );
+ pView = (ImplAnimView*) mpViewList->GetCurObject();
+ }
+ else
+ pView = (ImplAnimView*) mpViewList->Next();
+ }
+
+ // stop or restart timer
+ if( !mpViewList->Count() )
+ Stop();
+ else
+ ImplRestartTimer( pStepBmp->nWait );
+ }
+ }
+ else
+ Stop();
+
+ return 0L;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::Insert( const AnimationBitmap& rStepBmp )
+{
+ BOOL bRet = FALSE;
+
+ if( !IsInAnimation() )
+ {
+ Point aPoint;
+ Rectangle aGlobalRect( aPoint, maGlobalSize );
+
+ maGlobalSize = aGlobalRect.Union( Rectangle( rStepBmp.aPosPix, rStepBmp.aSizePix ) ).GetSize();
+ maList.Insert( new AnimationBitmap( rStepBmp ), LIST_APPEND );
+
+ // zunaechst nehmen wir die erste BitmapEx als Ersatz-BitmapEx
+ if( maList.Count() == 1 )
+ maBitmapEx = rStepBmp.aBmpEx;
+
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+const AnimationBitmap& Animation::Get( USHORT nAnimation ) const
+{
+ DBG_ASSERT( ( nAnimation < maList.Count() ), "No object at this position" );
+ return *(AnimationBitmap*) maList.GetObject( nAnimation );
+}
+
+// -----------------------------------------------------------------------
+
+void Animation::Replace( const AnimationBitmap& rNewAnimationBitmap, USHORT nAnimation )
+{
+ DBG_ASSERT( ( nAnimation < maList.Count() ), "No object at this position" );
+
+ delete (AnimationBitmap*) maList.Replace( new AnimationBitmap( rNewAnimationBitmap ), nAnimation );
+
+ // Falls wir an erster Stelle einfuegen,
+ // muessen wir natuerlich auch,
+ // auch die Ersatzdarstellungs-BitmapEx
+ // aktualisieren;
+ if ( ( !nAnimation && ( !mbLoopTerminated || ( maList.Count() == 1 ) ) ) ||
+ ( ( nAnimation == maList.Count() - 1 ) && mbLoopTerminated ) )
+ {
+ maBitmapEx = rNewAnimationBitmap.aBmpEx;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Animation::SetLoopCount( const ULONG nLoopCount )
+{
+ mnLoopCount = nLoopCount;
+ ResetLoopCount();
+}
+
+// -----------------------------------------------------------------------
+
+void Animation::ResetLoopCount()
+{
+ mnLoops = mnLoopCount;
+ mbLoopTerminated = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::Convert( BmpConversion eConversion )
+{
+ DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
+
+ BOOL bRet;
+
+ if( !IsInAnimation() && maList.Count() )
+ {
+ bRet = TRUE;
+
+ for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() )
+ bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Convert( eConversion );
+
+ maBitmapEx.Convert( eConversion );
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::ReduceColors( USHORT nNewColorCount, BmpReduce eReduce )
+{
+ DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
+
+ BOOL bRet;
+
+ if( !IsInAnimation() && maList.Count() )
+ {
+ bRet = TRUE;
+
+ for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() )
+ bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.ReduceColors( nNewColorCount, eReduce );
+
+ maBitmapEx.ReduceColors( nNewColorCount, eReduce );
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::Invert()
+{
+ DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
+
+ BOOL bRet;
+
+ if( !IsInAnimation() && maList.Count() )
+ {
+ bRet = TRUE;
+
+ for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() )
+ bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Invert();
+
+ maBitmapEx.Invert();
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::Mirror( ULONG nMirrorFlags )
+{
+ DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
+
+ BOOL bRet;
+
+ if( !IsInAnimation() && maList.Count() )
+ {
+ bRet = TRUE;
+
+ if( nMirrorFlags )
+ {
+ for( AnimationBitmap* pStepBmp = (AnimationBitmap*) maList.First();
+ pStepBmp && bRet;
+ pStepBmp = (AnimationBitmap*) maList.Next() )
+ {
+ if( ( bRet = pStepBmp->aBmpEx.Mirror( nMirrorFlags ) ) == TRUE )
+ {
+ if( nMirrorFlags & BMP_MIRROR_HORZ )
+ pStepBmp->aPosPix.X() = maGlobalSize.Width() - pStepBmp->aPosPix.X() - pStepBmp->aSizePix.Width();
+
+ if( nMirrorFlags & BMP_MIRROR_VERT )
+ pStepBmp->aPosPix.Y() = maGlobalSize.Height() - pStepBmp->aPosPix.Y() - pStepBmp->aSizePix.Height();
+ }
+ }
+
+ maBitmapEx.Mirror( nMirrorFlags );
+ }
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::Dither( ULONG nDitherFlags, const BitmapPalette* pDitherPal )
+{
+ DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
+
+ BOOL bRet;
+
+ if( !IsInAnimation() && maList.Count() )
+ {
+ bRet = TRUE;
+
+ for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() )
+ bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Dither( nDitherFlags, pDitherPal );
+
+ maBitmapEx.Dither( nDitherFlags, pDitherPal );
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::Adjust( short nLuminancePercent, short nContrastPercent,
+ short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
+ double fGamma, BOOL bInvert )
+{
+ DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
+
+ BOOL bRet;
+
+ if( !IsInAnimation() && maList.Count() )
+ {
+ bRet = TRUE;
+
+ for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() )
+ {
+ bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Adjust( nLuminancePercent, nContrastPercent,
+ nChannelRPercent, nChannelGPercent, nChannelBPercent,
+ fGamma, bInvert );
+ }
+
+ maBitmapEx.Adjust( nLuminancePercent, nContrastPercent,
+ nChannelRPercent, nChannelGPercent, nChannelBPercent,
+ fGamma, bInvert );
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Animation::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
+
+ BOOL bRet;
+
+ if( !IsInAnimation() && maList.Count() )
+ {
+ bRet = TRUE;
+
+ for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() )
+ bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Filter( eFilter, pFilterParam, pProgress );
+
+ maBitmapEx.Filter( eFilter, pFilterParam, pProgress );
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const Animation& rAnimation )
+{
+ const USHORT nCount = rAnimation.Count();
+
+ if( nCount )
+ {
+ const ByteString aDummyStr;
+ const UINT32 nDummy32 = 0UL;
+
+ // Falls keine BitmapEx gesetzt wurde, schreiben wir
+ // einfach die erste Bitmap der Animation
+ if( !rAnimation.GetBitmapEx().GetBitmap() )
+ rOStm << rAnimation.Get( 0 ).aBmpEx;
+ else
+ rOStm << rAnimation.GetBitmapEx();
+
+ // Kennung schreiben ( SDANIMA1 )
+ rOStm << (UINT32) 0x5344414e << (UINT32) 0x494d4931;
+
+ for( USHORT i = 0; i < nCount; i++ )
+ {
+ const AnimationBitmap& rAnimBmp = rAnimation.Get( i );
+ const UINT16 nRest = nCount - i - 1;
+
+ // AnimationBitmap schreiben
+ rOStm << rAnimBmp.aBmpEx;
+ rOStm << rAnimBmp.aPosPix;
+ rOStm << rAnimBmp.aSizePix;
+ rOStm << rAnimation.maGlobalSize;
+ rOStm << (UINT16) ( ( ANIMATION_TIMEOUT_ON_CLICK == rAnimBmp.nWait ) ? 65535 : rAnimBmp.nWait );
+ rOStm << (UINT16) rAnimBmp.eDisposal;
+ rOStm << (BYTE) rAnimBmp.bUserInput;
+ rOStm << (UINT32) rAnimation.mnLoopCount;
+ rOStm << nDummy32; // unbenutzt
+ rOStm << nDummy32; // unbenutzt
+ rOStm << nDummy32; // unbenutzt
+ rOStm << aDummyStr; // unbenutzt
+ rOStm << nRest; // Anzahl der Strukturen, die noch _folgen_
+ }
+ }
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, Animation& rAnimation )
+{
+ Bitmap aBmp;
+ ULONG nStmPos = rIStm.Tell();
+ UINT32 nAnimMagic1, nAnimMagic2;
+ USHORT nOldFormat = rIStm.GetNumberFormatInt();
+ BOOL bReadAnimations = FALSE;
+
+ rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ nStmPos = rIStm.Tell();
+ rIStm >> nAnimMagic1 >> nAnimMagic2;
+
+ rAnimation.Clear();
+
+ // Wenn die BitmapEx am Anfang schon gelesen
+ // wurde ( von Graphic ), koennen wir direkt die Animationsbitmaps einlesen
+ if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() )
+ bReadAnimations = TRUE;
+ // ansonsten versuchen wir erstmal die Bitmap(-Ex) zu lesen
+ else
+ {
+ rIStm.Seek( nStmPos );
+ rIStm >> rAnimation.maBitmapEx;
+ nStmPos = rIStm.Tell();
+ rIStm >> nAnimMagic1 >> nAnimMagic2;
+
+ if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() )
+ bReadAnimations = TRUE;
+ else
+ rIStm.Seek( nStmPos );
+ }
+
+ // ggf. Animationsbitmaps lesen
+ if( bReadAnimations )
+ {
+ AnimationBitmap aAnimBmp;
+ BitmapEx aBmpEx;
+ ByteString aDummyStr;
+ Point aPoint;
+ Size aSize;
+ UINT32 nTmp32;
+ UINT16 nTmp16;
+ BYTE cTmp;
+
+ do
+ {
+ rIStm >> aAnimBmp.aBmpEx;
+ rIStm >> aAnimBmp.aPosPix;
+ rIStm >> aAnimBmp.aSizePix;
+ rIStm >> rAnimation.maGlobalSize;
+ rIStm >> nTmp16; aAnimBmp.nWait = ( ( 65535 == nTmp16 ) ? ANIMATION_TIMEOUT_ON_CLICK : nTmp16 );
+ rIStm >> nTmp16; aAnimBmp.eDisposal = ( Disposal) nTmp16;
+ rIStm >> cTmp; aAnimBmp.bUserInput = (BOOL) cTmp;
+ rIStm >> nTmp32; rAnimation.mnLoopCount = (USHORT) nTmp32;
+ rIStm >> nTmp32; // unbenutzt
+ rIStm >> nTmp32; // unbenutzt
+ rIStm >> nTmp32; // unbenutzt
+ rIStm >> aDummyStr; // unbenutzt
+ rIStm >> nTmp16; // Rest zu lesen
+
+ rAnimation.Insert( aAnimBmp );
+ }
+ while( nTmp16 && !rIStm.GetError() );
+
+ rAnimation.ResetLoopCount();
+ }
+
+ rIStm.SetNumberFormatInt( nOldFormat );
+
+ return rIStm;
+}
diff --git a/vcl/source/gdi/bitmap.cxx b/vcl/source/gdi/bitmap.cxx
new file mode 100644
index 000000000000..d5016647cfca
--- /dev/null
+++ b/vcl/source/gdi/bitmap.cxx
@@ -0,0 +1,1980 @@
+/*************************************************************************
+ *
+ * $RCSfile: bitmap.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_BITMAP_CXX
+
+#ifndef _RTL_CRC_H_
+#include <rtl/crc.h>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_IMPBMP_HXX
+#include <impbmp.hxx>
+#endif
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_ALPHA_HXX
+#include <alpha.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+
+// ------------------------------------------------------------------
+
+Bitmap::Bitmap() :
+ mpImpBmp( NULL )
+{
+}
+
+// ------------------------------------------------------------------
+
+Bitmap::Bitmap( const ResId& rResId ) :
+ mpImpBmp( NULL )
+{
+ ResMgr * pResMgr = NULL;
+
+ ResMgr::GetResourceSkipHeader( rResId.SetRT( RSC_BITMAP ), &pResMgr );
+
+ USHORT nBitmapType;
+ USHORT nBitmapId;
+ nBitmapType = pResMgr->ReadShort();
+ nBitmapId = pResMgr->ReadShort();
+
+ SvStream* pBmpStream = pResMgr->pImpRes->GetBitmapStream( nBitmapId );
+ if( pBmpStream )
+ *pBmpStream >> *this;
+ // pop filename
+ String aDummy = pResMgr->ReadString();
+}
+
+// ------------------------------------------------------------------
+
+Bitmap::Bitmap( const Bitmap& rBitmap ) :
+ maPrefMapMode ( rBitmap.maPrefMapMode ),
+ maPrefSize ( rBitmap.maPrefSize )
+{
+ mpImpBmp = rBitmap.mpImpBmp;
+
+ if ( mpImpBmp )
+ mpImpBmp->ImplIncRefCount();
+}
+
+// ------------------------------------------------------------------
+
+Bitmap::Bitmap( const Size& rSizePixel, USHORT nBitCount, const BitmapPalette* pPal )
+{
+ if( rSizePixel.Width() && rSizePixel.Height() )
+ {
+ BitmapPalette aPal;
+ BitmapPalette* pRealPal = NULL;
+
+ if( nBitCount <= 8 )
+ {
+ if( !pPal )
+ {
+ if( 1 == nBitCount )
+ {
+ aPal.SetEntryCount( 2 );
+ aPal[ 0 ] = Color( COL_BLACK );
+ aPal[ 1 ] = Color( COL_WHITE );
+ }
+ else if( ( 4 == nBitCount ) || ( 8 == nBitCount ) )
+ {
+ aPal.SetEntryCount( 1 << nBitCount );
+ aPal[ 0 ] = Color( COL_BLACK );
+ aPal[ 1 ] = Color( COL_BLUE );
+ aPal[ 2 ] = Color( COL_GREEN );
+ aPal[ 3 ] = Color( COL_CYAN );
+ aPal[ 4 ] = Color( COL_RED );
+ aPal[ 5 ] = Color( COL_MAGENTA );
+ aPal[ 6 ] = Color( COL_BROWN );
+ aPal[ 7 ] = Color( COL_GRAY );
+ aPal[ 8 ] = Color( COL_LIGHTGRAY );
+ aPal[ 9 ] = Color( COL_LIGHTBLUE );
+ aPal[ 10 ] = Color( COL_LIGHTGREEN );
+ aPal[ 11 ] = Color( COL_LIGHTCYAN );
+ aPal[ 12 ] = Color( COL_LIGHTRED );
+ aPal[ 13 ] = Color( COL_LIGHTMAGENTA );
+ aPal[ 14 ] = Color( COL_YELLOW );
+ aPal[ 15 ] = Color( COL_WHITE );
+
+ // Dither-Palette erzeugen
+ if( 8 == nBitCount )
+ {
+ USHORT nActCol = 16;
+
+ for( USHORT nB = 0; nB < 256; nB += 51 )
+ for( USHORT nG = 0; nG < 256; nG += 51 )
+ for( USHORT nR = 0; nR < 256; nR += 51 )
+ aPal[ nActCol++ ] = BitmapColor( (BYTE) nR, (BYTE) nG, (BYTE) nB );
+
+ // Standard-Office-Farbe setzen
+ aPal[ nActCol++ ] = BitmapColor( 0, 184, 255 );
+ }
+ }
+ }
+ else
+ pRealPal = (BitmapPalette*) pPal;
+ }
+
+ mpImpBmp = new ImpBitmap;
+ mpImpBmp->ImplCreate( rSizePixel, nBitCount, pRealPal ? *pRealPal : aPal );
+ }
+ else
+ mpImpBmp = NULL;
+}
+
+// ------------------------------------------------------------------
+
+Bitmap::~Bitmap()
+{
+ ImplReleaseRef();
+}
+
+// ------------------------------------------------------------------
+
+const BitmapPalette& Bitmap::GetGreyPalette( USHORT nEntries )
+{
+ static BitmapPalette aGreyPalette2;
+ static BitmapPalette aGreyPalette4;
+ static BitmapPalette aGreyPalette16;
+ static BitmapPalette aGreyPalette256;
+
+ // create greyscale palette with 2, 4, 16 or 256 entries
+ if( 2 == nEntries || 4 == nEntries || 16 == nEntries || 256 == nEntries )
+ {
+ if( 2 == nEntries )
+ {
+ if( !aGreyPalette2.GetEntryCount() )
+ {
+ aGreyPalette2.SetEntryCount( 2 );
+ aGreyPalette2[ 0 ] = BitmapColor( 0, 0, 0 );
+ aGreyPalette2[ 1 ] = BitmapColor( 255, 255, 255 );
+ }
+
+ return aGreyPalette2;
+ }
+ else if( 4 == nEntries )
+ {
+ if( !aGreyPalette4.GetEntryCount() )
+ {
+ aGreyPalette4.SetEntryCount( 4 );
+ aGreyPalette4[ 0 ] = BitmapColor( 0, 0, 0 );
+ aGreyPalette4[ 1 ] = BitmapColor( 85, 85, 85 );
+ aGreyPalette4[ 2 ] = BitmapColor( 170, 170, 170 );
+ aGreyPalette4[ 3 ] = BitmapColor( 255, 255, 255 );
+ }
+
+ return aGreyPalette4;
+ }
+ else if( 16 == nEntries )
+ {
+ if( !aGreyPalette16.GetEntryCount() )
+ {
+ BYTE cGrey = 0, cGreyInc = 17;
+
+ aGreyPalette16.SetEntryCount( 16 );
+
+ for( USHORT i = 0; i < 16; i++, cGrey += cGreyInc )
+ aGreyPalette16[ i ] = BitmapColor( cGrey, cGrey, cGrey );
+ }
+
+ return aGreyPalette16;
+ }
+ else
+ {
+ if( !aGreyPalette256.GetEntryCount() )
+ {
+ aGreyPalette256.SetEntryCount( 256 );
+
+ for( USHORT i = 0; i < 256; i++ )
+ aGreyPalette256[ i ] = BitmapColor( (BYTE) i, (BYTE) i, (BYTE) i );
+ }
+
+ return aGreyPalette256;
+ }
+ }
+ else
+ {
+ DBG_ERROR( "Bitmap::GetGreyPalette: invalid entry count (2/4/16/256 allowed)" );
+ return aGreyPalette2;
+ }
+}
+
+// ------------------------------------------------------------------
+
+Bitmap& Bitmap::operator=( const Bitmap& rBitmap )
+{
+ maPrefSize = rBitmap.maPrefSize;
+ maPrefMapMode = rBitmap.maPrefMapMode;
+
+ if ( rBitmap.mpImpBmp )
+ rBitmap.mpImpBmp->ImplIncRefCount();
+
+ ImplReleaseRef();
+ mpImpBmp = rBitmap.mpImpBmp;
+
+ return *this;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::IsEqual( const Bitmap& rBmp ) const
+{
+ return( IsSameInstance( rBmp ) ||
+ ( rBmp.GetSizePixel() == GetSizePixel() &&
+ rBmp.GetBitCount() == GetBitCount() &&
+ rBmp.GetChecksum() == GetChecksum() ) );
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::SetEmpty()
+{
+ maPrefMapMode = MapMode();
+ maPrefSize = Size();
+
+ ImplReleaseRef();
+ mpImpBmp = NULL;
+}
+
+// ------------------------------------------------------------------
+
+Size Bitmap::GetSizePixel() const
+{
+ return( mpImpBmp ? mpImpBmp->ImplGetSize() : Size() );
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::SetSizePixel( const Size& rNewSize )
+{
+ Scale( rNewSize );
+}
+
+// ------------------------------------------------------------------
+
+USHORT Bitmap::GetBitCount() const
+{
+ return( mpImpBmp ? mpImpBmp->ImplGetBitCount() : 0 );
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::HasGreyPalette() const
+{
+ const USHORT nBitCount = GetBitCount();
+ BOOL bRet = FALSE;
+
+ if( 1 == nBitCount )
+ bRet = TRUE;
+ else if( 4 == nBitCount || 8 == nBitCount )
+ {
+ BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess();
+
+ if( pRAcc )
+ {
+ if( pRAcc->HasPalette() && ( (BitmapPalette&) pRAcc->GetPalette() == GetGreyPalette( 1 << nBitCount ) ) )
+ bRet = TRUE;
+
+ ( (Bitmap*) this )->ReleaseAccess( pRAcc );
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+ULONG Bitmap::GetChecksum() const
+{
+ ULONG nRet = 0UL;
+
+ if( mpImpBmp )
+ {
+ nRet = mpImpBmp->ImplGetChecksum();
+
+ if( !nRet )
+ {
+ BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess();
+
+ if( pRAcc && pRAcc->Width() && pRAcc->Height() )
+ {
+ sal_uInt32 nCrc = 0;
+ SVBT32 aBT32;
+
+ pRAcc->ImplZeroInitUnusedBits();
+
+ LongToSVBT32( pRAcc->Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pRAcc->Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pRAcc->GetBitCount(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pRAcc->GetColorMask().GetRedMask(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pRAcc->GetColorMask().GetGreenMask(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pRAcc->GetColorMask().GetBlueMask(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ if( pRAcc->HasPalette() )
+ {
+ nCrc = rtl_crc32( nCrc, pRAcc->GetPalette().ImplGetColorBuffer(),
+ pRAcc->GetPaletteEntryCount() * sizeof( BitmapColor ) );
+ }
+
+ nCrc = rtl_crc32( nCrc, pRAcc->GetBuffer(), pRAcc->GetScanlineSize() * pRAcc->Height() );
+
+ ( (Bitmap*) this )->ReleaseAccess( pRAcc );
+
+ mpImpBmp->ImplSetChecksum( nRet = nCrc );
+ }
+ }
+ }
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ImplReleaseRef()
+{
+ if( mpImpBmp )
+ {
+ if( mpImpBmp->ImplGetRefCount() > 1UL )
+ mpImpBmp->ImplDecRefCount();
+ else
+ {
+ delete mpImpBmp;
+ mpImpBmp = NULL;
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ImplMakeUnique()
+{
+ if( mpImpBmp && mpImpBmp->ImplGetRefCount() > 1UL )
+ {
+ ImpBitmap* pOldImpBmp = mpImpBmp;
+
+ pOldImpBmp->ImplDecRefCount();
+
+ mpImpBmp = new ImpBitmap;
+ mpImpBmp->ImplCreate( *pOldImpBmp );
+ }
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ImplAssignWithSize( const Bitmap& rBitmap )
+{
+ const Size aOldSizePix( GetSizePixel() );
+ const Size aNewSizePix( rBitmap.GetSizePixel() );
+ const MapMode aOldMapMode( maPrefMapMode );
+ Size aNewPrefSize;
+
+ if( ( aOldSizePix != aNewSizePix ) && aOldSizePix.Width() && aOldSizePix.Height() )
+ {
+ aNewPrefSize.Width() = FRound( maPrefSize.Width() * aNewSizePix.Width() / aOldSizePix.Width() );
+ aNewPrefSize.Height() = FRound( maPrefSize.Height() * aNewSizePix.Height() / aOldSizePix.Height() );
+ }
+ else
+ aNewPrefSize = maPrefSize;
+
+ *this = rBitmap;
+
+ maPrefSize = aNewPrefSize;
+ maPrefMapMode = aOldMapMode;
+}
+
+// ------------------------------------------------------------------
+
+ImpBitmap* Bitmap::ImplGetImpBitmap() const
+{
+ return mpImpBmp;
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ImplSetImpBitmap( ImpBitmap* pImpBmp )
+{
+ if( pImpBmp != mpImpBmp )
+ {
+ ImplReleaseRef();
+ mpImpBmp = pImpBmp;
+ }
+}
+
+// ------------------------------------------------------------------
+
+BitmapReadAccess* Bitmap::AcquireReadAccess()
+{
+#ifdef REMOTE_APPSERVER
+ BOOL bGottenFromServer = FALSE;
+ if( mpImpBmp && mpImpBmp->ImplIsGetPrepared() )
+ mpImpBmp->ImplResolveGet(), bGottenFromServer = TRUE;
+#endif
+
+ BitmapReadAccess* pReadAccess = new BitmapReadAccess( *this );
+
+ if( !*pReadAccess )
+ {
+ delete pReadAccess;
+ pReadAccess = NULL;
+ }
+
+#ifdef REMOTE_APPSERVER
+ if( pReadAccess && mpImpBmp && bGottenFromServer )
+ mpImpBmp->ImplReleaseRemoteBmp();
+#endif
+
+ return pReadAccess;
+}
+
+// ------------------------------------------------------------------
+
+BitmapWriteAccess* Bitmap::AcquireWriteAccess()
+{
+#ifdef REMOTE_APPSERVER
+ if( mpImpBmp && mpImpBmp->ImplIsGetPrepared() )
+ mpImpBmp->ImplResolveGet();
+#endif
+
+ BitmapWriteAccess* pWriteAccess = new BitmapWriteAccess( *this );
+
+ if( !*pWriteAccess )
+ {
+ delete pWriteAccess;
+ pWriteAccess = NULL;
+ }
+
+#ifdef REMOTE_APPSERVER
+ if( pWriteAccess && mpImpBmp )
+ mpImpBmp->ImplReleaseRemoteBmp();
+#endif
+
+ return pWriteAccess;
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ReleaseAccess( BitmapReadAccess* pBitmapAccess )
+{
+ delete pBitmapAccess;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Erase( const Color& rFillColor )
+{
+ BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pWriteAcc )
+ {
+ const ULONG nFormat = pWriteAcc->GetScanlineFormat();
+ BYTE cIndex;
+ BOOL bFast;
+
+ switch( nFormat )
+ {
+ case( BMP_FORMAT_1BIT_MSB_PAL ):
+ case( BMP_FORMAT_1BIT_LSB_PAL ):
+ {
+ cIndex = (BYTE) pWriteAcc->GetBestPaletteIndex( rFillColor );
+ cIndex = ( cIndex ? 255 : 0 );
+ bFast = TRUE;
+ }
+ break;
+
+ case( BMP_FORMAT_4BIT_MSN_PAL ):
+ case( BMP_FORMAT_4BIT_LSN_PAL ):
+ {
+ cIndex = (BYTE) pWriteAcc->GetBestPaletteIndex( rFillColor );
+ cIndex = cIndex | ( cIndex << 4 );
+ bFast = TRUE;
+ }
+ break;
+
+ case( BMP_FORMAT_8BIT_PAL ):
+ {
+ cIndex = (BYTE) pWriteAcc->GetBestPaletteIndex( rFillColor );
+ bFast = TRUE;
+ }
+ break;
+
+ case( BMP_FORMAT_24BIT_TC_BGR ):
+ case( BMP_FORMAT_24BIT_TC_RGB ):
+ {
+ if( ( rFillColor.GetRed() == rFillColor.GetGreen() ) &&
+ ( rFillColor.GetRed() == rFillColor.GetBlue() ) )
+ {
+ cIndex = rFillColor.GetRed();
+ bFast = TRUE;
+ }
+ else
+ bFast = FALSE;
+ }
+ break;
+
+ default:
+ bFast = FALSE;
+ break;
+ }
+
+ if( bFast )
+ {
+ const ULONG nBufSize = pWriteAcc->GetScanlineSize() * pWriteAcc->Height();
+ HMEMSET( pWriteAcc->GetBuffer(), cIndex, nBufSize );
+ }
+ else
+ {
+ Point aTmpPoint;
+ const Rectangle aRect( aTmpPoint, Size( pWriteAcc->Width(), pWriteAcc->Height() ) );
+ pWriteAcc->SetFillColor( rFillColor );
+ pWriteAcc->FillRect( aRect );
+ }
+
+ ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Invert()
+{
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pAcc )
+ {
+ if( pAcc->HasPalette() )
+ {
+ BitmapPalette aBmpPal( pAcc->GetPalette() );
+ const USHORT nCount = aBmpPal.GetEntryCount();
+
+ for( USHORT i = 0; i < nCount; i++ )
+ aBmpPal[ i ].Invert();
+
+ pAcc->SetPalette( aBmpPal );
+ }
+ else
+ {
+ const long nWidth = pAcc->Width();
+ const long nHeight = pAcc->Height();
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ for( long nY = 0L; nY < nHeight; nY++ )
+ pAcc->SetPixel( nY, nX, pAcc->GetPixel( nY, nX ).Invert() );
+ }
+
+ ReleaseAccess( pAcc );
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Mirror( ULONG nMirrorFlags )
+{
+ BOOL bHorz = ( ( nMirrorFlags & BMP_MIRROR_HORZ ) == BMP_MIRROR_HORZ );
+ BOOL bVert = ( ( nMirrorFlags & BMP_MIRROR_VERT ) == BMP_MIRROR_VERT );
+ BOOL bRet = FALSE;
+
+ if( bHorz && !bVert )
+ {
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+
+ if( pAcc )
+ {
+ const long nWidth = pAcc->Width();
+ const long nHeight = pAcc->Height();
+ const long nWidth1 = nWidth - 1L;
+ const long nWidth_2 = nWidth >> 1L;
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L, nOther = nWidth1; nX < nWidth_2; nX++, nOther-- )
+ {
+ const BitmapColor aTemp( pAcc->GetPixel( nY, nX ) );
+
+ pAcc->SetPixel( nY, nX, pAcc->GetPixel( nY, nOther ) );
+ pAcc->SetPixel( nY, nOther, aTemp );
+ }
+ }
+
+ ReleaseAccess( pAcc );
+ bRet = TRUE;
+ }
+ }
+ else if( bVert && !bHorz )
+ {
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+
+ if( pAcc )
+ {
+ const long nScanSize = pAcc->GetScanlineSize();
+ BYTE* pBuffer = new BYTE[ nScanSize ];
+ const long nHeight = pAcc->Height();
+ const long nHeight1 = nHeight - 1L;
+ const long nHeight_2 = nHeight >> 1L;
+
+ for( long nY = 0L, nOther = nHeight1; nY < nHeight_2; nY++, nOther-- )
+ {
+ HMEMCPY( pBuffer, pAcc->GetScanline( nY ), nScanSize );
+ HMEMCPY( pAcc->GetScanline( nY ), pAcc->GetScanline( nOther ), nScanSize );
+ HMEMCPY( pAcc->GetScanline( nOther ), pBuffer, nScanSize );
+ }
+
+ delete[] pBuffer;
+ ReleaseAccess( pAcc );
+ bRet = TRUE;
+ }
+ }
+ else if( bHorz && bVert )
+ {
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+
+ if( pAcc )
+ {
+ const long nWidth = pAcc->Width();
+ const long nWidth1 = nWidth - 1L;
+ const long nHeight = pAcc->Height();
+ long nHeight_2 = nHeight >> 1;
+
+ for( long nY = 0L, nOtherY = nHeight - 1L; nY < nHeight_2; nY++, nOtherY-- )
+ {
+ for( long nX = 0L, nOtherX = nWidth1; nX < nWidth; nX++, nOtherX-- )
+ {
+ const BitmapColor aTemp( pAcc->GetPixel( nY, nX ) );
+
+ pAcc->SetPixel( nY, nX, pAcc->GetPixel( nOtherY, nOtherX ) );
+ pAcc->SetPixel( nOtherY, nOtherX, aTemp );
+ }
+ }
+
+ // ggf. noch mittlere Zeile horizontal spiegeln
+ if( nHeight & 1 )
+ {
+ for( long nX = 0L, nOtherX = nWidth1, nWidth_2 = nWidth >> 1; nX < nWidth_2; nX++, nOtherX-- )
+ {
+ const BitmapColor aTemp( pAcc->GetPixel( nHeight_2, nX ) );
+ pAcc->SetPixel( nHeight_2, nX, pAcc->GetPixel( nHeight_2, nOtherX ) );
+ pAcc->SetPixel( nHeight_2, nOtherX, aTemp );
+ }
+ }
+
+ ReleaseAccess( pAcc );
+ bRet = TRUE;
+ }
+ }
+ else
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Rotate( long nAngle10, const Color& rFillColor )
+{
+ BOOL bRet = FALSE;
+
+ nAngle10 %= 3600L;
+ nAngle10 = ( nAngle10 < 0L ) ? ( 3599L + nAngle10 ) : nAngle10;
+
+ if( !nAngle10 )
+ bRet = TRUE;
+ else if( 1800L == nAngle10 )
+ bRet = Mirror( BMP_MIRROR_HORZ | BMP_MIRROR_VERT );
+ else
+ {
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ Bitmap aRotatedBmp;
+
+ if( pReadAcc )
+ {
+ const Size aSizePix( GetSizePixel() );
+
+ if( ( 900L == nAngle10 ) || ( 2700L == nAngle10 ) )
+ {
+ const Size aNewSizePix( aSizePix.Height(), aSizePix.Width() );
+ Bitmap aNewBmp( aNewSizePix, GetBitCount(), &pReadAcc->GetPalette() );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const long nWidth = aSizePix.Width();
+ const long nWidth1 = nWidth - 1L;
+ const long nHeight = aSizePix.Height();
+ const long nHeight1 = nHeight - 1L;
+ const long nNewWidth = aNewSizePix.Width();
+ const long nNewHeight = aNewSizePix.Height();
+
+ if( 900L == nAngle10 )
+ {
+ for( long nY = 0L, nOtherX = nWidth1; nY < nNewHeight; nY++, nOtherX-- )
+ for( long nX = 0L, nOtherY = 0L; nX < nNewWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nOtherY++, nOtherX ) );
+ }
+ else if( 2700L == nAngle10 )
+ {
+ for( long nY = 0L, nOtherX = 0L; nY < nNewHeight; nY++, nOtherX++ )
+ for( long nX = 0L, nOtherY = nHeight1; nX < nNewWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nOtherY--, nOtherX ) );
+ }
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ }
+
+ aRotatedBmp = aNewBmp;
+ }
+ else
+ {
+ Point aTmpPoint;
+ Rectangle aTmpRectangle( aTmpPoint, aSizePix );
+ Polygon aPoly( aTmpRectangle );
+ aPoly.Rotate( aTmpPoint, (USHORT) nAngle10 );
+
+ Rectangle aNewBound( aPoly.GetBoundRect() );
+ const Size aNewSizePix( aNewBound.GetSize() );
+ Bitmap aNewBmp( aNewSizePix, GetBitCount(), &pReadAcc->GetPalette() );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const BitmapColor aFillColor( pWriteAcc->GetBestMatchingColor( rFillColor ) );
+ const double fCosAngle = cos( nAngle10 * F_PI1800 );
+ const double fSinAngle = sin( nAngle10 * F_PI1800 );
+ const double fXMin = aNewBound.Left();
+ const double fYMin = aNewBound.Top();
+ const long nWidth = aSizePix.Width();
+ const long nHeight = aSizePix.Height();
+ const long nNewWidth = aNewSizePix.Width();
+ const long nNewHeight = aNewSizePix.Height();
+ long nX;
+ long nY;
+ long nRotX;
+ long nRotY;
+ long nSinY;
+ long nCosY;
+ long* pCosX = new long[ nNewWidth ];
+ long* pSinX = new long[ nNewWidth ];
+ long* pCosY = new long[ nNewHeight ];
+ long* pSinY = new long[ nNewHeight ];
+
+ for ( nX = 0; nX < nNewWidth; nX++ )
+ {
+ const double fTmp = ( fXMin + nX ) * 64.;
+
+ pCosX[ nX ] = FRound( fCosAngle * fTmp );
+ pSinX[ nX ] = FRound( fSinAngle * fTmp );
+ }
+
+ for ( nY = 0; nY < nNewHeight; nY++ )
+ {
+ const double fTmp = ( fYMin + nY ) * 64.;
+
+ pCosY[ nY ] = FRound( fCosAngle * fTmp );
+ pSinY[ nY ] = FRound( fSinAngle * fTmp );
+ }
+
+ for( nY = 0L; nY < nNewHeight; nY++ )
+ {
+ nSinY = pSinY[ nY ];
+ nCosY = pCosY[ nY ];
+
+ for( nX = 0L; nX < nNewWidth; nX++ )
+ {
+ nRotX = ( pCosX[ nX ] - nSinY ) >> 6;
+ nRotY = ( pSinX[ nX ] + nCosY ) >> 6;
+
+ if ( ( nRotX > -1L ) && ( nRotX < nWidth ) && ( nRotY > -1L ) && ( nRotY < nHeight ) )
+ pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nRotY, nRotX ) );
+ else
+ pWriteAcc->SetPixel( nY, nX, aFillColor );
+ }
+ }
+
+ delete[] pSinX;
+ delete[] pCosX;
+ delete[] pSinY;
+ delete[] pCosY;
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ }
+
+ aRotatedBmp = aNewBmp;
+ }
+
+ ReleaseAccess( pReadAcc );
+ }
+
+ if( ( bRet = !!aRotatedBmp ) == TRUE )
+ ImplAssignWithSize( aRotatedBmp );
+ }
+
+ return bRet;
+};
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Crop( const Rectangle& rRectPixel )
+{
+ const Size aSizePix( GetSizePixel() );
+ Rectangle aRect( rRectPixel );
+ BOOL bRet = FALSE;
+
+ aRect.Intersection( Rectangle( Point(), aSizePix ) );
+
+ if( !aRect.IsEmpty() )
+ {
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+
+ if( pReadAcc )
+ {
+ Point aTmpPoint;
+ const Rectangle aNewRect( aTmpPoint, aRect.GetSize() );
+ Bitmap aNewBmp( aNewRect.GetSize(), GetBitCount(), &pReadAcc->GetPalette() );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const long nOldX = aRect.Left();
+ const long nOldY = aRect.Top();
+ const long nNewWidth = aNewRect.GetWidth();
+ const long nNewHeight = aNewRect.GetHeight();
+
+ for( long nY = 0, nY2 = nOldY; nY < nNewHeight; nY++, nY2++ )
+ for( long nX = 0, nX2 = nOldX; nX < nNewWidth; nX++, nX2++ )
+ pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY2, nX2 ) );
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ ImplAssignWithSize( aNewBmp );
+ }
+ }
+
+ return bRet;
+};
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::CopyPixel( const Rectangle& rRectDst,
+ const Rectangle& rRectSrc, const Bitmap* pBmpSrc )
+{
+ const Size aSizePix( GetSizePixel() );
+ Rectangle aRectDst( rRectDst );
+ BOOL bRet = FALSE;
+
+ aRectDst.Intersection( Rectangle( Point(), aSizePix ) );
+
+ if( !aRectDst.IsEmpty() )
+ {
+ if( pBmpSrc && ( *pBmpSrc != *this ) )
+ {
+ Bitmap* pSrc = (Bitmap*) pBmpSrc;
+ const Size aCopySizePix( pSrc->GetSizePixel() );
+ Rectangle aRectSrc( rRectSrc );
+ const USHORT nSrcBitCount = pBmpSrc->GetBitCount();
+ const USHORT nDstBitCount = GetBitCount();
+
+ if( nSrcBitCount > nDstBitCount )
+ {
+ long nNextIndex = 0L;
+
+ if( ( nSrcBitCount == 24 ) && ( nDstBitCount < 24 ) )
+ Convert( BMP_CONVERSION_24BIT );
+ else if( ( nSrcBitCount == 8 ) && ( nDstBitCount < 8 ) )
+ {
+ Convert( BMP_CONVERSION_8BIT_COLORS );
+ nNextIndex = 16;
+ }
+ else if( ( nSrcBitCount == 4 ) && ( nDstBitCount < 4 ) )
+ {
+ Convert( BMP_CONVERSION_4BIT_COLORS );
+ nNextIndex = 2;
+ }
+
+ if( nNextIndex )
+ {
+ BitmapReadAccess* pSrcAcc = pSrc->AcquireReadAccess();
+ BitmapWriteAccess* pDstAcc = AcquireWriteAccess();
+
+ if( pSrcAcc && pDstAcc )
+ {
+ const long nSrcCount = pDstAcc->GetPaletteEntryCount();
+ const long nDstCount = 1 << nDstBitCount;
+ BOOL bFound;
+
+ for( long i = 0L; ( i < nSrcCount ) && ( nNextIndex < nSrcCount ); i++ )
+ {
+ const BitmapColor& rSrcCol = pSrcAcc->GetPaletteColor( (USHORT) i );
+
+ bFound = FALSE;
+
+ for( long j = 0L; j < nDstCount; j++ )
+ {
+ if( rSrcCol == pDstAcc->GetPaletteColor( (USHORT) j ) )
+ {
+ bFound = TRUE;
+ break;
+ }
+ }
+
+ if( !bFound )
+ pDstAcc->SetPaletteColor( (USHORT) nNextIndex++, rSrcCol );
+ }
+ }
+
+ if( pSrcAcc )
+ pSrc->ReleaseAccess( pSrcAcc );
+
+ if( pDstAcc )
+ ReleaseAccess( pDstAcc );
+ }
+ }
+
+ aRectSrc.Intersection( Rectangle( Point(), aCopySizePix ) );
+
+ if( !aRectSrc.IsEmpty() )
+ {
+ BitmapReadAccess* pReadAcc = pSrc->AcquireReadAccess();
+
+ if( pReadAcc )
+ {
+ BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const long nWidth = Min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
+ const long nHeight = Min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
+ const long nSrcEndX = aRectSrc.Left() + nWidth;
+ const long nSrcEndY = aRectSrc.Top() + nHeight;
+ long nDstY = aRectDst.Top();
+
+ if( pReadAcc->HasPalette() && pWriteAcc->HasPalette() )
+ {
+ const USHORT nCount = pReadAcc->GetPaletteEntryCount();
+ BYTE* pMap = new BYTE[ nCount ];
+
+ // Index-Map fuer Farbtabelle
+ // aufbauen, da das Bild ja (relativ) farbgenau
+ // kopiert werden soll
+ for( USHORT i = 0; i < nCount; i++ )
+ pMap[ i ] = (BYTE) pWriteAcc->GetBestPaletteIndex( pReadAcc->GetPaletteColor( i ) );
+
+ for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
+ for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
+ pWriteAcc->SetPixel( nDstY, nDstX, pMap[ pReadAcc->GetPixel( nSrcY, nSrcX ).GetIndex() ] );
+
+ delete[] pMap;
+ }
+ else if( pReadAcc->HasPalette() )
+ {
+ }
+ else
+ for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
+ for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
+ pWriteAcc->SetPixel( nDstY, nDstX, pReadAcc->GetPixel( nSrcY, nSrcX ) );
+
+ ReleaseAccess( pWriteAcc );
+ bRet = ( nWidth > 0L ) && ( nHeight > 0L );
+ }
+
+ pSrc->ReleaseAccess( pReadAcc );
+ }
+ }
+ }
+ else
+ {
+ Rectangle aRectSrc( rRectSrc );
+
+ aRectSrc.Intersection( Rectangle( Point(), aSizePix ) );
+
+ if( !aRectSrc.IsEmpty() && ( aRectSrc != aRectDst ) )
+ {
+ BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const long nWidth = Min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
+ const long nHeight = Min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
+ const long nSrcX = aRectSrc.Left();
+ const long nSrcY = aRectSrc.Top();
+ const long nSrcEndX1 = nSrcX + nWidth - 1L;
+ const long nSrcEndY1 = nSrcY + nHeight - 1L;
+ const long nDstX = aRectDst.Left();
+ const long nDstY = aRectDst.Top();
+ const long nDstEndX1 = nDstX + nWidth - 1L;
+ const long nDstEndY1 = nDstY + nHeight - 1L;
+
+ if( ( nDstX <= nSrcX ) && ( nDstY <= nSrcY ) )
+ {
+ for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
+ for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
+ pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
+ }
+ else if( ( nDstX <= nSrcX ) && ( nDstY >= nSrcY ) )
+ {
+ for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
+ for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
+ pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
+ }
+ else if( ( nDstX >= nSrcX ) && ( nDstY <= nSrcY ) )
+ {
+ for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
+ for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
+ pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
+ }
+ else
+ {
+ for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
+ for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
+ pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
+ }
+
+ ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Expand( ULONG nDX, ULONG nDY, const Color* pInitColor )
+{
+ BOOL bRet = FALSE;
+
+ if( nDX || nDY )
+ {
+ const Size aSizePixel( GetSizePixel() );
+ const long nWidth = aSizePixel.Width();
+ const long nHeight = aSizePixel.Height();
+ const Size aNewSize( nWidth + nDX, nHeight + nDY );
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+
+ if( pReadAcc )
+ {
+// Was soll den das ?
+// BitmapPalette aBmpPal( pReadAcc ? pReadAcc->GetPalette() : BitmapPalette() );
+ BitmapPalette aBmpPal( pReadAcc->GetPalette() );
+ Bitmap aNewBmp( aNewSize, GetBitCount(), &aBmpPal );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ BitmapColor aColor;
+ const ULONG nScanlineSize = pReadAcc->GetScanlineSize();
+ const long nNewX = nWidth;
+ const long nNewY = nHeight;
+ const long nNewWidth = pWriteAcc->Width();
+ const long nNewHeight = pWriteAcc->Height();
+ long nX;
+ long nY;
+
+ if( pInitColor )
+ aColor = pWriteAcc->GetBestMatchingColor( *pInitColor );
+
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ pWriteAcc->CopyScanline( nY, *pReadAcc );
+
+ if( pInitColor && nDX )
+ for( nX = nNewX; nX < nNewWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, aColor );
+ }
+
+ if( pInitColor && nDY )
+ for( nY = nNewY; nY < nNewHeight; nY++ )
+ for( nX = nNewX; nX < nNewWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, aColor );
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ ImplAssignWithSize( aNewBmp );
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+Bitmap Bitmap::CreateMask( const Color& rTransColor, ULONG nTol ) const
+{
+ Bitmap aNewBmp( GetSizePixel(), 1 );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pWriteAcc )
+ {
+ BitmapReadAccess* pReadAcc = ( (Bitmap*) this )->AcquireReadAccess();
+
+ if( pReadAcc )
+ {
+ const long nWidth = pReadAcc->Width();
+ const long nHeight = pReadAcc->Height();
+ const BitmapColor aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ if( !nTol )
+ {
+ const BitmapColor aTest( pReadAcc->GetBestMatchingColor( rTransColor ) );
+ long nX, nY, nShift;
+
+ if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_MSN_PAL ||
+ pReadAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_LSN_PAL )
+ {
+ // optimized for 4Bit-MSN/LSN source palette
+ const BYTE cTest = aTest.GetIndex();
+ const long nShiftInit = ( ( pReadAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_MSN_PAL ) ? 4 : 0 );
+
+ if( pWriteAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
+ aWhite.GetIndex() == 1 )
+ {
+ // optimized for 1Bit-MSB destination palette
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ Scanline pSrc = pReadAcc->GetScanline( nY );
+ Scanline pDst = pWriteAcc->GetScanline( nY );
+ for( nX = 0L, nShift = nShiftInit; nX < nWidth; nX++, nShift ^= 4 )
+ {
+ if( cTest == ( ( pSrc[ nX >> 1 ] >> nShift ) & 0x0f ) )
+ pDst[ nX >> 3 ] |= 1 << ( 7 - ( nX & 7 ) );
+ else
+ pDst[ nX >> 3 ] &= ~( 1 << ( 7 - ( nX & 7 ) ) );
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ Scanline pSrc = pReadAcc->GetScanline( nY );
+ for( nX = 0L, nShift = nShiftInit; nX < nWidth; nX++, nShift ^= 4 )
+ {
+ if( cTest == ( ( pSrc[ nX >> 1 ] >> nShift ) & 0x0f ) )
+ pWriteAcc->SetPixel( nY, nX, aWhite );
+ else
+ pWriteAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ }
+ }
+ else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ // optimized for 8Bit source palette
+ const BYTE cTest = aTest.GetIndex();
+
+ if( pWriteAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
+ aWhite.GetIndex() == 1 )
+ {
+ // optimized for 1Bit-MSB destination palette
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ Scanline pSrc = pReadAcc->GetScanline( nY );
+ Scanline pDst = pWriteAcc->GetScanline( nY );
+ for( nX = 0L; nX < nWidth; nX++ )
+ {
+ if( cTest == pSrc[ nX ] )
+ pDst[ nX >> 3 ] |= 1 << ( 7 - ( nX & 7 ) );
+ else
+ pDst[ nX >> 3 ] &= ~( 1 << ( 7 - ( nX & 7 ) ) );
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ Scanline pSrc = pReadAcc->GetScanline( nY );
+ for( nX = 0L; nX < nWidth; nX++ )
+ {
+ if( cTest == pSrc[ nX ] )
+ pWriteAcc->SetPixel( nY, nX, aWhite );
+ else
+ pWriteAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ }
+ }
+ else
+ {
+ // not optimized
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ for( nX = 0L; nX < nWidth; nX++ )
+ {
+ if( aTest == pReadAcc->GetPixel( nY, nX ) )
+ pWriteAcc->SetPixel( nY, nX, aWhite );
+ else
+ pWriteAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aCol;
+ long nR, nG, nB;
+ const long nMinR = MinMax( (long) rTransColor.GetRed() - nTol, 0, 255 );
+ const long nMaxR = MinMax( (long) rTransColor.GetRed() + nTol, 0, 255 );
+ const long nMinG = MinMax( (long) rTransColor.GetGreen() - nTol, 0, 255 );
+ const long nMaxG = MinMax( (long) rTransColor.GetGreen() + nTol, 0, 255 );
+ const long nMinB = MinMax( (long) rTransColor.GetBlue() - nTol, 0, 255 );
+ const long nMaxB = MinMax( (long) rTransColor.GetBlue() + nTol, 0, 255 );
+
+ if( pReadAcc->HasPalette() )
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aCol = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nX ) );
+ nR = aCol.GetRed();
+ nG = aCol.GetGreen();
+ nB = aCol.GetBlue();
+
+ if( nMinR <= nR && nMaxR >= nR &&
+ nMinG <= nG && nMaxG >= nG &&
+ nMinB <= nB && nMaxB >= nB )
+ {
+ pWriteAcc->SetPixel( nY, nX, aWhite );
+ }
+ else
+ pWriteAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ }
+ else
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aCol = pReadAcc->GetPixel( nY, nX );
+ nR = aCol.GetRed();
+ nG = aCol.GetGreen();
+ nB = aCol.GetBlue();
+
+ if( nMinR <= nR && nMaxR >= nR &&
+ nMinG <= nG && nMaxG >= nG &&
+ nMinB <= nB && nMaxB >= nB )
+ {
+ pWriteAcc->SetPixel( nY, nX, aWhite );
+ }
+ else
+ pWriteAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ }
+ }
+
+ ( (Bitmap*) this )->ReleaseAccess( pReadAcc );
+ bRet = TRUE;
+ }
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ }
+
+ if( bRet )
+ {
+ aNewBmp.maPrefSize = maPrefSize;
+ aNewBmp.maPrefMapMode = maPrefMapMode;
+ }
+ else
+ aNewBmp = Bitmap();
+
+ return aNewBmp;
+}
+
+// ------------------------------------------------------------------
+
+Region Bitmap::CreateRegion( const Color& rColor, const Rectangle& rRect ) const
+{
+ Region aRegion;
+ Rectangle aRect( rRect );
+ BitmapReadAccess* pReadAcc = ( (Bitmap*) this )->AcquireReadAccess();
+
+ aRect.Intersection( Rectangle( Point(), GetSizePixel() ) );
+ aRect.Justify();
+
+ if( pReadAcc )
+ {
+ Rectangle aSubRect;
+ const long nLeft = aRect.Left();
+ const long nTop = aRect.Top();
+ const long nRight = aRect.Right();
+ const long nBottom = aRect.Bottom();
+ const BitmapColor aMatch( pReadAcc->GetBestMatchingColor( rColor ) );
+
+ aRegion.ImplBeginAddRect();
+
+ for( long nY = nTop; nY <= nBottom; nY++ )
+ {
+ aSubRect.Top() = aSubRect.Bottom() = nY;
+
+ for( long nX = nLeft; nX <= nRight; )
+ {
+ while( ( nX <= nRight ) && ( aMatch != pReadAcc->GetPixel( nY, nX ) ) )
+ nX++;
+
+ if( nX <= nRight )
+ {
+ aSubRect.Left() = nX;
+
+ while( ( nX <= nRight ) && ( aMatch == pReadAcc->GetPixel( nY, nX ) ) )
+ nX++;
+
+ aSubRect.Right() = nX - 1L;
+ aRegion.ImplAddRect( aSubRect );
+ }
+ }
+ }
+
+ aRegion.ImplEndAddRect();
+ ( (Bitmap*) this )->ReleaseAccess( pReadAcc );
+ }
+ else
+ aRegion = aRect;
+
+ return aRegion;
+}
+
+//fuer WIN16 Borland
+#ifdef WIN
+#pragma codeseg BITMAP_SEG1
+#endif
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Replace( const Bitmap& rMask, const Color& rReplaceColor )
+{
+ BitmapReadAccess* pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pMaskAcc && pAcc )
+ {
+ const long nWidth = Min( pMaskAcc->Width(), pAcc->Width() );
+ const long nHeight = Min( pMaskAcc->Height(), pAcc->Height() );
+ const BitmapColor aMaskWhite( pMaskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ BitmapColor aReplace;
+
+ if( pAcc->HasPalette() )
+ {
+ const USHORT nActColors = pAcc->GetPaletteEntryCount();
+ const USHORT nMaxColors = 1 << pAcc->GetBitCount();
+
+ // erst einmal naechste Farbe nehmen
+ aReplace = pAcc->GetBestMatchingColor( rReplaceColor );
+
+ // falls Palettenbild, und die zu setzende Farbe ist nicht
+ // in der Palette, suchen wir nach freien Eintraegen (teuer)
+ if( pAcc->GetPaletteColor( (BYTE) aReplace ) != BitmapColor( rReplaceColor ) )
+ {
+ // erst einmal nachsehen, ob wir unsere ReplaceColor
+ // nicht auf einen freien Platz am Ende der Palette
+ // setzen koennen
+ if( nActColors < nMaxColors )
+ {
+ pAcc->SetPaletteEntryCount( nActColors + 1 );
+ pAcc->SetPaletteColor( nActColors, rReplaceColor );
+ aReplace = BitmapColor( (BYTE) nActColors );
+ }
+ else
+ {
+ BOOL* pFlags = new BOOL[ nMaxColors ];
+
+ // alle Eintraege auf 0 setzen
+ memset( pFlags, 0, nMaxColors );
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pFlags[ (BYTE) pAcc->GetPixel( nY, nX ) ] = TRUE;
+
+ for( USHORT i = 0UL; i < nMaxColors; i++ )
+ {
+ // Hurra, wir haben einen unbenutzten Eintrag
+ if( !pFlags[ i ] )
+ {
+ pAcc->SetPaletteColor( (USHORT) i, rReplaceColor );
+ aReplace = BitmapColor( (BYTE) i );
+ }
+ }
+
+ delete[] pFlags;
+ }
+ }
+ }
+ else
+ aReplace = rReplaceColor;
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX = 0L; nX < nWidth; nX++ )
+ if( pMaskAcc->GetPixel( nY, nX ) == aMaskWhite )
+ pAcc->SetPixel( nY, nX, aReplace );
+ }
+
+ ( (Bitmap&) rMask ).ReleaseAccess( pMaskAcc );
+ ReleaseAccess( pAcc );
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Replace( const AlphaMask& rAlpha, const Color& rMergeColor )
+{
+ Bitmap aNewBmp( GetSizePixel(), 24 );
+ BitmapReadAccess* pAcc = AcquireReadAccess();
+ BitmapReadAccess* pAlphaAcc = ( (AlphaMask&) rAlpha ).AcquireReadAccess();
+ BitmapWriteAccess* pNewAcc = aNewBmp.AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pAcc && pAlphaAcc && pNewAcc )
+ {
+ BitmapColor aCol;
+ const long nWidth = Min( pAlphaAcc->Width(), pAcc->Width() );
+ const long nHeight = Min( pAlphaAcc->Height(), pAcc->Height() );
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aCol = pAcc->GetColor( nY, nX );
+ pNewAcc->SetPixel( nY, nX, aCol.Merge( rMergeColor, 255 - (BYTE) pAlphaAcc->GetPixel( nY, nX ) ) );
+ }
+ }
+
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pAcc );
+ ( (AlphaMask&) rAlpha ).ReleaseAccess( pAlphaAcc );
+ aNewBmp.ReleaseAccess( pNewAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Replace( const Color& rSearchColor, const Color& rReplaceColor, ULONG nTol )
+{
+ // Bitmaps with 1 bit color depth can cause problems
+ // if they have other entries than black/white in their palette
+ if( 1 == GetBitCount() )
+ Convert( BMP_CONVERSION_4BIT_COLORS );
+
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pAcc )
+ {
+ const long nMinR = MinMax( (long) rSearchColor.GetRed() - nTol, 0, 255 );
+ const long nMaxR = MinMax( (long) rSearchColor.GetRed() + nTol, 0, 255 );
+ const long nMinG = MinMax( (long) rSearchColor.GetGreen() - nTol, 0, 255 );
+ const long nMaxG = MinMax( (long) rSearchColor.GetGreen() + nTol, 0, 255 );
+ const long nMinB = MinMax( (long) rSearchColor.GetBlue() - nTol, 0, 255 );
+ const long nMaxB = MinMax( (long) rSearchColor.GetBlue() + nTol, 0, 255 );
+
+ if( pAcc->HasPalette() )
+ {
+ for( USHORT i = 0, nPalCount = pAcc->GetPaletteEntryCount(); i < nPalCount; i++ )
+ {
+ const BitmapColor& rCol = pAcc->GetPaletteColor( i );
+
+ if( nMinR <= rCol.GetRed() && nMaxR >= rCol.GetRed() &&
+ nMinG <= rCol.GetGreen() && nMaxG >= rCol.GetGreen() &&
+ nMinB <= rCol.GetBlue() && nMaxB >= rCol.GetBlue() )
+ {
+ pAcc->SetPaletteColor( i, rReplaceColor );
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aCol;
+ const BitmapColor aReplace( pAcc->GetBestMatchingColor( rReplaceColor ) );
+
+ for( long nY = 0L, nHeight = pAcc->Height(); nY < nHeight; nY++ )
+ {
+ for( long nX = 0L, nWidth = pAcc->Width(); nX < nWidth; nX++ )
+ {
+ aCol = pAcc->GetPixel( nY, nX );
+
+ if( nMinR <= aCol.GetRed() && nMaxR >= aCol.GetRed() &&
+ nMinG <= aCol.GetGreen() && nMaxG >= aCol.GetGreen() &&
+ nMinB <= aCol.GetBlue() && nMaxB >= aCol.GetBlue() )
+ {
+ pAcc->SetPixel( nY, nX, aReplace );
+ }
+ }
+ }
+ }
+
+ ReleaseAccess( pAcc );
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Replace( const Color* pSearchColors, const Color* pReplaceColors,
+ ULONG nColorCount, ULONG* _pTols )
+{
+ // Bitmaps with 1 bit color depth can cause problems
+ // if they have other entries than black/white in their palette
+ if( 1 == GetBitCount() )
+ Convert( BMP_CONVERSION_4BIT_COLORS );
+
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pAcc )
+ {
+ long* pMinR = new long[ nColorCount ];
+ long* pMaxR = new long[ nColorCount ];
+ long* pMinG = new long[ nColorCount ];
+ long* pMaxG = new long[ nColorCount ];
+ long* pMinB = new long[ nColorCount ];
+ long* pMaxB = new long[ nColorCount ];
+ long* pTols;
+ ULONG i;
+
+ if( !_pTols )
+ {
+ pTols = new long[ nColorCount ];
+ memset( pTols, 0, nColorCount * sizeof( long ) );
+ }
+ else
+ pTols = (long*) _pTols;
+
+ for( i = 0UL; i < nColorCount; i++ )
+ {
+ const Color& rCol = pSearchColors[ i ];
+ const long nTol = pTols[ i ];
+
+ pMinR[ i ] = MinMax( (long) rCol.GetRed() - nTol, 0, 255 );
+ pMaxR[ i ] = MinMax( (long) rCol.GetRed() + nTol, 0, 255 );
+ pMinG[ i ] = MinMax( (long) rCol.GetGreen() - nTol, 0, 255 );
+ pMaxG[ i ] = MinMax( (long) rCol.GetGreen() + nTol, 0, 255 );
+ pMinB[ i ] = MinMax( (long) rCol.GetBlue() - nTol, 0, 255 );
+ pMaxB[ i ] = MinMax( (long) rCol.GetBlue() + nTol, 0, 255 );
+ }
+
+ if( pAcc->HasPalette() )
+ {
+ for( USHORT nEntry = 0, nPalCount = pAcc->GetPaletteEntryCount(); nEntry < nPalCount; nEntry++ )
+ {
+ const BitmapColor& rCol = pAcc->GetPaletteColor( nEntry );
+
+ for( i = 0UL; i < nColorCount; i++ )
+ {
+ if( pMinR[ i ] <= rCol.GetRed() && pMaxR[ i ] >= rCol.GetRed() &&
+ pMinG[ i ] <= rCol.GetGreen() && pMaxG[ i ] >= rCol.GetGreen() &&
+ pMinB[ i ] <= rCol.GetBlue() && pMaxB[ i ] >= rCol.GetBlue() )
+ {
+ pAcc->SetPaletteColor( (USHORT)nEntry, pReplaceColors[ i ] );
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aCol;
+ BitmapColor* pReplaces = new BitmapColor[ nColorCount ];
+
+ for( i = 0UL; i < nColorCount; i++ )
+ pReplaces[ i ] = pAcc->GetBestMatchingColor( pReplaceColors[ i ] );
+
+ for( long nY = 0L, nHeight = pAcc->Height(); nY < nHeight; nY++ )
+ {
+ for( long nX = 0L, nWidth = pAcc->Width(); nX < nWidth; nX++ )
+ {
+ aCol = pAcc->GetPixel( nY, nX );
+
+ for( i = 0UL; i < nColorCount; i++ )
+ {
+ if( pMinR[ i ] <= aCol.GetRed() && pMaxR[ i ] >= aCol.GetRed() &&
+ pMinG[ i ] <= aCol.GetGreen() && pMaxG[ i ] >= aCol.GetGreen() &&
+ pMinB[ i ] <= aCol.GetBlue() && pMaxB[ i ] >= aCol.GetBlue() )
+ {
+ pAcc->SetPixel( nY, nX, pReplaces[ i ] );
+ break;
+ }
+ }
+ }
+ }
+
+ delete[] pReplaces;
+ }
+
+ if( !_pTols )
+ delete[] pTols;
+
+ delete[] pMinR;
+ delete[] pMaxR;
+ delete[] pMinG;
+ delete[] pMaxG;
+ delete[] pMinB;
+ delete[] pMaxB;
+ ReleaseAccess( pAcc );
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+Bitmap Bitmap::CreateDisplayBitmap( OutputDevice* pDisplay )
+{
+ Bitmap aDispBmp( *this );
+
+#ifndef REMOTE_APPSERVER
+ if( mpImpBmp && ( pDisplay->mpGraphics || pDisplay->ImplGetGraphics() ) )
+ {
+ ImpBitmap* pImpDispBmp = new ImpBitmap;
+
+ if( pImpDispBmp->ImplCreate( *mpImpBmp, pDisplay->mpGraphics ) )
+ aDispBmp.ImplSetImpBitmap( pImpDispBmp );
+ else
+ delete pImpDispBmp;
+ }
+#endif
+
+ return aDispBmp;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::CombineSimple( const Bitmap& rMask, BmpCombine eCombine )
+{
+ BitmapReadAccess* pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pMaskAcc && pAcc )
+ {
+ const long nWidth = Min( pMaskAcc->Width(), pAcc->Width() );
+ const long nHeight = Min( pMaskAcc->Height(), pAcc->Height() );
+ const Color aColBlack( COL_BLACK );
+ BitmapColor aPixel;
+ BitmapColor aMaskPixel;
+ const BitmapColor aWhite( pAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ const BitmapColor aBlack( pAcc->GetBestMatchingColor( aColBlack ) );
+ const BitmapColor aMaskBlack( pMaskAcc->GetBestMatchingColor( aColBlack ) );
+
+ switch( eCombine )
+ {
+ case( BMP_COMBINE_COPY ):
+ {
+ for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pMaskAcc->GetPixel( nY, nX ) == aMaskBlack )
+ pAcc->SetPixel( nY, nX, aBlack );
+ else
+ pAcc->SetPixel( nY, nX, aWhite );
+ }
+ }
+ break;
+
+ case( BMP_COMBINE_INVERT ):
+ {
+ for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pAcc->GetPixel( nY, nX ) == aBlack )
+ pAcc->SetPixel( nY, nX, aWhite );
+ else
+ pAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ break;
+
+ case( BMP_COMBINE_AND ):
+ {
+ for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack && pAcc->GetPixel( nY, nX ) != aBlack )
+ pAcc->SetPixel( nY, nX, aWhite );
+ else
+ pAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ break;
+
+ case( BMP_COMBINE_NAND ):
+ {
+ for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack && pAcc->GetPixel( nY, nX ) != aBlack )
+ pAcc->SetPixel( nY, nX, aBlack );
+ else
+ pAcc->SetPixel( nY, nX, aWhite );
+ }
+ }
+ break;
+
+ case( BMP_COMBINE_OR ):
+ {
+ for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack || pAcc->GetPixel( nY, nX ) != aBlack )
+ pAcc->SetPixel( nY, nX, aWhite );
+ else
+ pAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ break;
+
+ case( BMP_COMBINE_NOR ):
+ {
+ for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack || pAcc->GetPixel( nY, nX ) != aBlack )
+ pAcc->SetPixel( nY, nX, aBlack );
+ else
+ pAcc->SetPixel( nY, nX, aWhite );
+ }
+ }
+ break;
+
+ case( BMP_COMBINE_XOR ):
+ {
+ for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aPixel = pAcc->GetPixel( nY, nX );
+ aMaskPixel = pMaskAcc->GetPixel( nY, nX );
+
+ if( ( aMaskPixel != aMaskBlack && aPixel == aBlack ) ||
+ ( aMaskPixel == aMaskBlack && aPixel != aBlack ) )
+ {
+ pAcc->SetPixel( nY, nX, aWhite );
+ }
+ else
+ pAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ break;
+
+ case( BMP_COMBINE_NXOR ):
+ {
+ for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aPixel = pAcc->GetPixel( nY, nX );
+ aMaskPixel = pMaskAcc->GetPixel( nY, nX );
+
+ if( ( aMaskPixel != aMaskBlack && aPixel == aBlack ) ||
+ ( aMaskPixel == aMaskBlack && aPixel != aBlack ) )
+ {
+ pAcc->SetPixel( nY, nX, aBlack );
+ }
+ else
+ pAcc->SetPixel( nY, nX, aWhite );
+ }
+ }
+ break;
+ }
+ }
+
+ ( (Bitmap&) rMask ).ReleaseAccess( pMaskAcc );
+ ReleaseAccess( pAcc );
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+#ifdef REMOTE_APPSERVER
+
+void Bitmap::ImplDrawRemote( OutputDevice* pOut,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Point& rDestPt, const Size& rDestSz ) const
+{
+ if( mpImpBmp )
+ {
+ if( !mpImpBmp->ImplGetRemoteBmp() )
+ mpImpBmp->ImplCreateRemoteBmp( *this );
+
+ mpImpBmp->ImplDrawRemoteBmp( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz );
+ }
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ImplDrawRemoteEx( OutputDevice* pOut,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Point& rDestPt, const Size& rDestSz,
+ const Bitmap& rMask ) const
+{
+ if( mpImpBmp )
+ {
+ if( !mpImpBmp->ImplGetRemoteBmp() )
+ mpImpBmp->ImplCreateRemoteBmp( *this );
+
+ mpImpBmp->ImplDrawRemoteBmpEx( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz, rMask );
+ }
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ImplDrawRemoteAlpha( OutputDevice* pOut,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Point& rDestPt, const Size& rDestSz,
+ const AlphaMask& rAlpha ) const
+{
+ if( mpImpBmp )
+ {
+ if( !mpImpBmp->ImplGetRemoteBmp() )
+ mpImpBmp->ImplCreateRemoteBmp( *this );
+
+ mpImpBmp->ImplDrawRemoteBmpAlpha( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz, rAlpha );
+ }
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ImplDrawRemoteMask( OutputDevice* pOut,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Point& rDestPt, const Size& rDestSz,
+ const Color& rColor ) const
+{
+ if( mpImpBmp )
+ {
+ if( !mpImpBmp->ImplGetRemoteBmp() )
+ mpImpBmp->ImplCreateRemoteBmp( *this );
+
+ mpImpBmp->ImplDrawRemoteBmpMask( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz, rColor );
+ }
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ImplGetRemoteBmp( OutputDevice* pOut, const Point& rPt, const Size& rSz )
+{
+ DBG_ASSERT( !mpImpBmp, "Bitmap::ImplGetRemoteBmp???" );
+
+ mpImpBmp = new ImpBitmap;
+ mpImpBmp->ImplCreateRemoteBmp( *this, pOut, rPt, rSz );
+}
+
+#endif
diff --git a/vcl/source/gdi/bitmap2.cxx b/vcl/source/gdi/bitmap2.cxx
new file mode 100644
index 000000000000..e4e4c407fc18
--- /dev/null
+++ b/vcl/source/gdi/bitmap2.cxx
@@ -0,0 +1,1269 @@
+/*************************************************************************
+ *
+ * $RCSfile: bitmap2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef WIN
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#endif
+
+#define _SV_BITMAP_CXX
+
+#include <tools/zcodec.hxx>
+#ifndef _TOOLS_NEW_HXX
+#include <tools/new.hxx>
+#endif
+#ifndef _TOOLS_STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+
+#define USE_ZCODEC
+
+// -----------
+// - Defines -
+// -----------
+
+#define DIBCOREHEADERSIZE ( 12UL )
+#define DIBINFOHEADERSIZE ( sizeof( DIBInfoHeader ) )
+#define SETPIXEL4( pBuf, nX, cChar )( (pBuf)[ (nX) >> 1 ] |= ( (nX) & 1 ) ? ( cChar ): (cChar) << 4 );
+
+// ----------------------
+// - Compression defines
+// ----------------------
+
+#define COMPRESS_OWN ('S'|('D'<<8UL))
+#define COMPRESS_NONE ( 0UL )
+#define RLE_8 ( 1UL )
+#define RLE_4 ( 2UL )
+#define BITFIELDS ( 3UL )
+#define ZCOMPRESS ( COMPRESS_OWN | 0x01000000UL ) /* == 'SD01' (binary) */
+
+// -----------------
+// - DIBInfoHeader -
+// -----------------
+
+struct DIBInfoHeader
+{
+ UINT32 nSize;
+ UINT32 nWidth;
+ UINT32 nHeight;
+ UINT16 nPlanes;
+ UINT16 nBitCount;
+ UINT32 nCompression;
+ UINT32 nSizeImage;
+ UINT32 nXPelsPerMeter;
+ UINT32 nYPelsPerMeter;
+ UINT32 nColsUsed;
+ UINT32 nColsImportant;
+
+ DIBInfoHeader() :
+ nSize( 0UL ),
+ nWidth( 0UL ),
+ nHeight( 0UL ),
+ nPlanes( 0 ),
+ nBitCount( 0 ),
+ nCompression( 0UL ),
+ nSizeImage( 0UL ),
+ nXPelsPerMeter( 0UL ),
+ nYPelsPerMeter( 0UL ),
+ nColsUsed( 0UL ),
+ nColsImportant( 0UL ) {}
+
+ ~DIBInfoHeader() {}
+};
+
+// ----------
+// - Bitmap -
+// ----------
+
+SvStream& operator>>( SvStream& rIStm, Bitmap& rBitmap )
+{
+ rBitmap.Read( rIStm, TRUE );
+ return rIStm;
+}
+
+// ------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const Bitmap& rBitmap )
+{
+ rBitmap.Write( rOStm, FALSE, TRUE );
+ return rOStm;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Read( SvStream& rIStm, BOOL bFileHeader )
+{
+ const USHORT nOldFormat = rIStm.GetNumberFormatInt();
+ const ULONG nOldPos = rIStm.Tell();
+ ULONG nOffset = 0UL;
+ BOOL bRet = FALSE;
+
+ rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ if( bFileHeader )
+ {
+ if( ImplReadDIBFileHeader( rIStm, nOffset ) )
+ bRet = ImplReadDIB( rIStm, *this, nOffset );
+ }
+ else
+ bRet = ImplReadDIB( rIStm, *this, nOffset );
+
+ if( !bRet )
+ {
+ if( !rIStm.GetError() )
+ rIStm.SetError( SVSTREAM_GENERALERROR );
+
+ rIStm.Seek( nOldPos );
+ }
+
+ rIStm.SetNumberFormatInt( nOldFormat );
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplReadDIB( SvStream& rIStm, Bitmap& rBmp, ULONG nOffset )
+{
+ DIBInfoHeader aHeader;
+ const ULONG nStmPos = rIStm.Tell();
+ BitmapPalette* pPalette = NULL;
+ BOOL bHeaderRead = FALSE;
+ BOOL bRet = FALSE;
+
+ if( ImplReadDIBInfoHeader( rIStm, aHeader ) && aHeader.nWidth && aHeader.nHeight && aHeader.nBitCount )
+ {
+ USHORT nBitCount = ( aHeader.nBitCount <= 1 ) ? 1 :
+ ( aHeader.nBitCount <= 4 ) ? 4 :
+ ( aHeader.nBitCount <= 8 ) ? 8 : 24;
+
+ const Size aSizePixel( aHeader.nWidth, aHeader.nHeight );
+ BitmapPalette aDummyPal;
+ Bitmap aNewBmp( aSizePixel, nBitCount, &aDummyPal );
+ BitmapWriteAccess* pAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pAcc )
+ {
+ USHORT nColors;
+ SvStream* pIStm;
+ SvMemoryStream* pMemStm = NULL;
+ BYTE* pData = NULL;
+
+ if( nBitCount <= 8 )
+ {
+ if( aHeader.nColsUsed )
+ nColors = (USHORT) aHeader.nColsUsed;
+ else
+ nColors = ( 1 << aHeader.nBitCount );
+ }
+ else
+ nColors = 0;
+
+#ifdef USE_ZCODEC
+ if( ZCOMPRESS == aHeader.nCompression )
+ {
+ ZCodec aCodec;
+ ULONG nCodedSize, nUncodedSize;
+ ULONG nCodedPos;
+
+ // read coding information
+ rIStm >> nCodedSize >> nUncodedSize >> aHeader.nCompression;
+ pData = (BYTE*) SvMemAlloc( nUncodedSize );
+
+ // decode buffer
+ nCodedPos = rIStm.Tell();
+ aCodec.BeginCompression();
+ aCodec.Read( rIStm, pData, nUncodedSize );
+ aCodec.EndCompression();
+
+ // skip unread bytes from coded buffer
+ rIStm.SeekRel( nCodedSize - ( rIStm.Tell() - nCodedPos ) );
+
+ // set decoded bytes to memory stream,
+ // from which we will read the bitmap data
+ pIStm = pMemStm = new SvMemoryStream;
+ pMemStm->SetBuffer( (char*) pData, nUncodedSize, FALSE, nUncodedSize );
+ nOffset = 0;
+ }
+ else
+#endif // USE_ZCODEC
+ pIStm = &rIStm;
+
+ // read palette
+ if( nColors )
+ {
+ pAcc->SetPaletteEntryCount( nColors );
+ ImplReadDIBPalette( *pIStm, *pAcc, aHeader.nSize != DIBCOREHEADERSIZE );
+ }
+
+ // read bits
+ if( !pIStm->GetError() )
+ {
+ if( nOffset )
+ pIStm->SeekRel( nOffset - ( pIStm->Tell() - nStmPos ) );
+
+ bRet = ImplReadDIBBits( *pIStm, aHeader, *pAcc );
+
+ if( bRet && aHeader.nXPelsPerMeter && aHeader.nYPelsPerMeter )
+ {
+ MapMode aMapMode( MAP_MM, Point(),
+ Fraction( 1000, aHeader.nXPelsPerMeter ),
+ Fraction( 1000, aHeader.nYPelsPerMeter ) );
+
+ aNewBmp.SetPrefMapMode( aMapMode );
+ aNewBmp.SetPrefSize( Size( aHeader.nWidth, aHeader.nHeight ) );
+ }
+ }
+
+ if( pData )
+ SvMemFree( pData );
+
+ delete pMemStm;
+ aNewBmp.ReleaseAccess( pAcc );
+
+ if( bRet )
+ rBmp = aNewBmp;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplReadDIBFileHeader( SvStream& rIStm, ULONG& rOffset )
+{
+ UINT32 nTmp32;
+ UINT16 nTmp16;
+ BOOL bRet = FALSE;
+
+ rIStm >> nTmp16;
+
+ if ( ( 0x4D42 == nTmp16 ) || ( 0x4142 == nTmp16 ) )
+ {
+ if ( 0x4142 == nTmp16 )
+ {
+ rIStm.SeekRel( 12L );
+ rIStm >> nTmp16;
+ rIStm.SeekRel( 8L );
+ rIStm >> nTmp32;
+ rOffset = nTmp32 - 28UL;;
+ bRet = ( 0x4D42 == nTmp16 );
+ }
+ else
+ {
+ rIStm.SeekRel( 8L );
+ rIStm >> nTmp32;
+ rOffset = nTmp32 - 14UL;
+ bRet = ( rIStm.GetError() == 0UL );
+ }
+ }
+ else
+ rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplReadDIBInfoHeader( SvStream& rIStm, DIBInfoHeader& rHeader )
+{
+ // BITMAPINFOHEADER or BITMAPCOREHEADER
+ rIStm >> rHeader.nSize;
+
+ // BITMAPCOREHEADER
+ if ( rHeader.nSize == DIBCOREHEADERSIZE )
+ {
+ UINT16 nTmp16;
+
+ rIStm >> nTmp16; rHeader.nWidth = nTmp16;
+ rIStm >> nTmp16; rHeader.nHeight = nTmp16;
+ rIStm >> nTmp16; rHeader.nPlanes = nTmp16;
+ rIStm >> nTmp16; rHeader.nBitCount = nTmp16;
+ }
+ else
+ {
+ // unknown Header
+ if( rHeader.nSize < DIBINFOHEADERSIZE )
+ {
+ ULONG nUnknownSize = sizeof( rHeader.nSize );
+
+ rIStm >> rHeader.nWidth; nUnknownSize += sizeof( rHeader.nWidth );
+ rIStm >> rHeader.nHeight; nUnknownSize += sizeof( rHeader.nHeight );
+ rIStm >> rHeader.nPlanes; nUnknownSize += sizeof( rHeader.nPlanes );
+ rIStm >> rHeader.nBitCount; nUnknownSize += sizeof( rHeader.nBitCount );
+
+ if( nUnknownSize < rHeader.nSize )
+ {
+ rIStm >> rHeader.nCompression;
+ nUnknownSize += sizeof( rHeader.nCompression );
+
+ if( nUnknownSize < rHeader.nSize )
+ {
+ rIStm >> rHeader.nSizeImage;
+ nUnknownSize += sizeof( rHeader.nSizeImage );
+
+ if( nUnknownSize < rHeader.nSize )
+ {
+ rIStm >> rHeader.nXPelsPerMeter;
+ nUnknownSize += sizeof( rHeader.nXPelsPerMeter );
+
+ if( nUnknownSize < rHeader.nSize )
+ {
+ rIStm >> rHeader.nYPelsPerMeter;
+ nUnknownSize += sizeof( rHeader.nYPelsPerMeter );
+ }
+
+ if( nUnknownSize < rHeader.nSize )
+ {
+ rIStm >> rHeader.nColsUsed;
+ nUnknownSize += sizeof( rHeader.nColsUsed );
+
+ if( nUnknownSize < rHeader.nSize )
+ {
+ rIStm >> rHeader.nColsImportant;
+ nUnknownSize += sizeof( rHeader.nColsImportant );
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ rIStm >> rHeader.nWidth;
+ rIStm >> rHeader.nHeight;
+ rIStm >> rHeader.nPlanes;
+ rIStm >> rHeader.nBitCount;
+ rIStm >> rHeader.nCompression;
+ rIStm >> rHeader.nSizeImage;
+ rIStm >> rHeader.nXPelsPerMeter;
+ rIStm >> rHeader.nYPelsPerMeter;
+ rIStm >> rHeader.nColsUsed;
+ rIStm >> rHeader.nColsImportant;
+ }
+
+ // Eventuell bis zur Palette ueberlesen
+ if ( rHeader.nSize > DIBINFOHEADERSIZE )
+ rIStm.SeekRel( rHeader.nSize - DIBINFOHEADERSIZE );
+ }
+
+ return( ( rHeader.nPlanes == 1 ) && ( rIStm.GetError() == 0UL ) );
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, BOOL bQuad )
+{
+ const USHORT nColors = rAcc.GetPaletteEntryCount();
+ const ULONG nPalSize = nColors * ( bQuad ? 4UL : 3UL );
+ BitmapColor aPalColor;
+
+ BYTE* pEntries = new BYTE[ nPalSize ];
+ rIStm.Read( pEntries, nPalSize );
+
+ BYTE* pTmpEntry = pEntries;
+ for( USHORT i = 0; i < nColors; i++ )
+ {
+ aPalColor.SetBlue( *pTmpEntry++ );
+ aPalColor.SetGreen( *pTmpEntry++ );
+ aPalColor.SetRed( *pTmpEntry++ );
+
+ if( bQuad )
+ pTmpEntry++;
+
+ rAcc.SetPaletteColor( i, aPalColor );
+ }
+
+ delete[] pEntries;
+
+ return( rIStm.GetError() == 0UL );
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplReadDIBBits( SvStream& rIStm, DIBInfoHeader& rHeader, BitmapWriteAccess& rAcc )
+{
+ const ULONG nAlignedWidth = AlignedWidth4Bytes( rHeader.nWidth * rHeader.nBitCount );
+ UINT32 nRMask;
+ UINT32 nGMask;
+ UINT32 nBMask;
+ BOOL bNative;
+ BOOL bTCMask = ( rHeader.nBitCount == 16 ) || ( rHeader.nBitCount == 32 );
+ BOOL bRLE = ( RLE_8 == rHeader.nCompression && rHeader.nBitCount == 8 ) ||
+ ( RLE_4 == rHeader.nCompression && rHeader.nBitCount == 4 );
+
+ // Is native format?
+ switch( rAcc.GetScanlineFormat() )
+ {
+ case( BMP_FORMAT_1BIT_MSB_PAL ):
+ case( BMP_FORMAT_4BIT_MSN_PAL ):
+ case( BMP_FORMAT_8BIT_PAL ):
+ case( BMP_FORMAT_24BIT_TC_BGR ):
+ bNative = ( rAcc.IsBottomUp() && !bRLE && !bTCMask && ( rAcc.GetScanlineSize() == nAlignedWidth ) );
+ break;
+
+ default:
+ bNative = FALSE;
+ break;
+ }
+
+ // Read data
+ if( bNative )
+ {
+ // true color DIB's can have a (optimization) palette
+ if( rHeader.nColsUsed && rHeader.nBitCount > 8 )
+ rIStm.SeekRel( rHeader.nColsUsed * ( ( rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3 ) );
+
+ rIStm.Read( rAcc.GetBuffer(), rHeader.nHeight * nAlignedWidth );
+ }
+ else
+ {
+ // Read color mask
+ if( bTCMask )
+ {
+ if( rHeader.nCompression == BITFIELDS )
+ {
+ rIStm.SeekRel( -12L );
+ rIStm >> nRMask;
+ rIStm >> nGMask;
+ rIStm >> nBMask;
+ }
+ else
+ {
+ nRMask = ( rHeader.nBitCount == 16 ) ? 0x00007c00UL : 0x00ff0000UL;
+ nGMask = ( rHeader.nBitCount == 16 ) ? 0x000003e0UL : 0x0000ff00UL;
+ nBMask = ( rHeader.nBitCount == 16 ) ? 0x0000001fUL : 0x000000ffUL;
+ }
+ }
+
+ if( bRLE )
+ {
+ if ( !rHeader.nSizeImage )
+ {
+ const ULONG nOldPos = rIStm.Tell();
+
+ rIStm.Seek( STREAM_SEEK_TO_END );
+ rHeader.nSizeImage = rIStm.Tell() - nOldPos;
+ rIStm.Seek( nOldPos );
+ }
+
+ BYTE* pBuffer = (BYTE*) SvMemAlloc( rHeader.nSizeImage );
+
+ rIStm.Read( (char*) pBuffer, rHeader.nSizeImage );
+ ImplDecodeRLE( pBuffer, rHeader, rAcc, RLE_4 == rHeader.nCompression );
+
+ SvMemFree( pBuffer );
+ }
+ else
+ {
+ const long nWidth = rHeader.nWidth;
+ const long nHeight = rHeader.nHeight;
+ BYTE* pBuf = new BYTE[ nAlignedWidth ];
+
+ // true color DIB's can have a (optimization) palette
+ if( rHeader.nColsUsed && rHeader.nBitCount > 8 )
+ rIStm.SeekRel( rHeader.nColsUsed * ( ( rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3 ) );
+
+ switch( rHeader.nBitCount )
+ {
+ case( 1 ):
+ {
+ BYTE* pTmp;
+ BYTE cTmp;
+
+ for( long nY = nHeight - 1; nY >= 0L; nY-- )
+ {
+ rIStm.Read( pTmp = pBuf, nAlignedWidth );
+ cTmp = *pTmp++;
+
+ for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ )
+ {
+ if( !nShift )
+ {
+ nShift = 8L,
+ cTmp = *pTmp++;
+ }
+
+ rAcc.SetPixel( nY, nX, ( cTmp >> --nShift ) & 1 );
+ }
+ }
+ }
+ break;
+
+ case( 4 ):
+ {
+ BYTE* pTmp;
+ BYTE cTmp;
+
+ for( long nY = nHeight - 1; nY >= 0L; nY-- )
+ {
+ rIStm.Read( pTmp = pBuf, nAlignedWidth );
+ cTmp = *pTmp++;
+
+ for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ )
+ {
+ if( !nShift )
+ {
+ nShift = 2UL,
+ cTmp = *pTmp++;
+ }
+
+ rAcc.SetPixel( nY, nX, ( cTmp >> ( --nShift << 2UL ) ) & 0x0f );
+ }
+ }
+ }
+ break;
+
+ case( 8 ):
+ {
+ BYTE* pTmp;
+
+ for( long nY = nHeight - 1; nY >= 0L; nY-- )
+ {
+ rIStm.Read( pTmp = pBuf, nAlignedWidth );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ rAcc.SetPixel( nY, nX, *pTmp++ );
+ }
+ }
+ break;
+
+ case( 16 ):
+ {
+ ColorMask aMask( nRMask, nGMask, nBMask );
+ BitmapColor aColor;
+ UINT16* pTmp16;
+
+ for( long nY = rHeader.nHeight - 1L; nY >= 0L; nY-- )
+ {
+ rIStm.Read( (char*)( pTmp16 = (UINT16*) pBuf ), nAlignedWidth );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aMask.GetColorFor16Bit( aColor, (BYTE*) pTmp16++ );
+ rAcc.SetPixel( nY, nX, aColor );
+ }
+ }
+ }
+ break;
+
+ case( 24 ):
+ {
+ BitmapColor aPixelColor;
+ BYTE* pTmp;
+
+ for( long nY = nHeight - 1; nY >= 0L; nY-- )
+ {
+ rIStm.Read( pTmp = pBuf, nAlignedWidth );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aPixelColor.SetBlue( *pTmp++ );
+ aPixelColor.SetGreen( *pTmp++ );
+ aPixelColor.SetRed( *pTmp++ );
+ rAcc.SetPixel( nY, nX, aPixelColor );
+ }
+ }
+ }
+ break;
+
+ case( 32 ):
+ {
+ ColorMask aMask( nRMask, nGMask, nBMask );
+ BitmapColor aColor;
+ UINT32* pTmp32;
+
+ for( long nY = rHeader.nHeight - 1L; nY >= 0L; nY-- )
+ {
+ rIStm.Read( (char*)( pTmp32 = (UINT32*) pBuf ), nAlignedWidth );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aMask.GetColorFor32Bit( aColor, (BYTE*) pTmp32++ );
+ rAcc.SetPixel( nY, nX, aColor );
+ }
+ }
+ }
+ }
+
+ delete[] pBuf;
+ }
+ }
+
+ return( rIStm.GetError() == 0UL );
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::Write( SvStream& rOStm, BOOL bCompressed, BOOL bFileHeader ) const
+{
+ BMP_ASSERT( mpImpBmp, "Empty Bitmaps can't be saved" );
+
+ const Size aSizePix( GetSizePixel() );
+ BOOL bRet = FALSE;
+
+ if( mpImpBmp && aSizePix.Width() && aSizePix.Height() )
+ {
+ BitmapReadAccess* pAcc = ( (Bitmap*) this)->AcquireReadAccess();
+ const USHORT nOldFormat = rOStm.GetNumberFormatInt();
+ const ULONG nOldPos = rOStm.Tell();
+
+ rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ if( pAcc )
+ {
+ if( bFileHeader )
+ {
+ if( ImplWriteDIBFileHeader( rOStm, *pAcc ) )
+ bRet = ImplWriteDIB( rOStm, *pAcc, bCompressed );
+ }
+ else
+ bRet = ImplWriteDIB( rOStm, *pAcc, bCompressed );
+
+ ( (Bitmap*) this)->ReleaseAccess( pAcc );
+ }
+
+ if( !bRet )
+ {
+ rOStm.SetError( SVSTREAM_GENERALERROR );
+ rOStm.Seek( nOldPos );
+ }
+
+ rOStm.SetNumberFormatInt( nOldFormat );
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplWriteDIB( SvStream& rOStm, BitmapReadAccess& rAcc, BOOL bCompressed ) const
+{
+ DIBInfoHeader aHeader;
+ ULONG nImageSizePos;
+ ULONG nEndPos;
+ ULONG nCompression = 0UL;
+ BOOL bRet = FALSE;
+
+ aHeader.nSize = DIBINFOHEADERSIZE;
+ aHeader.nWidth = rAcc.Width();
+ aHeader.nHeight = rAcc.Height();
+ aHeader.nPlanes = 1;
+
+ switch( rAcc.GetScanlineFormat() )
+ {
+ case( BMP_FORMAT_16BIT_TC_MASK ):
+ case( BMP_FORMAT_32BIT_TC_MASK ):
+ {
+ aHeader.nBitCount = ( rAcc.GetScanlineFormat() == BMP_FORMAT_16BIT_TC_MASK ) ? 16 : 32;
+ nCompression = BITFIELDS;
+ }
+ break;
+
+ default:
+ {
+ aHeader.nBitCount = rAcc.GetBitCount();
+
+ if( bCompressed )
+ {
+ if( 4 == aHeader.nBitCount )
+ nCompression = RLE_4;
+ else if( 8 == aHeader.nBitCount )
+ nCompression = RLE_8;
+ }
+ else
+ nCompression = COMPRESS_NONE;
+ }
+ break;
+ }
+
+#ifdef USE_ZCODEC
+ if( ( rOStm.GetCompressMode() & COMPRESSMODE_ZBITMAP ) &&
+ ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_40 ) )
+ {
+ aHeader.nCompression = ZCOMPRESS;
+ }
+ else
+#endif // USE_ZCODEC
+ aHeader.nCompression = nCompression;
+
+ aHeader.nSizeImage = rAcc.Height() * rAcc.GetScanlineSize();
+
+ if( maPrefSize.Width() && maPrefSize.Height() )
+ {
+ const Size aSize100( OutputDevice::LogicToLogic( maPrefSize, maPrefMapMode, MAP_100TH_MM ) );
+
+ if( aSize100.Width() && aSize100.Height() )
+ {
+ aHeader.nXPelsPerMeter = ( rAcc.Width() * 100000UL ) / aSize100.Width();
+ aHeader.nYPelsPerMeter = ( rAcc.Height() * 100000UL ) / aSize100.Height();
+ }
+ }
+
+ aHeader.nColsUsed = ( ( aHeader.nBitCount <= 8 ) ? rAcc.GetPaletteEntryCount() : 0 );
+ aHeader.nColsImportant = 0;
+
+ rOStm << aHeader.nSize;
+ rOStm << aHeader.nWidth;
+ rOStm << aHeader.nHeight;
+ rOStm << aHeader.nPlanes;
+ rOStm << aHeader.nBitCount;
+ rOStm << aHeader.nCompression;
+
+ nImageSizePos = rOStm.Tell();
+ rOStm.SeekRel( sizeof( aHeader.nSizeImage ) );
+
+ rOStm << aHeader.nXPelsPerMeter;
+ rOStm << aHeader.nYPelsPerMeter;
+ rOStm << aHeader.nColsUsed;
+ rOStm << aHeader.nColsImportant;
+
+#ifdef USE_ZCODEC
+ if( aHeader.nCompression == ZCOMPRESS )
+ {
+ ZCodec aCodec;
+ SvMemoryStream aMemStm( aHeader.nSizeImage + 4096, 65535 );
+ ULONG nCodedPos = rOStm.Tell(), nLastPos;
+ ULONG nCodedSize, nUncodedSize;
+
+ // write uncoded data palette
+ if( aHeader.nColsUsed )
+ ImplWriteDIBPalette( aMemStm, rAcc );
+
+ // write uncoded bits
+ bRet = ImplWriteDIBBits( aMemStm, rAcc, nCompression, aHeader.nSizeImage );
+
+ // get uncoded size
+ nUncodedSize = aMemStm.Tell();
+
+ // seek over compress info
+ rOStm.SeekRel( 12 );
+
+ // write compressed data
+ aCodec.BeginCompression( 3 );
+ aCodec.Write( rOStm, (BYTE*) aMemStm.GetData(), nUncodedSize );
+ aCodec.EndCompression();
+
+ // update compress info ( coded size, uncoded size, uncoded compression )
+ nCodedSize = ( nLastPos = rOStm.Tell() ) - nCodedPos - 12;
+ rOStm.Seek( nCodedPos );
+ rOStm << nCodedSize << nUncodedSize << nCompression;
+ rOStm.Seek( nLastPos );
+
+ if( bRet )
+ bRet = ( rOStm.GetError() == ERRCODE_NONE );
+ }
+ else
+#endif // USE_ZCODEC
+ {
+ if( aHeader.nColsUsed )
+ ImplWriteDIBPalette( rOStm, rAcc );
+
+ bRet = ImplWriteDIBBits( rOStm, rAcc, aHeader.nCompression, aHeader.nSizeImage );
+ }
+
+ nEndPos = rOStm.Tell();
+ rOStm.Seek( nImageSizePos );
+ rOStm << aHeader.nSizeImage;
+ rOStm.Seek( nEndPos );
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplWriteDIBFileHeader( SvStream& rOStm, BitmapReadAccess& rAcc )
+{
+ UINT32 nPalCount = ( rAcc.HasPalette() ? rAcc.GetPaletteEntryCount() : rAcc.HasColorMask() ? 3UL : 0UL );
+ UINT32 nOffset = 14 + DIBINFOHEADERSIZE + nPalCount * 4UL;
+
+ rOStm << (UINT16) 0x4D42;
+ rOStm << (UINT32) ( nOffset + ( rAcc.Height() * rAcc.GetScanlineSize() ) );
+ rOStm << (UINT16) 0;
+ rOStm << (UINT16) 0;
+ rOStm << nOffset;
+
+ return( rOStm.GetError() == 0UL );
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc )
+{
+ const USHORT nColors = rAcc.GetPaletteEntryCount();
+ const ULONG nPalSize = nColors * 4UL;
+ BYTE* pEntries = new BYTE[ nPalSize ];
+ BYTE* pTmpEntry = pEntries;
+ BitmapColor aPalColor;
+
+ for( USHORT i = 0; i < nColors; i++ )
+ {
+ const BitmapColor& rPalColor = rAcc.GetPaletteColor( i );
+
+ *pTmpEntry++ = rPalColor.GetBlue();
+ *pTmpEntry++ = rPalColor.GetGreen();
+ *pTmpEntry++ = rPalColor.GetRed();
+ *pTmpEntry++ = 0;
+ }
+
+ rOStm.Write( pEntries, nPalSize );
+ delete[] pEntries;
+
+ return( rOStm.GetError() == 0UL );
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplWriteDIBBits( SvStream& rOStm, BitmapReadAccess& rAcc,
+ ULONG nCompression, ULONG& rImageSize )
+{
+ if( BITFIELDS == nCompression )
+ {
+ const ColorMask& rMask = rAcc.GetColorMask();
+ SVBT32 aVal32;
+
+ LongToSVBT32( rMask.GetRedMask(), aVal32 );
+ rOStm.Write( (BYTE*) aVal32, 4UL );
+
+ LongToSVBT32( rMask.GetGreenMask(), aVal32 );
+ rOStm.Write( (BYTE*) aVal32, 4UL );
+
+ LongToSVBT32( rMask.GetBlueMask(), aVal32 );
+ rOStm.Write( (BYTE*) aVal32, 4UL );
+
+ rImageSize = rOStm.Tell();
+
+ if( rAcc.IsBottomUp() )
+ rOStm.Write( rAcc.GetBuffer(), rAcc.Height() * rAcc.GetScanlineSize() );
+ else
+ {
+ for( long nY = rAcc.Height() - 1, nScanlineSize = rAcc.GetScanlineSize(); nY >= 0L; nY-- )
+ rOStm.Write( rAcc.GetScanline( nY ), nScanlineSize );
+ }
+ }
+ else if( ( RLE_4 == nCompression ) || ( RLE_8 == nCompression ) )
+ {
+ rImageSize = rOStm.Tell();
+ ImplWriteRLE( rOStm, rAcc, RLE_4 == nCompression );
+ }
+ else if( !nCompression )
+ {
+ const ULONG nAlignedWidth = AlignedWidth4Bytes( rAcc.Width() * rAcc.GetBitCount() );
+ BOOL bNative = FALSE;
+
+ switch( rAcc.GetScanlineFormat() )
+ {
+ case( BMP_FORMAT_1BIT_MSB_PAL ):
+ case( BMP_FORMAT_4BIT_MSN_PAL ):
+ case( BMP_FORMAT_8BIT_PAL ):
+ case( BMP_FORMAT_24BIT_TC_BGR ):
+ {
+ if( rAcc.IsBottomUp() && ( rAcc.GetScanlineSize() == nAlignedWidth ) )
+ bNative = TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ rImageSize = rOStm.Tell();
+
+ if( bNative )
+ rOStm.Write( rAcc.GetBuffer(), nAlignedWidth * rAcc.Height() );
+ else
+ {
+ const long nWidth = rAcc.Width();
+ const long nHeight = rAcc.Height();
+ BYTE* pBuf = new BYTE[ nAlignedWidth ];
+ BYTE* pTmp;
+ BYTE cTmp;
+
+ switch( rAcc.GetBitCount() )
+ {
+ case( 1 ):
+ {
+ for( long nY = nHeight - 1; nY >= 0L; nY-- )
+ {
+ pTmp = pBuf;
+ cTmp = 0;
+
+ for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ )
+ {
+ if( !nShift )
+ {
+ nShift = 8L;
+ *pTmp++ = cTmp;
+ cTmp = 0;
+ }
+
+ cTmp |= ( (BYTE) rAcc.GetPixel( nY, nX ) << --nShift );
+ }
+
+ *pTmp = cTmp;
+ rOStm.Write( pBuf, nAlignedWidth );
+ }
+ }
+ break;
+
+ case( 4 ):
+ {
+ for( long nY = nHeight - 1; nY >= 0L; nY-- )
+ {
+ pTmp = pBuf;
+ cTmp = 0;
+
+ for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ )
+ {
+ if( !nShift )
+ {
+ nShift = 2L;
+ *pTmp++ = cTmp;
+ cTmp = 0;
+ }
+
+ cTmp |= ( (BYTE) rAcc.GetPixel( nY, nX ) << ( --nShift << 2L ) );
+ }
+ *pTmp = cTmp;
+ rOStm.Write( pBuf, nAlignedWidth );
+ }
+ }
+ break;
+
+ case( 8 ):
+ {
+ for( long nY = nHeight - 1; nY >= 0L; nY-- )
+ {
+ pTmp = pBuf;
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ *pTmp++ = rAcc.GetPixel( nY, nX );
+
+ rOStm.Write( pBuf, nAlignedWidth );
+ }
+ }
+ break;
+
+ default:
+ {
+ BitmapColor aPixelColor;
+
+ for( long nY = nHeight - 1; nY >= 0L; nY-- )
+ {
+ pTmp = pBuf;
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aPixelColor = rAcc.GetPixel( nY, nX );
+ *pTmp++ = aPixelColor.GetBlue();
+ *pTmp++ = aPixelColor.GetGreen();
+ *pTmp++ = aPixelColor.GetRed();
+ }
+
+ rOStm.Write( pBuf, nAlignedWidth );
+ }
+ }
+ break;
+ }
+
+ delete[] pBuf;
+ }
+ }
+
+ rImageSize = rOStm.Tell() - rImageSize;
+
+ return( rOStm.GetError() == 0UL );
+}
+
+// ------------------------------------------------------------------
+
+void Bitmap::ImplDecodeRLE( BYTE* pBuffer, DIBInfoHeader& rHeader,
+ BitmapWriteAccess& rAcc, BOOL bRLE4 )
+{
+ Scanline pRLE = pBuffer;
+ long nY = rHeader.nHeight - 1L;
+ const ULONG nWidth = rAcc.Width();
+ ULONG nCountByte;
+ ULONG nRunByte;
+ ULONG nX = 0UL;
+ BYTE cTmp;
+ BOOL bEndDecoding = FALSE;
+
+ do
+ {
+ if( !( nCountByte = *pRLE++ ) )
+ {
+ nRunByte = *pRLE++;
+
+ if( nRunByte > 2 )
+ {
+ if( bRLE4 )
+ {
+ nCountByte = nRunByte >> 1;
+
+ for( ULONG i = 0UL; i < nCountByte; i++ )
+ {
+ cTmp = *pRLE++;
+
+ if( nX < nWidth )
+ rAcc.SetPixel( nY, nX++, cTmp >> 4 );
+
+ if( nX < nWidth )
+ rAcc.SetPixel( nY, nX++, cTmp & 0x0f );
+ }
+
+ if( nRunByte & 1 )
+ {
+ if( nX < nWidth )
+ rAcc.SetPixel( nY, nX++, *pRLE >> 4 );
+
+ pRLE++;
+ }
+
+ if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
+ pRLE++;
+ }
+ else
+ {
+ for( ULONG i = 0UL; i < nRunByte; i++ )
+ {
+ if( nX < nWidth )
+ rAcc.SetPixel( nY, nX++, *pRLE );
+
+ pRLE++;
+ }
+
+ if( nRunByte & 1 )
+ pRLE++;
+ }
+ }
+ else if( !nRunByte )
+ {
+ nY--;
+ nX = 0UL;
+ }
+ else if( nRunByte == 1 )
+ bEndDecoding = TRUE;
+ else
+ {
+ nX += *pRLE++;
+ nY -= *pRLE++;
+ }
+ }
+ else
+ {
+ cTmp = *pRLE++;
+
+ if( bRLE4 )
+ {
+ nRunByte = nCountByte >> 1;
+
+ for( ULONG i = 0UL; i < nRunByte; i++ )
+ {
+ if( nX < nWidth )
+ rAcc.SetPixel( nY, nX++, cTmp >> 4 );
+
+ if( nX < nWidth )
+ rAcc.SetPixel( nY, nX++, cTmp & 0x0f );
+ }
+
+ if( ( nCountByte & 1 ) && ( nX < nWidth ) )
+ rAcc.SetPixel( nY, nX++, cTmp >> 4 );
+ }
+ else
+ {
+ for( ULONG i = 0UL; ( i < nCountByte ) && ( nX < nWidth ); i++ )
+ rAcc.SetPixel( nY, nX++, cTmp );
+ }
+ }
+ }
+ while ( !bEndDecoding && ( nY >= 0L ) );
+}
+
+// ------------------------------------------------------------------
+
+BOOL Bitmap::ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, BOOL bRLE4 )
+{
+ const ULONG nWidth = rAcc.Width();
+ const ULONG nHeight = rAcc.Height();
+ ULONG nX;
+ ULONG nSaveIndex;
+ ULONG nCount;
+ ULONG nBufCount;
+ BYTE* pBuf = new BYTE[ nWidth << 1 ];
+ BYTE* pTmp;
+ BYTE cPix;
+ BYTE cLast;
+ BOOL bFound;
+
+ for ( long nY = nHeight - 1L; nY >= 0L; nY-- )
+ {
+ pTmp = pBuf;
+ nX = nBufCount = 0UL;
+
+ while( nX < nWidth )
+ {
+ nCount = 1L;
+ cPix = rAcc.GetPixel( nY, nX++ );
+
+ while( ( nX < nWidth ) && ( nCount < 255L ) && ( cPix == rAcc.GetPixel( nY, nX ) ) )
+ {
+ nX++;
+ nCount++;
+ }
+
+ if ( nCount > 1 )
+ {
+ *pTmp++ = (BYTE) nCount;
+ *pTmp++ = ( bRLE4 ? ( ( cPix << 4 ) | cPix ) : cPix );
+ nBufCount += 2;
+ }
+ else
+ {
+ cLast = cPix;
+ nSaveIndex = nX - 1UL;
+ bFound = FALSE;
+
+ while( ( nX < nWidth ) && ( nCount < 256L ) && ( cPix = rAcc.GetPixel( nY, nX ) ) != cLast )
+ {
+ nX++; nCount++;
+ cLast = cPix;
+ bFound = TRUE;
+ }
+
+ if ( bFound )
+ nX--;
+
+ if ( nCount > 3 )
+ {
+ *pTmp++ = 0;
+ *pTmp++ = (BYTE) --nCount;
+
+ if( bRLE4 )
+ {
+ for ( ULONG i = 0; i < nCount; i++, pTmp++ )
+ {
+ *pTmp = (BYTE) rAcc.GetPixel( nY, nSaveIndex++ ) << 4;
+
+ if ( ++i < nCount )
+ *pTmp |= rAcc.GetPixel( nY, nSaveIndex++ );
+ }
+
+ nCount = ( nCount + 1 ) >> 1;
+ }
+ else
+ {
+ for( ULONG i = 0UL; i < nCount; i++ )
+ *pTmp++ = rAcc.GetPixel( nY, nSaveIndex++ );
+ }
+
+ if ( nCount & 1 )
+ {
+ *pTmp++ = 0;
+ nBufCount += ( nCount + 3 );
+ }
+ else
+ nBufCount += ( nCount + 2 );
+ }
+ else
+ {
+ *pTmp++ = 1;
+ *pTmp++ = (BYTE) rAcc.GetPixel( nY, nSaveIndex ) << ( bRLE4 ? 4 : 0 );
+
+ if ( nCount == 3 )
+ {
+ *pTmp++ = 1;
+ *pTmp++ = (BYTE) rAcc.GetPixel( nY, ++nSaveIndex ) << ( bRLE4 ? 4 : 0 );
+ nBufCount += 4;
+ }
+ else
+ nBufCount += 2;
+ }
+ }
+ }
+
+ pBuf[ nBufCount++ ] = 0;
+ pBuf[ nBufCount++ ] = 0;
+
+ rOStm.Write( pBuf, nBufCount );
+ }
+
+ rOStm << (BYTE) 0;
+ rOStm << (BYTE) 1;
+
+ delete[] pBuf;
+
+ return( rOStm.GetError() == 0UL );
+}
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
new file mode 100644
index 000000000000..34776a8b00bf
--- /dev/null
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -0,0 +1,2248 @@
+/*************************************************************************
+ *
+ * $RCSfile: bitmap3.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdlib.h>
+#define _SV_BITMAP_CXX
+
+#ifdef W31
+#include <tools/svwin.h>
+#endif
+#include <tools/new.hxx>
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_IMPOCT_HXX
+#include <impoct.hxx>
+#endif
+#ifndef _SV_OCTREE_HXX
+#include <octree.hxx>
+#endif
+#ifndef _SV_IMPVECT_HXX
+#include <impvect.hxx>
+#endif
+#ifndef _SV_BITMAPEX_HXX
+#include <bitmapex.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define RGB15( _def_cR, _def_cG, _def_cB ) (((ULONG)(_def_cR)<<10UL)|((ULONG)(_def_cG)<<5UL)|(ULONG)(_def_cB))
+#define GAMMA( _def_cVal, _def_InvGamma ) ((BYTE)MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0L,255L))
+
+#define CALC_ERRORS \
+ nTemp = p1T[nX++] >> 12; \
+ nBErr = MinMax( nTemp, 0, 255 ); \
+ nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; \
+ nTemp = p1T[nX++] >> 12; \
+ nGErr = MinMax( nTemp, 0, 255 ); \
+ nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; \
+ nTemp = p1T[nX] >> 12; \
+ nRErr = MinMax( nTemp, 0, 255 ); \
+ nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ];
+
+#define CALC_TABLES3 \
+ p2T[nX++] += FloydError3[nBErr]; \
+ p2T[nX++] += FloydError3[nGErr]; \
+ p2T[nX++] += FloydError3[nRErr];
+
+#define CALC_TABLES5 \
+ p2T[nX++] += FloydError5[nBErr]; \
+ p2T[nX++] += FloydError5[nGErr]; \
+ p2T[nX++] += FloydError5[nRErr];
+
+#define CALC_TABLES7 \
+ p1T[++nX] += FloydError7[nBErr]; \
+ p2T[nX++] += FloydError1[nBErr]; \
+ p1T[nX] += FloydError7[nGErr]; \
+ p2T[nX++] += FloydError1[nGErr]; \
+ p1T[nX] += FloydError7[nRErr]; \
+ p2T[nX] += FloydError1[nRErr];
+
+// -----------
+// - Statics -
+// -----------
+
+ULONG nVCLRLut[ 6 ] = { 16, 17, 18, 19, 20, 21 };
+ULONG nVCLGLut[ 6 ] = { 0, 6, 12, 18, 24, 30 };
+ULONG nVCLBLut[ 6 ] = { 0, 36, 72, 108, 144, 180 };
+
+// ------------------------------------------------------------------------
+
+ULONG nVCLDitherLut[ 256 ] =
+{
+ 0, 49152, 12288, 61440, 3072, 52224, 15360, 64512, 768, 49920, 13056,
+ 62208, 3840, 52992, 16128, 65280, 32768, 16384, 45056, 28672, 35840, 19456,
+ 48128, 31744, 33536, 17152, 45824, 29440, 36608, 20224, 48896, 32512, 8192,
+ 57344, 4096, 53248, 11264, 60416, 7168, 56320, 8960, 58112, 4864, 54016,
+ 12032, 61184, 7936, 57088, 40960, 24576, 36864, 20480, 44032, 27648, 39936,
+ 23552, 41728, 25344, 37632, 21248, 44800, 28416, 40704, 24320, 2048, 51200,
+ 14336, 63488, 1024, 50176, 13312, 62464, 2816, 51968, 15104, 64256, 1792,
+ 50944, 14080, 63232, 34816, 18432, 47104, 30720, 33792, 17408, 46080, 29696,
+ 35584, 19200, 47872, 31488, 34560, 18176, 46848, 30464, 10240, 59392, 6144,
+ 55296, 9216, 58368, 5120, 54272, 11008, 60160, 6912, 56064, 9984, 59136,
+ 5888, 55040, 43008, 26624, 38912, 22528, 41984, 25600, 37888, 21504, 43776,
+ 27392, 39680, 23296, 42752, 26368, 38656, 22272, 512, 49664, 12800, 61952,
+ 3584, 52736, 15872, 65024, 256, 49408, 12544, 61696, 3328, 52480, 15616,
+ 64768, 33280, 16896, 45568, 29184, 36352, 19968, 48640, 32256, 33024, 16640,
+ 45312, 28928, 36096, 19712, 48384, 32000, 8704, 57856, 4608, 53760, 11776,
+ 60928, 7680, 56832, 8448, 57600, 4352, 53504, 11520, 60672, 7424, 56576,
+ 41472, 25088, 37376, 20992, 44544, 28160, 40448, 24064, 41216, 24832, 37120,
+ 20736, 44288, 27904, 40192, 23808, 2560, 51712, 14848, 64000, 1536, 50688,
+ 13824, 62976, 2304, 51456, 14592, 63744, 1280, 50432, 13568, 62720, 35328,
+ 18944, 47616, 31232, 34304, 17920, 46592, 30208, 35072, 18688, 47360, 30976,
+ 34048, 17664, 46336, 29952, 10752, 59904, 6656, 55808, 9728, 58880, 5632,
+ 54784, 10496, 59648, 6400, 55552, 9472, 58624, 5376, 54528, 43520, 27136,
+ 39424, 23040, 42496, 26112, 38400, 22016, 43264, 26880, 39168, 22784, 42240,
+ 25856, 38144, 21760
+};
+
+// ------------------------------------------------------------------------
+
+ULONG nVCLLut[ 256 ] =
+{
+ 0, 1286, 2572, 3858, 5144, 6430, 7716, 9002,
+ 10288, 11574, 12860, 14146, 15432, 16718, 18004, 19290,
+ 20576, 21862, 23148, 24434, 25720, 27006, 28292, 29578,
+ 30864, 32150, 33436, 34722, 36008, 37294, 38580, 39866,
+ 41152, 42438, 43724, 45010, 46296, 47582, 48868, 50154,
+ 51440, 52726, 54012, 55298, 56584, 57870, 59156, 60442,
+ 61728, 63014, 64300, 65586, 66872, 68158, 69444, 70730,
+ 72016, 73302, 74588, 75874, 77160, 78446, 79732, 81018,
+ 82304, 83590, 84876, 86162, 87448, 88734, 90020, 91306,
+ 92592, 93878, 95164, 96450, 97736, 99022,100308,101594,
+ 102880,104166,105452,106738,108024,109310,110596,111882,
+ 113168,114454,115740,117026,118312,119598,120884,122170,
+ 123456,124742,126028,127314,128600,129886,131172,132458,
+ 133744,135030,136316,137602,138888,140174,141460,142746,
+ 144032,145318,146604,147890,149176,150462,151748,153034,
+ 154320,155606,156892,158178,159464,160750,162036,163322,
+ 164608,165894,167180,168466,169752,171038,172324,173610,
+ 174896,176182,177468,178754,180040,181326,182612,183898,
+ 185184,186470,187756,189042,190328,191614,192900,194186,
+ 195472,196758,198044,199330,200616,201902,203188,204474,
+ 205760,207046,208332,209618,210904,212190,213476,214762,
+ 216048,217334,218620,219906,221192,222478,223764,225050,
+ 226336,227622,228908,230194,231480,232766,234052,235338,
+ 236624,237910,239196,240482,241768,243054,244340,245626,
+ 246912,248198,249484,250770,252056,253342,254628,255914,
+ 257200,258486,259772,261058,262344,263630,264916,266202,
+ 267488,268774,270060,271346,272632,273918,275204,276490,
+ 277776,279062,280348,281634,282920,284206,285492,286778,
+ 288064,289350,290636,291922,293208,294494,295780,297066,
+ 298352,299638,300924,302210,303496,304782,306068,307354,
+ 308640,309926,311212,312498,313784,315070,316356,317642,
+ 318928,320214,321500,322786,324072,325358,326644,327930
+};
+
+// ------------------------------------------------------------------------
+
+long FloydMap[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, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 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, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 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
+};
+
+// ------------------------------------------------------------------------
+
+long FloydError1[61] =
+{
+ -7680, -7424, -7168, -6912, -6656, -6400, -6144,
+ -5888, -5632, -5376, -5120, -4864, -4608, -4352,
+ -4096, -3840, -3584, -3328, -3072, -2816, -2560,
+ -2304, -2048, -1792, -1536, -1280, -1024, -768,
+ -512, -256, 0, 256, 512, 768, 1024, 1280, 1536,
+ 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584,
+ 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5632,
+ 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680
+};
+
+// ------------------------------------------------------------------------
+
+long FloydError3[61] =
+{
+ -23040, -22272, -21504, -20736, -19968, -19200,
+ -18432, -17664, -16896, -16128, -15360, -14592,
+ -13824, -13056, -12288, -11520, -10752, -9984,
+ -9216, -8448, -7680, -6912, -6144, -5376, -4608,
+ -3840, -3072, -2304, -1536, -768, 0, 768, 1536,
+ 2304, 3072, 3840, 4608, 5376, 6144, 6912, 7680,
+ 8448, 9216, 9984, 10752, 11520, 12288, 13056,
+ 13824, 14592, 15360, 16128, 16896, 17664, 18432,
+ 19200, 19968, 20736, 21504, 22272, 23040
+};
+
+// ------------------------------------------------------------------------
+
+long FloydError5[61] =
+{
+ -38400, -37120, -35840, -34560, -33280, -32000,
+ -30720, -29440, -28160, -26880, -25600, -24320,
+ -23040, -21760, -20480, -19200, -17920, -16640,
+ -15360, -14080, -12800, -11520, -10240, -8960,
+ -7680, -6400, -5120, -3840, -2560, -1280, 0,
+ 1280, 2560, 3840, 5120, 6400, 7680, 8960, 10240,
+ 11520, 12800, 14080, 15360, 16640, 17920, 19200,
+ 20480, 21760, 23040, 24320, 25600, 26880, 28160,
+ 29440, 30720, 32000, 33280, 34560, 35840, 37120,
+ 38400
+};
+
+// ------------------------------------------------------------------------
+
+long FloydError7[61] =
+{
+ -53760, -51968, -50176, -48384, -46592, -44800,
+ -43008, -41216, -39424, -37632, -35840, -34048,
+ -32256, -30464, -28672, -26880, -25088, -23296,
+ -21504, -19712, -17920, -16128, -14336, -12544,
+ -10752, -8960, -7168, -5376, -3584, -1792, 0,
+ 1792, 3584, 5376, 7168, 8960, 10752, 12544, 14336,
+ 16128, 17920, 19712, 21504, 23296, 25088, 26880,
+ 28672, 30464, 32256, 34048, 35840, 37632, 39424,
+ 41216, 43008, 44800, 46592, 48384, 50176, 51968,
+ 53760
+};
+
+// ------------------------------------------------------------------------
+
+long FloydIndexMap[6] =
+{
+ -30, 21, 72, 123, 174, 225
+};
+
+// --------------------------
+// - ImplCreateDitherMatrix -
+// --------------------------
+
+void ImplCreateDitherMatrix( BYTE (*pDitherMatrix)[16][16] )
+{
+ double fVal = 3.125;
+ const double fVal16 = fVal / 16.;
+ long i, j, k, l;
+ USHORT pMtx[ 16 ][ 16 ];
+ USHORT nMax = 0;
+ static BYTE pMagic[4][4] = { 0, 14, 3, 13,
+ 11, 5, 8, 6,
+ 12, 2, 15, 1,
+ 7, 9, 4, 10 };
+
+ // MagicSquare aufbauen
+ for ( i = 0; i < 4; i++ )
+ for ( j = 0; j < 4; j++ )
+ for ( k = 0; k < 4; k++ )
+ for ( l = 0; l < 4; l++ )
+ nMax = Max ( pMtx[ (k<<2) + i][(l<<2 ) + j] =
+ (USHORT) ( 0.5 + pMagic[i][j]*fVal + pMagic[k][l]*fVal16 ), nMax );
+
+ // auf Intervall [0;254] skalieren
+ for ( i = 0, fVal = 254. / nMax; i < 16; i++ )
+ for( j = 0; j < 16; j++ )
+ (*pDitherMatrix)[i][j] = (BYTE) ( fVal * pMtx[i][j] );
+}
+
+// ----------
+// - Bitmap -
+// ----------
+
+BOOL Bitmap::Convert( BmpConversion eConversion )
+{
+ const USHORT nBitCount = GetBitCount();
+ BOOL bRet = FALSE;
+
+ switch( eConversion )
+ {
+ case( BMP_CONVERSION_1BIT_THRESHOLD ):
+ bRet = ImplMakeMono( 128 );
+ break;
+
+ case( BMP_CONVERSION_1BIT_MATRIX ):
+ bRet = ImplMakeMonoDither();
+ break;
+
+ case( BMP_CONVERSION_4BIT_GREYS ):
+ bRet = ImplMakeGreyscales( 16 );
+ break;
+
+ case( BMP_CONVERSION_4BIT_COLORS ):
+ {
+ if( nBitCount < 4 )
+ bRet = ImplConvertUp( 4, NULL );
+ else if( nBitCount > 4 )
+ bRet = ImplConvertDown( 4, NULL );
+ else
+ bRet = TRUE;
+ }
+ break;
+
+ case( BMP_CONVERSION_4BIT_TRANS ):
+ {
+ Color aTrans( BMP_COL_TRANS );
+
+ if( nBitCount < 4 )
+ bRet = ImplConvertUp( 4, &aTrans );
+ else
+ bRet = ImplConvertDown( 4, &aTrans );
+ }
+ break;
+
+ case( BMP_CONVERSION_8BIT_GREYS ):
+ bRet = ImplMakeGreyscales( 256 );
+ break;
+
+ case( BMP_CONVERSION_8BIT_COLORS ):
+ {
+ if( nBitCount < 8 )
+ bRet = ImplConvertUp( 8 );
+ else if( nBitCount > 8 )
+ bRet = ImplConvertDown( 8 );
+ else
+ bRet = TRUE;
+ }
+ break;
+
+ case( BMP_CONVERSION_8BIT_TRANS ):
+ {
+ Color aTrans( BMP_COL_TRANS );
+
+ if( nBitCount < 8 )
+ bRet = ImplConvertUp( 8, &aTrans );
+ else
+ bRet = ImplConvertDown( 8, &aTrans );
+ }
+ break;
+
+ case( BMP_CONVERSION_24BIT ):
+ {
+ if( nBitCount < 24 )
+ bRet = ImplConvertUp( 24, FALSE );
+ else
+ bRet = TRUE;
+ }
+ break;
+
+ case( BMP_CONVERSION_GHOSTED ):
+ bRet = ImplConvertGhosted();
+ break;
+
+ default:
+ DBG_ERROR( "Bitmap::Convert(): Unsupported conversion" );
+ break;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplMakeMono( BYTE cThreshold )
+{
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc )
+ {
+ Bitmap aNewBmp( GetSizePixel(), 1 );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const BitmapColor aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ const long nWidth = pWriteAcc->Width();
+ const long nHeight = pWriteAcc->Height();
+
+ if( pReadAcc->HasPalette() )
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >=
+ cThreshold )
+ {
+ pWriteAcc->SetPixel( nY, nX, aWhite );
+ }
+ else
+ pWriteAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ }
+ else
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pReadAcc->GetPixel( nY, nX ).GetLuminance() >=
+ cThreshold )
+ {
+ pWriteAcc->SetPixel( nY, nX, aWhite );
+ }
+ else
+ pWriteAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ }
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplMakeMonoDither()
+{
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc )
+ {
+ Bitmap aNewBmp( GetSizePixel(), 1 );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const BitmapColor aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const BitmapColor aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ const long nWidth = pWriteAcc->Width();
+ const long nHeight = pWriteAcc->Height();
+ BYTE pDitherMatrix[ 16 ][ 16 ];
+
+ ImplCreateDitherMatrix( &pDitherMatrix );
+
+ if( pReadAcc->HasPalette() )
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L, nModY = nY % 16; nX < nWidth; nX++ )
+ {
+ if( pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >
+ pDitherMatrix[ nModY ][ nX % 16 ] )
+ {
+ pWriteAcc->SetPixel( nY, nX, aWhite );
+ }
+ else
+ pWriteAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ }
+ else
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L, nModY = nY % 16; nX < nWidth; nX++ )
+ {
+ if( pReadAcc->GetPixel( nY, nX ).GetLuminance() >
+ pDitherMatrix[ nModY ][ nX % 16 ] )
+ {
+ pWriteAcc->SetPixel( nY, nX, aWhite );
+ }
+ else
+ pWriteAcc->SetPixel( nY, nX, aBlack );
+ }
+ }
+ }
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplMakeGreyscales( USHORT nGreys )
+{
+ DBG_ASSERT( nGreys == 16 || nGreys == 256, "Only 16 or 256 greyscales are supported!" )
+
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc )
+ {
+ const BitmapPalette& rPal = GetGreyPalette( nGreys );
+ ULONG nShift = ( ( nGreys == 16 ) ? 4UL : 0UL );
+ BOOL bPalDiffers = !pReadAcc->HasPalette() || ( rPal.GetEntryCount() != pReadAcc->GetPaletteEntryCount() );
+
+ if( !bPalDiffers )
+ bPalDiffers = ( (BitmapPalette&) rPal != pReadAcc->GetPalette() );
+
+ if( bPalDiffers )
+ {
+ Bitmap aNewBmp( GetSizePixel(), ( nGreys == 16 ) ? 4 : 8, &rPal );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const long nWidth = pWriteAcc->Width();
+ const long nHeight = pWriteAcc->Height();
+
+ if( pReadAcc->HasPalette() )
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ pWriteAcc->SetPixel( nY, nX,
+ (BYTE) ( pReadAcc->GetPaletteColor(
+ pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >> nShift ) );
+ }
+ }
+ }
+ else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR &&
+ pWriteAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ nShift += 8;
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ Scanline pReadScan = pReadAcc->GetScanline( nY );
+ Scanline pWriteScan = pWriteAcc->GetScanline( nY );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ const ULONG nB = *pReadScan++;
+ const ULONG nG = *pReadScan++;
+ const ULONG nR = *pReadScan++;
+
+ *pWriteScan++ = (BYTE) ( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift );
+ }
+ }
+ }
+ else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB &&
+ pWriteAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ nShift += 8;
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ Scanline pReadScan = pReadAcc->GetScanline( nY );
+ Scanline pWriteScan = pWriteAcc->GetScanline( nY );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ const ULONG nR = *pReadScan++;
+ const ULONG nG = *pReadScan++;
+ const ULONG nB = *pReadScan++;
+
+ *pWriteScan++ = (BYTE) ( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift );
+ }
+ }
+ }
+ else
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, ( pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >> nShift );
+ }
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+ else
+ {
+ ReleaseAccess( pReadAcc );
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplConvertUp( USHORT nBitCount, Color* pExtColor )
+{
+ DBG_ASSERT( nBitCount > GetBitCount(), "New BitCount must be greater!" );
+
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc )
+ {
+ BitmapPalette aPal;
+ Bitmap aNewBmp( GetSizePixel(), nBitCount, &aPal );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const long nWidth = pWriteAcc->Width();
+ const long nHeight = pWriteAcc->Height();
+
+ if( pWriteAcc->HasPalette() )
+ {
+ const USHORT nOldCount = 1 << GetBitCount();
+ const BitmapPalette& rOldPal = pReadAcc->GetPalette();
+
+ aPal.SetEntryCount( 1 << nBitCount );
+
+ for( USHORT i = 0; i < nOldCount; i++ )
+ aPal[ i ] = rOldPal[ i ];
+
+ if( pExtColor )
+ aPal[ aPal.GetEntryCount() - 1 ] = *pExtColor;
+
+ pWriteAcc->SetPalette( aPal );
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY, nX ) );
+ }
+ else
+ {
+ if( pReadAcc->HasPalette() )
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nX ) ) );
+ }
+ else
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY, nX ) );
+ }
+ }
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplConvertDown( USHORT nBitCount, Color* pExtColor )
+{
+ DBG_ASSERT( nBitCount <= GetBitCount(), "New BitCount must be lower ( or equal when pExtColor is set )!" );
+
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc )
+ {
+ BitmapPalette aPal;
+ Bitmap aNewBmp( GetSizePixel(), nBitCount, &aPal );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const USHORT nCount = 1 << nBitCount;
+ const long nWidth = pWriteAcc->Width();
+ const long nWidth1 = nWidth - 1L;
+ const long nHeight = pWriteAcc->Height();
+ Octree aOctree( *pReadAcc, pExtColor ? ( nCount - 1 ) : nCount );
+ InverseColorMap aColorMap( aPal = aOctree.GetPalette() );
+ BitmapColor aColor;
+ ImpErrorQuad aErrQuad;
+ ImpErrorQuad* pErrQuad1 = new ImpErrorQuad[ nWidth ];
+ ImpErrorQuad* pErrQuad2 = new ImpErrorQuad[ nWidth ];
+ ImpErrorQuad* pQLine1 = pErrQuad1;
+ ImpErrorQuad* pQLine2;
+ long nX, nY;
+ long nYTmp = 0L;
+ BYTE cIndex;
+ BOOL bQ1 = TRUE;
+
+ if( pExtColor )
+ {
+ aPal.SetEntryCount( aPal.GetEntryCount() + 1 );
+ aPal[ aPal.GetEntryCount() - 1 ] = *pExtColor;
+ }
+
+ // set Black/White always, if we have enough space
+ if( aPal.GetEntryCount() < ( nCount - 1 ) )
+ {
+ aPal.SetEntryCount( aPal.GetEntryCount() + 2 );
+ aPal[ aPal.GetEntryCount() - 2 ] = Color( COL_BLACK );
+ aPal[ aPal.GetEntryCount() - 1 ] = Color( COL_WHITE );
+ }
+
+ pWriteAcc->SetPalette( aPal );
+
+ for( nY = 0L; nY < Min( nHeight, 2L ); nY++, nYTmp++ )
+ {
+ for( nX = 0L, pQLine2 = !nY ? pErrQuad1 : pErrQuad2; nX < nWidth; nX++ )
+ {
+ if( pReadAcc->HasPalette() )
+ pQLine2[ nX ] = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nYTmp, nX ) );
+ else
+ pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
+ }
+ }
+
+ for( nY = 0L; nY < nHeight; nY++, nYTmp++ )
+ {
+ // erstes ZeilenPixel
+ cIndex = (BYTE) aColorMap.GetBestPaletteIndex( pQLine1[ 0 ].ImplGetColor() );
+ pWriteAcc->SetPixel( nY, 0, cIndex );
+
+ for( nX = 1L; nX < nWidth1; nX++ )
+ {
+ cIndex = (BYTE) aColorMap.GetBestPaletteIndex( aColor = pQLine1[ nX ].ImplGetColor() );
+ aErrQuad = ( ImpErrorQuad( aColor ) -= pWriteAcc->GetPaletteColor( cIndex ) );
+ pQLine1[ ++nX ].ImplAddColorError7( aErrQuad );
+ pQLine2[ nX-- ].ImplAddColorError1( aErrQuad );
+ pQLine2[ nX-- ].ImplAddColorError5( aErrQuad );
+ pQLine2[ nX++ ].ImplAddColorError3( aErrQuad );
+ pWriteAcc->SetPixel( nY, nX, cIndex );
+ }
+
+ // letztes ZeilenPixel
+ cIndex = (BYTE) aColorMap.GetBestPaletteIndex( pQLine1[ nWidth1 ].ImplGetColor() );
+ pWriteAcc->SetPixel( nY, nX, cIndex );
+
+ // Zeilenpuffer neu fuellen/kopieren
+ pQLine1 = pQLine2;
+ pQLine2 = ( bQ1 = !bQ1 ) ? pErrQuad2 : pErrQuad1;
+
+ if( nYTmp < nHeight )
+ {
+ for( nX = 0L; nX < nWidth; nX++ )
+ {
+ if( pReadAcc->HasPalette() )
+ pQLine2[ nX ] = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nYTmp, nX ) );
+ else
+ pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
+ }
+ }
+ }
+
+ // Zeilenpuffer zerstoeren
+ delete[] pErrQuad1;
+ delete[] pErrQuad2;
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplConvertGhosted()
+{
+ Bitmap aNewBmp;
+ BitmapReadAccess* pR = AcquireReadAccess();
+ BOOL bRet = FALSE;
+
+ if( pR )
+ {
+ if( pR->HasPalette() )
+ {
+ BitmapPalette aNewPal( pR->GetPaletteEntryCount() );
+
+ for( long i = 0, nCount = aNewPal.GetEntryCount(); i < nCount; i++ )
+ {
+ const BitmapColor& rOld = pR->GetPaletteColor( (USHORT) i );
+ aNewPal[ (USHORT) i ] = BitmapColor( ( rOld.GetRed() >> 1 ) | 0x80,
+ ( rOld.GetGreen() >> 1 ) | 0x80,
+ ( rOld.GetBlue() >> 1 ) | 0x80 );
+ }
+
+ aNewBmp = Bitmap( GetSizePixel(), GetBitCount(), &aNewPal );
+ BitmapWriteAccess* pW = aNewBmp.AcquireWriteAccess();
+
+ if( pW )
+ {
+ pW->CopyBuffer( *pR );
+ aNewBmp.ReleaseAccess( pW );
+ bRet = TRUE;
+ }
+ }
+ else
+ {
+ aNewBmp = Bitmap( GetSizePixel(), 24 );
+
+ BitmapWriteAccess* pW = aNewBmp.AcquireWriteAccess();
+
+ if( pW )
+ {
+ const long nWidth = pR->Width(), nHeight = pR->Height();
+
+ for( long nY = 0; nY < nHeight; nY++ )
+ {
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ const BitmapColor aOld( pR->GetPixel( nY, nX ) );
+ pW->SetPixel( nY, nX, BitmapColor( ( aOld.GetRed() >> 1 ) | 0x80,
+ ( aOld.GetGreen() >> 1 ) | 0x80,
+ ( aOld.GetBlue() >> 1 ) | 0x80 ) );
+
+ }
+ }
+
+ aNewBmp.ReleaseAccess( pW );
+ bRet = TRUE;
+ }
+ }
+
+ ReleaseAccess( pR );
+ }
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::Scale( const double& rScaleX, const double& rScaleY, ULONG nScaleFlag )
+{
+ BOOL bRet;
+
+ if( ( rScaleX != 1.0 ) || ( rScaleY != 1.0 ) )
+ {
+ if( BMP_SCALE_FAST == nScaleFlag )
+ bRet = ImplScaleFast( rScaleX, rScaleY );
+ else if( BMP_SCALE_INTERPOLATE == nScaleFlag )
+ bRet = ImplScaleInterpolate( rScaleX, rScaleY );
+ else
+ bRet = FALSE;
+ }
+ else
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::Scale( const Size& rNewSize, ULONG nScaleFlag )
+{
+ const Size aSize( GetSizePixel() );
+ BOOL bRet;
+
+ if( aSize.Width() && aSize.Height() )
+ {
+ bRet = Scale( (double) rNewSize.Width() / aSize.Width(),
+ (double) rNewSize.Height() / aSize.Height(),
+ nScaleFlag );
+ }
+ else
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY )
+{
+ const Size aSizePix( GetSizePixel() );
+ const long nNewWidth = FRound( aSizePix.Width() * rScaleX );
+ const long nNewHeight = FRound( aSizePix.Height() * rScaleY );
+ BOOL bRet = FALSE;
+
+ if( nNewWidth && nNewHeight )
+ {
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ Bitmap aNewBmp( Size( nNewWidth, nNewHeight ), GetBitCount(), &pReadAcc->GetPalette() );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pReadAcc && pWriteAcc )
+ {
+ const long nScanlineSize = pWriteAcc->GetScanlineSize();
+ const long nNewWidth1 = nNewWidth - 1L;
+ const long nNewHeight1 = nNewHeight - 1L;
+ const long nWidth1 = pReadAcc->Width() - 1L;
+ const long nHeight1 = pReadAcc->Height() - 1L;
+ long* pLutX = new long[ nNewWidth ];
+ long* pLutY = new long[ nNewHeight ];
+ long nX, nY, nMapY, nActY = 0L;
+
+ if( nNewWidth1 && nNewHeight1 )
+ {
+ for( nX = 0L; nX < nNewWidth; nX++ )
+ pLutX[ nX ] = nX * nWidth1 / nNewWidth1;
+
+ for( nY = 0L; nY < nNewHeight; nY++ )
+ pLutY[ nY ] = nY * nHeight1 / nNewHeight1;
+
+ while( nActY < nNewHeight )
+ {
+ nMapY = pLutY[ nActY ];
+
+ for( nX = 0L; nX < nNewWidth; nX++ )
+ pWriteAcc->SetPixel( nActY, nX, pReadAcc->GetPixel( nMapY , pLutX[ nX ] ) );
+
+ while( ( nActY < nNewHeight1 ) && ( pLutY[ nActY + 1 ] == nMapY ) )
+ {
+ HMEMCPY( pWriteAcc->GetScanline( nActY + 1L ),
+ pWriteAcc->GetScanline( nActY ), nScanlineSize );
+ nActY++;
+ }
+
+ nActY++;
+ }
+
+ bRet = TRUE;
+ }
+
+ delete[] pLutX;
+ delete[] pLutY;
+ }
+
+ ReleaseAccess( pReadAcc );
+ aNewBmp.ReleaseAccess( pWriteAcc );
+
+ if( bRet )
+ ImplAssignWithSize( aNewBmp );
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplScaleInterpolate( const double& rScaleX, const double& rScaleY )
+{
+ const Size aSizePix( GetSizePixel() );
+ const long nNewWidth = FRound( aSizePix.Width() * rScaleX );
+ const long nNewHeight = FRound( aSizePix.Height() * rScaleY );
+ BOOL bRet = FALSE;
+
+ if( ( nNewWidth > 1L ) && ( nNewHeight > 1L ) )
+ {
+ BitmapColor aCol0;
+ BitmapColor aCol1;
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ long nWidth = pReadAcc->Width();
+ long nHeight = pReadAcc->Height();
+ Bitmap aNewBmp( Size( nNewWidth, nHeight ), 24 );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+ long* pLutInt;
+ long* pLutFrac;
+ long nX, nY;
+ long lXB0, lXB1, lXG0, lXG1, lXR0, lXR1;
+ double fTemp;
+ long nTemp;
+
+ if( pReadAcc && pWriteAcc )
+ {
+ const long nNewWidth1 = nNewWidth - 1L;
+ const long nWidth1 = pReadAcc->Width() - 1L;
+ const double fRevScaleX = (double) nWidth1 / nNewWidth1;
+
+ pLutInt = new long[ nNewWidth ];
+ pLutFrac = new long[ nNewWidth ];
+
+ for( nX = 0L, nTemp = nWidth - 2L; nX < nNewWidth; nX++ )
+ {
+ fTemp = nX * fRevScaleX;
+ pLutInt[ nX ] = MinMax( (long) fTemp, 0, nTemp );
+ fTemp -= pLutInt[ nX ];
+ pLutFrac[ nX ] = (long) ( fTemp * 1024. );
+ }
+
+ if( pReadAcc->HasPalette() )
+ {
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ if( 1 == nWidth )
+ {
+ aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, 0 ) );
+
+ for( nX = 0L; nX < nNewWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, aCol0 );
+ }
+ else
+ {
+ for( nX = 0L; nX < nNewWidth; nX++ )
+ {
+ nTemp = pLutInt[ nX ];
+
+ aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nTemp++ ) );
+ aCol1 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nTemp ) );
+
+ nTemp = pLutFrac[ nX ];
+
+ lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
+ lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
+ lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
+
+ aCol0.SetRed( (BYTE) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
+ aCol0.SetGreen( (BYTE) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
+ aCol0.SetBlue( (BYTE) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
+
+ pWriteAcc->SetPixel( nY, nX, aCol0 );
+ }
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ if( 1 == nWidth )
+ {
+ aCol0 = pReadAcc->GetPixel( nY, 0 );
+
+ for( nX = 0L; nX < nNewWidth; nX++ )
+ pWriteAcc->SetPixel( nY, nX, aCol0 );
+ }
+ else
+ {
+ for( nX = 0L; nX < nNewWidth; nX++ )
+ {
+ nTemp = pLutInt[ nX ];
+
+ aCol0 = pReadAcc->GetPixel( nY, nTemp++ );
+ aCol1 = pReadAcc->GetPixel( nY, nTemp );
+
+ nTemp = pLutFrac[ nX ];
+
+ lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
+ lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
+ lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
+
+ aCol0.SetRed( (BYTE) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
+ aCol0.SetGreen( (BYTE) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
+ aCol0.SetBlue( (BYTE) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
+
+ pWriteAcc->SetPixel( nY, nX, aCol0 );
+ }
+ }
+ }
+ }
+
+ delete[] pLutInt;
+ delete[] pLutFrac;
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+ aNewBmp.ReleaseAccess( pWriteAcc );
+
+ if( bRet )
+ {
+ bRet = FALSE;
+ ImplAssignWithSize( aNewBmp );
+ pReadAcc = AcquireReadAccess();
+ aNewBmp = Bitmap( Size( nNewWidth, nNewHeight ), 24 );
+ pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pReadAcc && pWriteAcc )
+ {
+ const long nNewHeight1 = nNewHeight - 1L;
+ const long nHeight1 = pReadAcc->Height() - 1L;
+ const double fRevScaleY = (double) nHeight1 / nNewHeight1;
+
+ pLutInt = new long[ nNewHeight ];
+ pLutFrac = new long[ nNewHeight ];
+
+ for( nY = 0L, nTemp = nHeight - 2L; nY < nNewHeight; nY++ )
+ {
+ fTemp = nY * fRevScaleY;
+ pLutInt[ nY ] = MinMax( (long) fTemp, 0, nTemp );
+ fTemp -= pLutInt[ nY ];
+ pLutFrac[ nY ] = (long) ( fTemp * 1024. );
+ }
+
+ if( pReadAcc->HasPalette() )
+ {
+ for( nX = 0L; nX < nNewWidth; nX++ )
+ {
+ if( 1 == nHeight )
+ {
+ aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( 0, nX ) );
+
+ for( nY = 0L; nY < nNewHeight; nY++ )
+ pWriteAcc->SetPixel( nY, nX, aCol0 );
+ }
+ else
+ {
+ for( nY = 0L; nY < nNewHeight; nY++ )
+ {
+ nTemp = pLutInt[ nY ];
+
+ aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nTemp++, nX ) );
+ aCol1 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nTemp, nX ) );
+
+ nTemp = pLutFrac[ nY ];
+
+ lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
+ lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
+ lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
+
+ aCol0.SetRed( (BYTE) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
+ aCol0.SetGreen( (BYTE) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
+ aCol0.SetBlue( (BYTE) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
+
+ pWriteAcc->SetPixel( nY, nX, aCol0 );
+ }
+ }
+ }
+ }
+ else
+ {
+ for( nX = 0L; nX < nNewWidth; nX++ )
+ {
+ if( 1 == nHeight )
+ {
+ aCol0 = pReadAcc->GetPixel( 0, nX );
+
+ for( nY = 0L; nY < nNewHeight; nY++ )
+ pWriteAcc->SetPixel( nY, nX, aCol0 );
+ }
+ else
+ {
+ for( nY = 0L; nY < nNewHeight; nY++ )
+ {
+ nTemp = pLutInt[ nY ];
+
+ aCol0 = pReadAcc->GetPixel( nTemp++, nX );
+ aCol1 = pReadAcc->GetPixel( nTemp, nX );
+
+ nTemp = pLutFrac[ nY ];
+
+ lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
+ lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
+ lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
+
+ aCol0.SetRed( (BYTE) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
+ aCol0.SetGreen( (BYTE) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
+ aCol0.SetBlue( (BYTE) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
+
+ pWriteAcc->SetPixel( nY, nX, aCol0 );
+ }
+ }
+ }
+ }
+
+ delete[] pLutInt;
+ delete[] pLutFrac;
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+ aNewBmp.ReleaseAccess( pWriteAcc );
+
+ if( bRet )
+ ImplAssignWithSize( aNewBmp );
+ }
+ }
+
+ if( !bRet )
+ bRet = ImplScaleFast( rScaleX, rScaleY );
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::Dither( ULONG nDitherFlags, const BitmapPalette* pDitherPal )
+{
+ DBG_ASSERT( !pDitherPal, "Sorry, using owner defined palettes is not yet supportet..." );
+
+ BOOL bRet = FALSE;
+
+ const Size aSizePix( GetSizePixel() );
+
+ if( aSizePix.Width() == 1 || aSizePix.Height() == 1 )
+ bRet = TRUE;
+ else if( nDitherFlags & BMP_DITHER_MATRIX )
+ bRet = ImplDitherMatrix( pDitherPal );
+ else if( nDitherFlags & BMP_DITHER_FLOYD )
+ bRet = ImplDitherFloyd( pDitherPal );
+ else if( ( nDitherFlags & BMP_DITHER_FLOYD_16 ) && ( GetBitCount() == 24 ) )
+ bRet = ImplDitherFloyd16();
+
+ return bRet;
+}
+
+//fuer WIN16 Borland
+#ifdef WIN
+#pragma codeseg BITMAP3_SEG1
+#endif
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplDitherMatrix( const BitmapPalette* pDitherPal )
+{
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ Bitmap aNewBmp( GetSizePixel(), 8 );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc && pWriteAcc )
+ {
+ const ULONG nWidth = pReadAcc->Width();
+ const ULONG nHeight = pReadAcc->Height();
+ BitmapColor aIndex( (BYTE) 0 );
+
+ if( pReadAcc->HasPalette() )
+ {
+ for( ULONG nY = 0UL; nY < nHeight; nY++ )
+ {
+ for( ULONG nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ )
+ {
+ const BitmapColor aCol( pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nX ) ) );
+ const ULONG nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ];
+ const ULONG nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL;
+ const ULONG nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL;
+ const ULONG nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL;
+
+ aIndex.SetIndex( (BYTE) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) );
+ pWriteAcc->SetPixel( nY, nX, aIndex );
+ }
+ }
+ }
+ else
+ {
+ for( ULONG nY = 0UL; nY < nHeight; nY++ )
+ {
+ for( ULONG nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ )
+ {
+ const BitmapColor aCol( pReadAcc->GetPixel( nY, nX ) );
+ const ULONG nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ];
+ const ULONG nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL;
+ const ULONG nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL;
+ const ULONG nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL;
+
+ aIndex.SetIndex( (BYTE) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) );
+ pWriteAcc->SetPixel( nY, nX, aIndex );
+ }
+ }
+ }
+
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+ aNewBmp.ReleaseAccess( pWriteAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplDitherFloyd( const BitmapPalette* pDitherPal )
+{
+ const Size aSize( GetSizePixel() );
+ BOOL bRet = FALSE;
+
+ if( ( aSize.Width() > 3 ) && ( aSize.Height() > 2 ) )
+ {
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ Bitmap aNewBmp( GetSizePixel(), 8 );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pReadAcc && pWriteAcc )
+ {
+ BitmapColor aColor;
+ long nWidth = pReadAcc->Width();
+ long nWidth1 = nWidth - 1L;
+ long nHeight = pReadAcc->Height();
+ long nX;
+ long nW = nWidth * 3L;
+ long nW2 = nW - 3L;
+ long nWLen = nW << 2;
+ long nRErr, nGErr, nBErr;
+ long nRC, nGC, nBC;
+ long nTemp;
+ long nZ;
+ long* p1 = new long[ nW ];
+ long* p2 = new long[ nW ];
+ long* p1T = p1;
+ long* p2T = p2;
+ long* pTmp;
+ BOOL bPal = pReadAcc->HasPalette();
+
+ pTmp = p2T;
+
+ if( bPal )
+ {
+ for( nZ = 0; nZ < nWidth; nZ++ )
+ {
+ aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( 0, nZ ) );
+
+ *pTmp++ = (long) aColor.GetBlue() << 12;
+ *pTmp++ = (long) aColor.GetGreen() << 12;
+ *pTmp++ = (long) aColor.GetRed() << 12;
+ }
+ }
+ else
+ {
+ for( nZ = 0; nZ < nWidth; nZ++ )
+ {
+ aColor = pReadAcc->GetPixel( 0, nZ );
+
+ *pTmp++ = (long) aColor.GetBlue() << 12;
+ *pTmp++ = (long) aColor.GetGreen() << 12;
+ *pTmp++ = (long) aColor.GetRed() << 12;
+ }
+ }
+
+ for( long nY = 1, nYAcc = 0L; nY <= nHeight; nY++, nYAcc++ )
+ {
+ pTmp = p1T;
+ p1T = p2T;
+ p2T = pTmp;
+
+ if( nY < nHeight )
+ {
+ if( bPal )
+ {
+ for( nZ = 0; nZ < nWidth; nZ++ )
+ {
+ aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nZ ) );
+
+ *pTmp++ = (long) aColor.GetBlue() << 12;
+ *pTmp++ = (long) aColor.GetGreen() << 12;
+ *pTmp++ = (long) aColor.GetRed() << 12;
+ }
+ }
+ else
+ {
+ for( nZ = 0; nZ < nWidth; nZ++ )
+ {
+ aColor = pReadAcc->GetPixel( nY, nZ );
+
+ *pTmp++ = (long) aColor.GetBlue() << 12;
+ *pTmp++ = (long) aColor.GetGreen() << 12;
+ *pTmp++ = (long) aColor.GetRed() << 12;
+ }
+ }
+ }
+
+ // erstes Pixel gesondert betrachten
+ nX = 0;
+ CALC_ERRORS;
+ CALC_TABLES7;
+ nX -= 5;
+ CALC_TABLES5;
+ pWriteAcc->SetPixel( nYAcc, 0, BitmapColor( (BYTE) ( nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ] ) ) );
+
+ // mittlere Pixel ueber Schleife
+ for ( long nX = 3L, nXAcc = 1L; nX < nW2; nXAcc++ )
+ {
+ CALC_ERRORS;
+ CALC_TABLES7;
+ nX -= 8;
+ CALC_TABLES3;
+ CALC_TABLES5;
+ pWriteAcc->SetPixel( nYAcc, nXAcc, BitmapColor( (BYTE) ( nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ] ) ) );
+ }
+
+ // letztes Pixel gesondert betrachten
+ CALC_ERRORS;
+ nX -= 5;
+ CALC_TABLES3;
+ CALC_TABLES5;
+ pWriteAcc->SetPixel( nYAcc, nWidth1, BitmapColor( (BYTE) ( nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ] ) ) );
+ }
+
+ delete[] p1;
+ delete[] p2;
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+ aNewBmp.ReleaseAccess( pWriteAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplDitherFloyd16()
+{
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ Bitmap aNewBmp( GetSizePixel(), 24 );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc && pWriteAcc )
+ {
+ const long nWidth = pWriteAcc->Width();
+ const long nWidth1 = nWidth - 1L;
+ const long nHeight = pWriteAcc->Height();
+ BitmapColor aColor;
+ BitmapColor aBestCol;
+ ImpErrorQuad aErrQuad;
+ ImpErrorQuad* pErrQuad1 = new ImpErrorQuad[ nWidth ];
+ ImpErrorQuad* pErrQuad2 = new ImpErrorQuad[ nWidth ];
+ ImpErrorQuad* pQLine1 = pErrQuad1;
+ ImpErrorQuad* pQLine2;
+ long nX, nY;
+ long nYTmp = 0L;
+ BOOL bQ1 = TRUE;
+
+ for( nY = 0L; nY < Min( nHeight, 2L ); nY++, nYTmp++ )
+ for( nX = 0L, pQLine2 = !nY ? pErrQuad1 : pErrQuad2; nX < nWidth; nX++ )
+ pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
+
+ for( nY = 0L; nY < nHeight; nY++, nYTmp++ )
+ {
+ // erstes ZeilenPixel
+ aBestCol = pQLine1[ 0 ].ImplGetColor();
+ aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 );
+ aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 );
+ aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 );
+ pWriteAcc->SetPixel( nY, 0, aBestCol );
+
+ for( nX = 1L; nX < nWidth1; nX++ )
+ {
+ aColor = pQLine1[ nX ].ImplGetColor();
+ aBestCol.SetRed( ( aColor.GetRed() & 248 ) | 7 );
+ aBestCol.SetGreen( ( aColor.GetGreen() & 248 ) | 7 );
+ aBestCol.SetBlue( ( aColor.GetBlue() & 248 ) | 7 );
+ aErrQuad = ( ImpErrorQuad( aColor ) -= aBestCol );
+ pQLine1[ ++nX ].ImplAddColorError7( aErrQuad );
+ pQLine2[ nX-- ].ImplAddColorError1( aErrQuad );
+ pQLine2[ nX-- ].ImplAddColorError5( aErrQuad );
+ pQLine2[ nX++ ].ImplAddColorError3( aErrQuad );
+ pWriteAcc->SetPixel( nY, nX, aBestCol );
+ }
+
+ // letztes ZeilenPixel
+ aBestCol = pQLine1[ nWidth1 ].ImplGetColor();
+ aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 );
+ aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 );
+ aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 );
+ pWriteAcc->SetPixel( nY, nX, aBestCol );
+
+ // Zeilenpuffer neu fuellen/kopieren
+ pQLine1 = pQLine2;
+ pQLine2 = ( bQ1 = !bQ1 ) ? pErrQuad2 : pErrQuad1;
+
+ if( nYTmp < nHeight )
+ for( nX = 0L; nX < nWidth; nX++ )
+ pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
+ }
+
+ // Zeilenpuffer zerstoeren
+ delete[] pErrQuad1;
+ delete[] pErrQuad2;
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+ aNewBmp.ReleaseAccess( pWriteAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ReduceColors( USHORT nColorCount, BmpReduce eReduce )
+{
+ BOOL bRet;
+
+ if( GetColorCount() <= (ULONG) nColorCount )
+ bRet = TRUE;
+ else if( nColorCount )
+ {
+ if( BMP_REDUCE_SIMPLE == eReduce )
+ bRet = ImplReduceSimple( nColorCount );
+ else if( BMP_REDUCE_POPULAR == eReduce )
+ bRet = ImplReducePopular( nColorCount );
+ else
+ bRet = ImplReduceMedian( nColorCount );
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplReduceSimple( USHORT nColorCount )
+{
+ Bitmap aNewBmp;
+ BitmapReadAccess* pRAcc = AcquireReadAccess();
+ const USHORT nColCount = Min( nColorCount, (USHORT) 256 );
+ USHORT nBitCount;
+ BOOL bRet = FALSE;
+
+ if( nColCount <= 2 )
+ nBitCount = 1;
+ else if( nColCount <= 16 )
+ nBitCount = 4;
+ else
+ nBitCount = 8;
+
+ if( pRAcc )
+ {
+ Octree aOct( *pRAcc, nColCount );
+ const BitmapPalette& rPal = aOct.GetPalette();
+ BitmapWriteAccess* pWAcc;
+
+ aNewBmp = Bitmap( GetSizePixel(), nBitCount, &rPal );
+ pWAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ const long nWidth = pRAcc->Width();
+ const long nHeight = pRAcc->Height();
+
+ if( pRAcc->HasPalette() )
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX =0L; nX < nWidth; nX++ )
+ pWAcc->SetPixel( nY, nX, (BYTE) aOct.GetBestPaletteIndex( pRAcc->GetPaletteColor( pRAcc->GetPixel( nY, nX ) ) ) );
+ }
+ else
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX =0L; nX < nWidth; nX++ )
+ pWAcc->SetPixel( nY, nX, (BYTE) aOct.GetBestPaletteIndex( pRAcc->GetPixel( nY, nX ) ) );
+ }
+
+ aNewBmp.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pRAcc );
+ }
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+struct PopularColorCount
+{
+ sal_uInt32 mnIndex;
+ sal_uInt32 mnCount;
+};
+
+// ------------------------------------------------------------------------
+
+extern "C" int __LOADONCALLAPI ImplPopularCmpFnc( const void* p1, const void* p2 )
+{
+ int nRet;
+
+ if( ( (PopularColorCount*) p1 )->mnCount < ( (PopularColorCount*) p2 )->mnCount )
+ nRet = 1;
+ else if( ( (PopularColorCount*) p1 )->mnCount == ( (PopularColorCount*) p2 )->mnCount )
+ nRet = 0;
+ else
+ nRet = -1;
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplReducePopular( USHORT nColCount )
+{
+ BitmapReadAccess* pRAcc = AcquireReadAccess();
+ USHORT nBitCount;
+ BOOL bRet = FALSE;
+
+ if( nColCount > 256 )
+ nColCount = 256;
+
+ if( nColCount < 17 )
+ nBitCount = 4;
+ else
+ nBitCount = 8;
+
+ if( pRAcc )
+ {
+ const sal_uInt32 nValidBits = 4;
+ const sal_uInt32 nRightShiftBits = 8 - nValidBits;
+ const sal_uInt32 nLeftShiftBits1 = nValidBits;
+ const sal_uInt32 nLeftShiftBits2 = nValidBits << 1;
+ const sal_uInt32 nColorsPerComponent = 1 << nValidBits;
+ const sal_uInt32 nColorOffset = 256 / nColorsPerComponent;
+ const sal_uInt32 nTotalColors = nColorsPerComponent * nColorsPerComponent * nColorsPerComponent;
+ const long nWidth = pRAcc->Width();
+ const long nHeight = pRAcc->Height();
+ PopularColorCount* pCountTable = new PopularColorCount[ nTotalColors ];
+ long nX, nY, nR, nG, nB, nIndex;
+
+ rtl_zeroMemory( pCountTable, nTotalColors * sizeof( PopularColorCount ) );
+
+ for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset )
+ for( nG = 0; nG < 256; nG += nColorOffset )
+ for( nB = 0; nB < 256; nB += nColorOffset )
+ pCountTable[ nIndex ].mnIndex = nIndex++;
+
+ if( pRAcc->HasPalette() )
+ {
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ for( nX = 0L; nX < nWidth; nX++ )
+ {
+ const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixel( nY, nX ) );
+ pCountTable[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
+ ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
+ ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++;
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ for( nX = 0L; nX < nWidth; nX++ )
+ {
+ const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) );
+ pCountTable[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
+ ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
+ ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++;
+ }
+ }
+ }
+
+ BitmapPalette aNewPal( nColCount );
+
+ qsort( pCountTable, nTotalColors, sizeof( PopularColorCount ), ImplPopularCmpFnc );
+
+ for( USHORT n = 0; n < nColCount; n++ )
+ {
+ const PopularColorCount& rPop = pCountTable[ n ];
+ aNewPal[ n ] = BitmapColor( (BYTE) ( ( rPop.mnIndex >> nLeftShiftBits2 ) << nRightShiftBits ),
+ (BYTE) ( ( ( rPop.mnIndex >> nLeftShiftBits1 ) & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ),
+ (BYTE) ( ( rPop.mnIndex & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ) );
+ }
+
+ Bitmap aNewBmp( GetSizePixel(), nBitCount, &aNewPal );
+ BitmapWriteAccess* pWAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ BitmapColor aDstCol( (BYTE) 0 );
+ BYTE* pIndexMap = new BYTE[ nTotalColors ];
+
+ for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset )
+ for( nG = 0; nG < 256; nG += nColorOffset )
+ for( nB = 0; nB < 256; nB += nColorOffset )
+ pIndexMap[ nIndex++ ] = aNewPal.GetBestIndex( BitmapColor( (BYTE) nR, (BYTE) nG, (BYTE) nB ) );
+
+ if( pRAcc->HasPalette() )
+ {
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ for( nX = 0L; nX < nWidth; nX++ )
+ {
+ const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixel( nY, nX ) );
+ aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
+ ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
+ ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ] );
+ pWAcc->SetPixel( nY, nX, aDstCol );
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0L; nY < nHeight; nY++ )
+ {
+ for( nX = 0L; nX < nWidth; nX++ )
+ {
+ const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) );
+ aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
+ ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
+ ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ] );
+ pWAcc->SetPixel( nY, nX, aDstCol );
+ }
+ }
+ }
+
+ delete[] pIndexMap;
+ aNewBmp.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ delete[] pCountTable;
+ ReleaseAccess( pRAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::ImplReduceMedian( USHORT nColCount )
+{
+ BitmapReadAccess* pRAcc = AcquireReadAccess();
+ USHORT nBitCount;
+ BOOL bRet = FALSE;
+
+ if( nColCount < 17 )
+ nBitCount = 4;
+ else if( nColCount < 257 )
+ nBitCount = 8;
+ else
+ {
+ DBG_ERROR( "Bitmap::ImplReduceMedian(): invalid color count!" );
+ nBitCount = 8;
+ nColCount = 256;
+ }
+
+ if( pRAcc )
+ {
+ Bitmap aNewBmp( GetSizePixel(), nBitCount );
+ BitmapWriteAccess* pWAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ const ULONG nSize = 32768UL * sizeof( ULONG );
+ HPULONG pColBuf = (HPULONG) SvMemAlloc( nSize );
+ const long nWidth = pWAcc->Width();
+ const long nHeight = pWAcc->Height();
+ long nIndex = 0L;
+
+ HMEMSET( (HPBYTE) pColBuf, 0, nSize );
+
+ // create Buffer
+ if( pRAcc->HasPalette() )
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixel( nY, nX ) );
+ pColBuf[ RGB15( rCol.GetRed() >> 3, rCol.GetGreen() >> 3, rCol.GetBlue() >> 3 ) ]++;
+ }
+ }
+ }
+ else
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) );
+ pColBuf[ RGB15( aCol.GetRed() >> 3, aCol.GetGreen() >> 3, aCol.GetBlue() >> 3 ) ]++;
+ }
+ }
+ }
+
+ // create palette via median cut
+ BitmapPalette aPal( pWAcc->GetPaletteEntryCount() );
+ ImplMedianCut( pColBuf, aPal, 0, 31, 0, 31, 0, 31,
+ nColCount, nWidth * nHeight, nIndex );
+
+ // do mapping of colors to palette
+ InverseColorMap aMap( aPal );
+ pWAcc->SetPalette( aPal );
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pWAcc->SetPixel( nY, nX, (BYTE) aMap.GetBestPaletteIndex( pRAcc->GetColor( nY, nX ) ) );
+
+ SvMemFree( pColBuf );
+ aNewBmp.ReleaseAccess( pWAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pRAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void Bitmap::ImplMedianCut( ULONG* pColBuf, BitmapPalette& rPal,
+ long nR1, long nR2, long nG1, long nG2, long nB1, long nB2,
+ long nColors, long nPixels, long& rIndex )
+{
+ if( !nPixels )
+ return;
+
+ BitmapColor aCol;
+ const long nRLen = nR2 - nR1;
+ const long nGLen = nG2 - nG1;
+ const long nBLen = nB2 - nB1;
+ long nR, nG, nB;
+ HPULONG pBuf = pColBuf;
+
+ if( !nRLen && !nGLen && !nBLen )
+ {
+ if( pBuf[ RGB15( nR1, nG1, nB1 ) ] )
+ {
+ aCol.SetRed( (BYTE) ( nR1 << 3 ) );
+ aCol.SetGreen( (BYTE) ( nG1 << 3 ) );
+ aCol.SetBlue( (BYTE) ( nB1 << 3 ) );
+ rPal[ (USHORT) rIndex++ ] = aCol;
+ }
+ }
+ else
+ {
+ if( 1 == nColors || 1 == nPixels )
+ {
+ long nPixSum = 0, nRSum = 0, nGSum = 0, nBSum = 0;
+
+ for( nR = nR1; nR <= nR2; nR++ )
+ {
+ for( nG = nG1; nG <= nG2; nG++ )
+ {
+ for( nB = nB1; nB <= nB2; nB++ )
+ {
+ nPixSum = pBuf[ RGB15( nR, nG, nB ) ];
+
+ if( nPixSum )
+ {
+ nRSum += nR * nPixSum;
+ nGSum += nG * nPixSum;
+ nBSum += nB * nPixSum;
+ }
+ }
+ }
+ }
+
+ aCol.SetRed( (BYTE) ( ( nRSum / nPixels ) << 3 ) );
+ aCol.SetGreen( (BYTE) ( ( nGSum / nPixels ) << 3 ) );
+ aCol.SetBlue( (BYTE) ( ( nBSum / nPixels ) << 3 ) );
+ rPal[ (USHORT) rIndex++ ] = aCol;
+ }
+ else
+ {
+ const long nTest = ( nPixels >> 1 );
+ long nPixOld, nPixNew = 0;
+
+ if( nBLen > nGLen && nBLen > nRLen )
+ {
+ nB = nB1 - 1;
+
+ while( nPixNew < nTest )
+ {
+ nB++, nPixOld = nPixNew;
+ for( nR = nR1; nR <= nR2; nR++ )
+ for( nG = nG1; nG <= nG2; nG++ )
+ nPixNew += pBuf[ RGB15( nR, nG, nB ) ];
+ }
+
+ if( nB < nB2 )
+ {
+ ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB, nColors >> 1, nPixNew, rIndex );
+ ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB + 1, nB2, nColors >> 1, nPixels - nPixNew, rIndex );
+ }
+ else
+ {
+ ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB - 1, nColors >> 1, nPixOld, rIndex );
+ ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB, nB2, nColors >> 1, nPixels - nPixOld, rIndex );
+ }
+ }
+ else if( nGLen > nRLen )
+ {
+ nG = nG1 - 1;
+
+ while( nPixNew < nTest )
+ {
+ nG++, nPixOld = nPixNew;
+ for( nR = nR1; nR <= nR2; nR++ )
+ for( nB = nB1; nB <= nB2; nB++ )
+ nPixNew += pBuf[ RGB15( nR, nG, nB ) ];
+ }
+
+ if( nG < nG2 )
+ {
+ ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG, nB1, nB2, nColors >> 1, nPixNew, rIndex );
+ ImplMedianCut( pBuf, rPal, nR1, nR2, nG + 1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex );
+ }
+ else
+ {
+ ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG - 1, nB1, nB2, nColors >> 1, nPixOld, rIndex );
+ ImplMedianCut( pBuf, rPal, nR1, nR2, nG, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex );
+ }
+ }
+ else
+ {
+ nR = nR1 - 1;
+
+ while( nPixNew < nTest )
+ {
+ nR++, nPixOld = nPixNew;
+ for( nG = nG1; nG <= nG2; nG++ )
+ for( nB = nB1; nB <= nB2; nB++ )
+ nPixNew += pBuf[ RGB15( nR, nG, nB ) ];
+ }
+
+ if( nR < nR2 )
+ {
+ ImplMedianCut( pBuf, rPal, nR1, nR, nG1, nG2, nB1, nB2, nColors >> 1, nPixNew, rIndex );
+ ImplMedianCut( pBuf, rPal, nR1 + 1, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex );
+ }
+ else
+ {
+ ImplMedianCut( pBuf, rPal, nR1, nR - 1, nG1, nG2, nB1, nB2, nColors >> 1, nPixOld, rIndex );
+ ImplMedianCut( pBuf, rPal, nR, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex );
+ }
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::Vectorize( PolyPolygon& rPolyPoly, ULONG nFlags, const Link* pProgress )
+{
+ return ImplVectorizer().ImplVectorize( *this, rPolyPoly, nFlags, pProgress );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::Vectorize( GDIMetaFile& rMtf, BYTE cReduce, ULONG nFlags, const Link* pProgress )
+{
+ return ImplVectorizer().ImplVectorize( *this, rMtf, cReduce, nFlags, pProgress );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
+ short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
+ double fGamma, BOOL bInvert )
+{
+ BOOL bRet = FALSE;
+
+ // nothing to do => return quickly
+ if( !nLuminancePercent && !nContrastPercent &&
+ !nChannelRPercent && !nChannelGPercent && !nChannelBPercent &&
+ ( fGamma == 1.0 ) && !bInvert )
+ {
+ bRet = TRUE;
+ }
+ else
+ {
+ BitmapWriteAccess* pAcc = AcquireWriteAccess();
+
+ if( pAcc )
+ {
+ BitmapColor aCol;
+ const long nW = pAcc->Width();
+ const long nH = pAcc->Height();
+ BYTE* cMapR = new BYTE[ 256 ];
+ BYTE* cMapG = new BYTE[ 256 ];
+ BYTE* cMapB = new BYTE[ 256 ];
+ long nX, nY;
+ double fM, fROff, fGOff, fBOff, fOff;
+
+ // calculate slope
+ if( nContrastPercent >= 0 )
+ fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0L, 100L ) );
+ else
+ fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0;
+
+ // total offset = luminance offset + contrast offset
+ fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0;
+
+ // channel offset = channel offset + total offset
+ fROff = nChannelRPercent * 2.55 + fOff;
+ fGOff = nChannelGPercent * 2.55 + fOff;
+ fBOff = nChannelBPercent * 2.55 + fOff;
+
+ // calculate gamma value
+ fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma );
+ const BOOL bGamma = ( fGamma != 1.0 );
+
+ // create mapping table
+ for( nX = 0L; nX < 256L; nX++ )
+ {
+ cMapR[ nX ] = (BYTE) MinMax( FRound( nX * fM + fROff ), 0L, 255L );
+ cMapG[ nX ] = (BYTE) MinMax( FRound( nX * fM + fGOff ), 0L, 255L );
+ cMapB[ nX ] = (BYTE) MinMax( FRound( nX * fM + fBOff ), 0L, 255L );
+
+ if( bGamma )
+ {
+ cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma );
+ cMapG[ nX ] = GAMMA( cMapG[ nX ], fGamma );
+ cMapB[ nX ] = GAMMA( cMapB[ nX ], fGamma );
+ }
+
+ if( bInvert )
+ {
+ cMapR[ nX ] = ~cMapR[ nX ];
+ cMapG[ nX ] = ~cMapG[ nX ];
+ cMapB[ nX ] = ~cMapB[ nX ];
+ }
+ }
+
+ // do modifying
+ if( pAcc->HasPalette() )
+ {
+ BitmapColor aNewCol;
+
+ for( USHORT i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ )
+ {
+ const BitmapColor& rCol = pAcc->GetPaletteColor( i );
+ aNewCol.SetRed( cMapR[ rCol.GetRed() ] );
+ aNewCol.SetGreen( cMapG[ rCol.GetGreen() ] );
+ aNewCol.SetBlue( cMapB[ rCol.GetBlue() ] );
+ pAcc->SetPaletteColor( i, aNewCol );
+ }
+ }
+ else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
+ {
+ for( nY = 0L; nY < nH; nY++ )
+ {
+ Scanline pScan = pAcc->GetScanline( nY );
+
+ for( nX = 0L; nX < nW; nX++ )
+ {
+ *pScan = cMapB[ *pScan ]; pScan++;
+ *pScan = cMapG[ *pScan ]; pScan++;
+ *pScan = cMapR[ *pScan ]; pScan++;
+ }
+ }
+ }
+ else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB )
+ {
+ for( nY = 0L; nY < nH; nY++ )
+ {
+ Scanline pScan = pAcc->GetScanline( nY );
+
+ for( nX = 0L; nX < nW; nX++ )
+ {
+ *pScan = cMapR[ *pScan ]; pScan++;
+ *pScan = cMapG[ *pScan ]; pScan++;
+ *pScan = cMapB[ *pScan ]; pScan++;
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0L; nY < nH; nY++ )
+ {
+ for( nX = 0L; nX < nW; nX++ )
+ {
+ aCol = pAcc->GetPixel( nY, nX );
+ aCol.SetRed( cMapR[ aCol.GetRed() ] );
+ aCol.SetGreen( cMapG[ aCol.GetGreen() ] );
+ aCol.SetBlue( cMapB[ aCol.GetBlue() ] );
+ pAcc->SetPixel( nY, nX, aCol );
+ }
+ }
+ }
+
+ delete[] cMapR;
+ delete[] cMapG;
+ delete[] cMapB;
+ ReleaseAccess( pAcc );
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
diff --git a/vcl/source/gdi/bitmap4.cxx b/vcl/source/gdi/bitmap4.cxx
new file mode 100644
index 000000000000..d959166272f5
--- /dev/null
+++ b/vcl/source/gdi/bitmap4.cxx
@@ -0,0 +1,953 @@
+/*************************************************************************
+ *
+ * $RCSfile: bitmap4.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define _SV_BITMAP_CXX
+
+#include <vos/macros.hxx>
+#include <tools/new.hxx>
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define S2(a,b) { register long t; if( ( t = b - a ) < 0 ) { a += t; b -= t; } }
+#define MN3(a,b,c) S2(a,b); S2(a,c);
+#define MX3(a,b,c) S2(b,c); S2(a,c);
+#define MNMX3(a,b,c) MX3(a,b,c); S2(a,b);
+#define MNMX4(a,b,c,d) S2(a,b); S2(c,d); S2(a,c); S2(b,d);
+#define MNMX5(a,b,c,d,e) S2(a,b); S2(c,d); MN3(a,c,e); MX3(b,d,e);
+#define MNMX6(a,b,c,d,e,f) S2(a,d); S2(b,e); S2(c,f); MN3(a,b,c); MX3(d,e,f);
+
+// ----------
+// - Bitmap -
+// ----------
+
+BOOL Bitmap::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ const USHORT nBitCount = GetBitCount();
+ BOOL bRet = FALSE;
+
+ switch( eFilter )
+ {
+ case( BMP_FILTER_SMOOTH ):
+ {
+ const long pSmoothMatrix[] = { 1, 2, 1, 2, 5, 2, 1, 2, 1 };
+ bRet = ImplConvolute3( &pSmoothMatrix[ 0 ], 17, pFilterParam, pProgress );
+ }
+ break;
+
+ case( BMP_FILTER_SHARPEN ):
+ {
+ const long pSharpenMatrix[] = { -1, -1, -1, -1, 16, -1, -1, -1, -1 };
+ bRet = ImplConvolute3( &pSharpenMatrix[ 0 ], 8, pFilterParam, pProgress );
+ }
+ break;
+
+ case( BMP_FILTER_REMOVENOISE ):
+ bRet = ImplMedianFilter( pFilterParam, pProgress );
+ break;
+
+ case( BMP_FILTER_SOBEL_GREY ):
+ bRet = ImplSobelGrey( pFilterParam, pProgress );
+ break;
+
+ case( BMP_FILTER_SOLARIZE ):
+ bRet = ImplSolarize( pFilterParam, pProgress );
+ break;
+
+ case( BMP_FILTER_SEPIA ):
+ bRet = ImplSepia( pFilterParam, pProgress );
+ break;
+
+ case( BMP_FILTER_MOSAIC ):
+ bRet = ImplMosaic( pFilterParam, pProgress );
+ break;
+
+ case( BMP_FILTER_EMBOSS_GREY ):
+ bRet = ImplEmbossGrey( pFilterParam, pProgress );
+ break;
+
+ default:
+ DBG_ERROR( "Bitmap::Convert(): Unsupported filter" );
+ break;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL Bitmap::ImplConvolute3( const long* pMatrix, long nDivisor,
+ const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc )
+ {
+ Bitmap aNewBmp( GetSizePixel(), 24 );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const long nWidth = pWriteAcc->Width(), nWidth2 = nWidth + 2;
+ const long nHeight = pWriteAcc->Height(), nHeight2 = nHeight + 2;
+ long* pColm = new long[ nWidth2 ];
+ long* pRows = new long[ nHeight2 ];
+ BitmapColor* pColRow1 = (BitmapColor*) new BYTE[ sizeof( BitmapColor ) * nWidth2 ];
+ BitmapColor* pColRow2 = (BitmapColor*) new BYTE[ sizeof( BitmapColor ) * nWidth2 ];
+ BitmapColor* pColRow3 = (BitmapColor*) new BYTE[ sizeof( BitmapColor ) * nWidth2 ];
+ BitmapColor* pRowTmp1 = pColRow1;
+ BitmapColor* pRowTmp2 = pColRow2;
+ BitmapColor* pRowTmp3 = pColRow3;
+ BitmapColor* pColor;
+ long nY, nX, i, nSumR, nSumG, nSumB, nMatrixVal, nTmp;
+ long (*pKoeff)[ 256 ] = new long[ 9 ][ 256 ];
+ long* pTmp;
+
+ // create LUT of products of matrix value and possible color component values
+ for( nY = 0; nY < 9; nY++ )
+ for( nX = nTmp = 0, nMatrixVal = pMatrix[ nY ]; nX < 256; nX++, nTmp += nMatrixVal )
+ pKoeff[ nY ][ nX ] = nTmp;
+
+ // create column LUT
+ for( i = 0; i < nWidth2; i++ )
+ pColm[ i ] = ( i > 0 ) ? ( i - 1 ) : 0;
+
+ pColm[ nWidth + 1 ] = pColm[ nWidth ];
+
+ // create row LUT
+ for( i = 0; i < nHeight2; i++ )
+ pRows[ i ] = ( i > 0 ) ? ( i - 1 ) : 0;
+
+ pRows[ nHeight + 1 ] = pRows[ nHeight ];
+
+ // read first three rows of bitmap color
+ for( i = 0; i < nWidth2; i++ )
+ {
+ pColRow1[ i ] = pReadAcc->GetColor( pRows[ 0 ], pColm[ i ] );
+ pColRow2[ i ] = pReadAcc->GetColor( pRows[ 1 ], pColm[ i ] );
+ pColRow3[ i ] = pReadAcc->GetColor( pRows[ 2 ], pColm[ i ] );
+ }
+
+ // do convolution
+ for( nY = 0; nY < nHeight; )
+ {
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ // first row
+ nSumR = ( pTmp = pKoeff[ 0 ] )[ ( pColor = pRowTmp1 + nX )->GetRed() ];
+ nSumG = pTmp[ pColor->GetGreen() ];
+ nSumB = pTmp[ pColor->GetBlue() ];
+
+ nSumR += ( pTmp = pKoeff[ 1 ] )[ ( ++pColor )->GetRed() ];
+ nSumG += pTmp[ pColor->GetGreen() ];
+ nSumB += pTmp[ pColor->GetBlue() ];
+
+ nSumR += ( pTmp = pKoeff[ 2 ] )[ ( ++pColor )->GetRed() ];
+ nSumG += pTmp[ pColor->GetGreen() ];
+ nSumB += pTmp[ pColor->GetBlue() ];
+
+ // second row
+ nSumR += ( pTmp = pKoeff[ 3 ] )[ ( pColor = pRowTmp2 + nX )->GetRed() ];
+ nSumG += pTmp[ pColor->GetGreen() ];
+ nSumB += pTmp[ pColor->GetBlue() ];
+
+ nSumR += ( pTmp = pKoeff[ 4 ] )[ ( ++pColor )->GetRed() ];
+ nSumG += pTmp[ pColor->GetGreen() ];
+ nSumB += pTmp[ pColor->GetBlue() ];
+
+ nSumR += ( pTmp = pKoeff[ 5 ] )[ ( ++pColor )->GetRed() ];
+ nSumG += pTmp[ pColor->GetGreen() ];
+ nSumB += pTmp[ pColor->GetBlue() ];
+
+ // third row
+ nSumR += ( pTmp = pKoeff[ 6 ] )[ ( pColor = pRowTmp3 + nX )->GetRed() ];
+ nSumG += pTmp[ pColor->GetGreen() ];
+ nSumB += pTmp[ pColor->GetBlue() ];
+
+ nSumR += ( pTmp = pKoeff[ 7 ] )[ ( ++pColor )->GetRed() ];
+ nSumG += pTmp[ pColor->GetGreen() ];
+ nSumB += pTmp[ pColor->GetBlue() ];
+
+ nSumR += ( pTmp = pKoeff[ 8 ] )[ ( ++pColor )->GetRed() ];
+ nSumG += pTmp[ pColor->GetGreen() ];
+ nSumB += pTmp[ pColor->GetBlue() ];
+
+ // calculate destination color
+ pWriteAcc->SetPixel( nY, nX, BitmapColor( (BYTE) MinMax( nSumR / nDivisor, 0, 255 ),
+ (BYTE) MinMax( nSumG / nDivisor, 0, 255 ),
+ (BYTE) MinMax( nSumB / nDivisor, 0, 255 ) ) );
+ }
+
+ if( ++nY < nHeight )
+ {
+ if( pRowTmp1 == pColRow1 )
+ pRowTmp1 = pColRow2, pRowTmp2 = pColRow3, pRowTmp3 = pColRow1;
+ else if( pRowTmp1 == pColRow2 )
+ pRowTmp1 = pColRow3, pRowTmp2 = pColRow1, pRowTmp3 = pColRow2;
+ else
+ pRowTmp1 = pColRow1, pRowTmp2 = pColRow2, pRowTmp3 = pColRow3;
+
+ for( i = 0; i < nWidth2; i++ )
+ pRowTmp3[ i ] = pReadAcc->GetColor( pRows[ nY + 2 ], pColm[ i ] );
+ }
+ }
+
+ delete[] pKoeff;
+ delete[] (BYTE*) pColRow1;
+ delete[] (BYTE*) pColRow2;
+ delete[] (BYTE*) pColRow3;
+ delete[] pColm;
+ delete[] pRows;
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL Bitmap::ImplMedianFilter( const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc )
+ {
+ Bitmap aNewBmp( GetSizePixel(), 24 );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const long nWidth = pWriteAcc->Width(), nWidth2 = nWidth + 2;
+ const long nHeight = pWriteAcc->Height(), nHeight2 = nHeight + 2;
+ long* pColm = new long[ nWidth2 ];
+ long* pRows = new long[ nHeight2 ];
+ BitmapColor* pColRow1 = (BitmapColor*) new BYTE[ sizeof( BitmapColor ) * nWidth2 ];
+ BitmapColor* pColRow2 = (BitmapColor*) new BYTE[ sizeof( BitmapColor ) * nWidth2 ];
+ BitmapColor* pColRow3 = (BitmapColor*) new BYTE[ sizeof( BitmapColor ) * nWidth2 ];
+ BitmapColor* pRowTmp1 = pColRow1;
+ BitmapColor* pRowTmp2 = pColRow2;
+ BitmapColor* pRowTmp3 = pColRow3;
+ BitmapColor* pColor;
+ long nY, nX, i;
+ long nR1, nR2, nR3, nR4, nR5, nR6, nR7, nR8, nR9;
+ long nG1, nG2, nG3, nG4, nG5, nG6, nG7, nG8, nG9;
+ long nB1, nB2, nB3, nB4, nB5, nB6, nB7, nB8, nB9;
+
+ // create column LUT
+ for( i = 0; i < nWidth2; i++ )
+ pColm[ i ] = ( i > 0 ) ? ( i - 1 ) : 0;
+
+ pColm[ nWidth + 1 ] = pColm[ nWidth ];
+
+ // create row LUT
+ for( i = 0; i < nHeight2; i++ )
+ pRows[ i ] = ( i > 0 ) ? ( i - 1 ) : 0;
+
+ pRows[ nHeight + 1 ] = pRows[ nHeight ];
+
+ // read first three rows of bitmap color
+ for( i = 0; i < nWidth2; i++ )
+ {
+ pColRow1[ i ] = pReadAcc->GetColor( pRows[ 0 ], pColm[ i ] );
+ pColRow2[ i ] = pReadAcc->GetColor( pRows[ 1 ], pColm[ i ] );
+ pColRow3[ i ] = pReadAcc->GetColor( pRows[ 2 ], pColm[ i ] );
+ }
+
+ // do median filtering
+ for( nY = 0; nY < nHeight; )
+ {
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ nR1 = ( pColor = pRowTmp1 + nX )->GetRed(), nG1 = pColor->GetGreen(), nB1 = pColor->GetBlue();
+ nR2 = ( ++pColor )->GetRed(), nG2 = pColor->GetGreen(), nB2 = pColor->GetBlue();
+ nR3 = ( ++pColor )->GetRed(), nG3 = pColor->GetGreen(), nB3 = pColor->GetBlue();
+
+ nR4 = ( pColor = pRowTmp2 + nX )->GetRed(), nG4 = pColor->GetGreen(), nB4 = pColor->GetBlue();
+ nR5 = ( ++pColor )->GetRed(), nG5 = pColor->GetGreen(), nB5 = pColor->GetBlue();
+ nR6 = ( ++pColor )->GetRed(), nG6 = pColor->GetGreen(), nB6 = pColor->GetBlue();
+
+ nR7 = ( pColor = pRowTmp3 + nX )->GetRed(), nG7 = pColor->GetGreen(), nB7 = pColor->GetBlue();
+ nR8 = ( ++pColor )->GetRed(), nG8 = pColor->GetGreen(), nB8 = pColor->GetBlue();
+ nR9 = ( ++pColor )->GetRed(), nG9 = pColor->GetGreen(), nB9 = pColor->GetBlue();
+
+ MNMX6( nR1, nR2, nR3, nR4, nR5, nR6 );
+ MNMX5( nR7, nR2, nR3, nR4, nR5 );
+ MNMX4( nR8, nR2, nR3, nR4 );
+ MNMX3( nR9, nR2, nR3 );
+
+ MNMX6( nG1, nG2, nG3, nG4, nG5, nG6 );
+ MNMX5( nG7, nG2, nG3, nG4, nG5 );
+ MNMX4( nG8, nG2, nG3, nG4 );
+ MNMX3( nG9, nG2, nG3 );
+
+ MNMX6( nB1, nB2, nB3, nB4, nB5, nB6 );
+ MNMX5( nB7, nB2, nB3, nB4, nB5 );
+ MNMX4( nB8, nB2, nB3, nB4 );
+ MNMX3( nB9, nB2, nB3 );
+
+ // set destination color
+ pWriteAcc->SetPixel( nY, nX, BitmapColor( (BYTE) nR2, (BYTE) nG2, (BYTE) nB2 ) );
+ }
+
+ if( ++nY < nHeight )
+ {
+ if( pRowTmp1 == pColRow1 )
+ pRowTmp1 = pColRow2, pRowTmp2 = pColRow3, pRowTmp3 = pColRow1;
+ else if( pRowTmp1 == pColRow2 )
+ pRowTmp1 = pColRow3, pRowTmp2 = pColRow1, pRowTmp3 = pColRow2;
+ else
+ pRowTmp1 = pColRow1, pRowTmp2 = pColRow2, pRowTmp3 = pColRow3;
+
+ for( i = 0; i < nWidth2; i++ )
+ pRowTmp3[ i ] = pReadAcc->GetColor( pRows[ nY + 2 ], pColm[ i ] );
+ }
+ }
+
+ delete[] (BYTE*) pColRow1;
+ delete[] (BYTE*) pColRow2;
+ delete[] (BYTE*) pColRow3;
+ delete[] pColm;
+ delete[] pRows;
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL Bitmap::ImplSobelGrey( const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ BOOL bRet = ImplMakeGreyscales( 256 );
+
+ if( bRet )
+ {
+ bRet = FALSE;
+
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+
+ if( pReadAcc )
+ {
+ Bitmap aNewBmp( GetSizePixel(), 8, &pReadAcc->GetPalette() );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ BitmapColor aGrey( (BYTE) 0 );
+ const long nWidth = pWriteAcc->Width();
+ const long nHeight = pWriteAcc->Height();
+ const long nMask111 = -1, nMask121 = 0, nMask131 = 1;
+ const long nMask211 = -2, nMask221 = 0, nMask231 = 2;
+ const long nMask311 = -1, nMask321 = 0, nMask331 = 1;
+ const long nMask112 = 1, nMask122 = 2, nMask132 = 1;
+ const long nMask212 = 0, nMask222 = 0, nMask232 = 0;
+ const long nMask312 = -1, nMask322 = -2, nMask332 = -1;
+ long nGrey11, nGrey12, nGrey13;
+ long nGrey21, nGrey22, nGrey23;
+ long nGrey31, nGrey32, nGrey33;
+ long* pHMap = new long[ nWidth + 2 ];
+ long* pVMap = new long[ nHeight + 2 ];
+ long nX, nY, nSum1, nSum2;
+
+ // fill mapping tables
+ pHMap[ 0 ] = 0;
+ for( nX = 1; nX <= nWidth; nX++ )
+ pHMap[ nX ] = nX - 1;
+ pHMap[ nWidth + 1 ] = nWidth - 1;
+
+ pVMap[ 0 ] = 0;
+ for( nY = 1; nY <= nHeight; nY++ )
+ pVMap[ nY ] = nY - 1;
+ pVMap[ nHeight + 1 ] = nHeight - 1;
+
+ for( nY = 0; nY < nHeight ; nY++ )
+ {
+ nGrey11 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 0 ] ).GetIndex();
+ nGrey12 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 1 ] ).GetIndex();
+ nGrey13 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 2 ] ).GetIndex();
+ nGrey21 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 0 ] ).GetIndex();
+ nGrey22 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 1 ] ).GetIndex();
+ nGrey23 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 2 ] ).GetIndex();
+ nGrey31 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 0 ] ).GetIndex();
+ nGrey32 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 1 ] ).GetIndex();
+ nGrey33 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 2 ] ).GetIndex();
+
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ nSum1 = nSum2 = 0;
+
+ nSum1 += nMask111 * nGrey11;
+ nSum2 += nMask112 * nGrey11;
+
+ nSum1 += nMask121 * nGrey12;
+ nSum2 += nMask122 * nGrey12;
+
+ nSum1 += nMask131 * nGrey13;
+ nSum2 += nMask132 * nGrey13;
+
+ nSum1 += nMask211 * nGrey21;
+ nSum2 += nMask212 * nGrey21;
+
+ nSum1 += nMask221 * nGrey22;
+ nSum2 += nMask222 * nGrey22;
+
+ nSum1 += nMask231 * nGrey23;
+ nSum2 += nMask232 * nGrey23;
+
+ nSum1 += nMask311 * nGrey31;
+ nSum2 += nMask312 * nGrey31;
+
+ nSum1 += nMask321 * nGrey32;
+ nSum2 += nMask322 * nGrey32;
+
+ nSum1 += nMask331 * nGrey33;
+ nSum2 += nMask332 * nGrey33;
+
+ nSum1 = (long) sqrt( ( nSum1 * nSum1 + nSum2 * nSum2 ) );
+ aGrey.SetIndex( ~(BYTE) VOS_BOUND( nSum1, 0, 255 ) );
+ pWriteAcc->SetPixel( nY, nX, aGrey );
+
+ if( nX < ( nWidth - 1 ) )
+ {
+ const long nNextX = pHMap[ nX + 3 ];
+
+ nGrey11 = nGrey12; nGrey12 = nGrey13; nGrey13 = pReadAcc->GetPixel( pVMap[ nY ], nNextX ).GetIndex();
+ nGrey21 = nGrey22; nGrey22 = nGrey23; nGrey23 = pReadAcc->GetPixel( pVMap[ nY + 1 ], nNextX ).GetIndex();
+ nGrey31 = nGrey32; nGrey32 = nGrey33; nGrey33 = pReadAcc->GetPixel( pVMap[ nY + 2 ], nNextX ).GetIndex();
+ }
+ }
+ }
+
+ delete[] pHMap;
+ delete[] pVMap;
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL Bitmap::ImplEmbossGrey( const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ BOOL bRet = ImplMakeGreyscales( 256 );
+
+ if( bRet )
+ {
+ bRet = FALSE;
+
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+
+ if( pReadAcc )
+ {
+ Bitmap aNewBmp( GetSizePixel(), 8, &pReadAcc->GetPalette() );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ BitmapColor aGrey( (BYTE) 0 );
+ const long nWidth = pWriteAcc->Width();
+ const long nHeight = pWriteAcc->Height();
+ long nGrey11, nGrey12, nGrey13;
+ long nGrey21, nGrey22, nGrey23;
+ long nGrey31, nGrey32, nGrey33;
+ double fAzim = ( ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_EMBOSS_GREY ) ?
+ ( pFilterParam->maEmbossAngles.mnAzimuthAngle100 * 0.01 ) : 0.0 ) * F_PI180;
+ double fElev = ( ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_EMBOSS_GREY ) ?
+ ( pFilterParam->maEmbossAngles.mnElevationAngle100 * 0.01 ) : 90.0 ) * F_PI180;
+ long* pHMap = new long[ nWidth + 2 ];
+ long* pVMap = new long[ nHeight + 2 ];
+ long nX, nY, nNx, nNy, nDotL;
+ const long nLx = FRound( cos( fAzim ) * cos( fElev ) * 255.0 );
+ const long nLy = FRound( sin( fAzim ) * cos( fElev ) * 255.0 );
+ const long nLz = FRound( sin( fElev ) * 255.0 );
+ const long nZ2 = ( ( 6 * 255 ) / 4 ) * ( ( 6 * 255 ) / 4 );
+ const long nNzLz = ( ( 6 * 255 ) / 4 ) * nLz;
+ const BYTE cLz = (BYTE) VOS_BOUND( nLz, 0, 255 );
+
+ // fill mapping tables
+ pHMap[ 0 ] = 0;
+ for( nX = 1; nX <= nWidth; nX++ )
+ pHMap[ nX ] = nX - 1;
+ pHMap[ nWidth + 1 ] = nWidth - 1;
+
+ pVMap[ 0 ] = 0;
+ for( nY = 1; nY <= nHeight; nY++ )
+ pVMap[ nY ] = nY - 1;
+ pVMap[ nHeight + 1 ] = nHeight - 1;
+
+ for( nY = 0; nY < nHeight ; nY++ )
+ {
+ nGrey11 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 0 ] ).GetIndex();
+ nGrey12 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 1 ] ).GetIndex();
+ nGrey13 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 2 ] ).GetIndex();
+ nGrey21 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 0 ] ).GetIndex();
+ nGrey22 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 1 ] ).GetIndex();
+ nGrey23 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 2 ] ).GetIndex();
+ nGrey31 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 0 ] ).GetIndex();
+ nGrey32 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 1 ] ).GetIndex();
+ nGrey33 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 2 ] ).GetIndex();
+
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ nNx = nGrey11 + nGrey21 + nGrey31 - nGrey13 - nGrey23 - nGrey33;
+ nNy = nGrey31 + nGrey32 + nGrey33 - nGrey11 - nGrey12 - nGrey13;
+
+ if( !nNx && !nNy )
+ aGrey.SetIndex( cLz );
+ else if( ( nDotL = nNx * nLx + nNy * nLy +nNzLz ) < 0 )
+ aGrey.SetIndex( 0 );
+ else
+ {
+ const double fGrey = nDotL / sqrt( nNx * nNx + nNy * nNy + nZ2 );
+ aGrey.SetIndex( (BYTE) VOS_BOUND( fGrey, 0, 255 ) );
+ }
+
+ pWriteAcc->SetPixel( nY, nX, aGrey );
+
+ if( nX < ( nWidth - 1 ) )
+ {
+ const long nNextX = pHMap[ nX + 3 ];
+
+ nGrey11 = nGrey12; nGrey12 = nGrey13; nGrey13 = pReadAcc->GetPixel( pVMap[ nY ], nNextX ).GetIndex();
+ nGrey21 = nGrey22; nGrey22 = nGrey23; nGrey23 = pReadAcc->GetPixel( pVMap[ nY + 1 ], nNextX ).GetIndex();
+ nGrey31 = nGrey32; nGrey32 = nGrey33; nGrey33 = pReadAcc->GetPixel( pVMap[ nY + 2 ], nNextX ).GetIndex();
+ }
+ }
+ }
+
+ delete[] pHMap;
+ delete[] pVMap;
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL Bitmap::ImplSolarize( const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ BOOL bRet = FALSE;
+ BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ const BYTE cThreshold = ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_SOLARIZE ) ?
+ pFilterParam->mcSolarGreyThreshold : 128;
+
+ if( pWriteAcc->HasPalette() )
+ {
+ const BitmapPalette& rPal = pWriteAcc->GetPalette();
+
+ for( USHORT i = 0, nCount = rPal.GetEntryCount(); i < nCount; i++ )
+ {
+ if( rPal[ i ].GetLuminance() >= cThreshold )
+ {
+ BitmapColor aCol( rPal[ i ] );
+ pWriteAcc->SetPaletteColor( i, aCol.Invert() );
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aCol;
+ const long nWidth = pWriteAcc->Width();
+ const long nHeight = pWriteAcc->Height();
+
+ for( long nY = 0; nY < nHeight ; nY++ )
+ {
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ aCol = pWriteAcc->GetPixel( nY, nX );
+
+ if( aCol.GetLuminance() >= cThreshold )
+ pWriteAcc->SetPixel( nY, nX, aCol.Invert() );
+ }
+ }
+ }
+
+ ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL Bitmap::ImplSepia( const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ BOOL bRet = FALSE;
+
+ if( pReadAcc )
+ {
+ long nSepiaPercent = ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_SEPIA ) ?
+ pFilterParam->mcSolarGreyThreshold : 10;
+ const long nSepia = 10000 - 100 * VOS_BOUND( nSepiaPercent, 0, 100 );
+ BitmapPalette aSepiaPal( 256 );
+
+ DBG_ASSERT( nSepiaPercent <= 100, "Bitmap::ImplSepia(): sepia value out of range; defaulting to 100%" );
+
+ for( long i = 0; i < 256; i++ )
+ {
+ BitmapColor& rCol = aSepiaPal[ i ];
+ const BYTE cSepiaValue = (BYTE) ( ( nSepia * i ) / 10000 );
+
+ rCol.SetRed( (BYTE) i );
+ rCol.SetGreen( cSepiaValue );
+ rCol.SetBlue( cSepiaValue );
+ }
+
+ Bitmap aNewBmp( GetSizePixel(), 8, &aSepiaPal );
+ BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
+
+ if( pWriteAcc )
+ {
+ BitmapColor aCol( (BYTE) 0 );
+ const long nWidth = pWriteAcc->Width();
+ const long nHeight = pWriteAcc->Height();
+
+ if( pReadAcc->HasPalette() )
+ {
+ for( long nY = 0; nY < nHeight ; nY++ )
+ {
+ const USHORT nPalCount = pReadAcc->GetPaletteEntryCount();
+ BYTE* pIndexMap = new BYTE[ nPalCount ];
+
+ for( USHORT i = 0; i < nPalCount; i++ )
+ pIndexMap[ i ] = pReadAcc->GetPaletteColor( i ).GetLuminance();
+
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ aCol.SetIndex( pIndexMap[ pReadAcc->GetPixel( nY, nX ).GetIndex() ] );
+ pWriteAcc->SetPixel( nY, nX, aCol );
+ }
+
+ delete[] pIndexMap;
+ }
+ }
+ else
+ {
+ for( long nY = 0; nY < nHeight ; nY++ )
+ {
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ aCol.SetIndex( pReadAcc->GetPixel( nY, nX ).GetLuminance() );
+ pWriteAcc->SetPixel( nY, nX, aCol );
+ }
+ }
+ }
+
+ aNewBmp.ReleaseAccess( pWriteAcc );
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = aNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL Bitmap::ImplMosaic( const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ ULONG nTileWidth = ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_MOSAIC ) ?
+ pFilterParam->maMosaicTileSize.mnTileWidth : 4;
+ ULONG nTileHeight = ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_MOSAIC ) ?
+ pFilterParam->maMosaicTileSize.mnTileHeight : 4;
+ BOOL bRet = FALSE;
+
+ if( !nTileWidth )
+ nTileWidth = 1;
+
+ if( !nTileHeight )
+ nTileHeight = 1;
+
+ if( nTileWidth > 1 || nTileHeight > 1 )
+ {
+ Bitmap* pNewBmp;
+ BitmapReadAccess* pReadAcc;
+ BitmapWriteAccess* pWriteAcc;
+
+ if( GetBitCount() > 8 )
+ {
+ pNewBmp = NULL;
+ pReadAcc = pWriteAcc = AcquireWriteAccess();
+ }
+ else
+ {
+ pNewBmp = new Bitmap( GetSizePixel(), 24 );
+ pReadAcc = AcquireReadAccess();
+ pWriteAcc = pNewBmp->AcquireWriteAccess();
+ }
+
+ if( pReadAcc && pWriteAcc )
+ {
+ BitmapColor aCol;
+ long nWidth = pReadAcc->Width();
+ long nHeight = pReadAcc->Height();
+ long nX, nY, nX1, nX2, nY1, nY2, nSumR, nSumG, nSumB;
+ double fArea_1;
+
+ nY1 = 0; nY2 = nTileHeight - 1;
+
+ if( nY2 >= nHeight )
+ nY2 = nHeight - 1;
+
+ do
+ {
+ nX1 = 0; nX2 = nTileWidth - 1;
+
+ if( nX2 >= nWidth )
+ nX2 = nWidth - 1;
+
+ fArea_1 = 1.0 / ( ( nX2 - nX1 + 1 ) * ( nY2 - nY1 + 1 ) );
+
+ if( !pNewBmp )
+ {
+ do
+ {
+ for( nY = nY1, nSumR = nSumG = nSumB = 0; nY <= nY2; nY++ )
+ {
+ for( nX = nX1; nX <= nX2; nX++ )
+ {
+ aCol = pReadAcc->GetPixel( nY, nX );
+ nSumR += aCol.GetRed();
+ nSumG += aCol.GetGreen();
+ nSumB += aCol.GetBlue();
+ }
+ }
+
+ aCol.SetRed( (BYTE) ( nSumR * fArea_1 ) );
+ aCol.SetGreen( (BYTE) ( nSumG * fArea_1 ) );
+ aCol.SetBlue( (BYTE) ( nSumB * fArea_1 ) );
+
+ for( nY = nY1; nY <= nY2; nY++ )
+ for( nX = nX1; nX <= nX2; nX++ )
+ pWriteAcc->SetPixel( nY, nX, aCol );
+
+ nX1 += nTileWidth; nX2 += nTileWidth;
+
+ if( nX2 >= nWidth )
+ {
+ nX2 = nWidth - 1;
+ fArea_1 = 1.0 / ( ( nX2 - nX1 + 1 ) * ( nY2 - nY1 + 1 ) );
+ }
+ }
+ while( nX1 < nWidth );
+ }
+ else
+ {
+ do
+ {
+ for( nY = nY1, nSumR = nSumG = nSumB = 0; nY <= nY2; nY++ )
+ {
+ for( nX = nX1; nX <= nX2; nX++ )
+ {
+ const BitmapColor& rCol = pReadAcc->GetPaletteColor( (BYTE) pReadAcc->GetPixel( nY, nX ) );
+ nSumR += rCol.GetRed();
+ nSumG += rCol.GetGreen();
+ nSumB += rCol.GetBlue();
+ }
+ }
+
+ aCol.SetRed( (BYTE) ( nSumR * fArea_1 ) );
+ aCol.SetGreen( (BYTE) ( nSumG * fArea_1 ) );
+ aCol.SetBlue( (BYTE) ( nSumB * fArea_1 ) );
+
+ for( nY = nY1; nY <= nY2; nY++ )
+ for( nX = nX1; nX <= nX2; nX++ )
+ pWriteAcc->SetPixel( nY, nX, aCol );
+
+ nX1 += nTileWidth; nX2 += nTileWidth;
+
+ if( nX2 >= nWidth )
+ {
+ nX2 = nWidth - 1;
+ fArea_1 = 1.0 / ( ( nX2 - nX1 + 1 ) * ( nY2 - nY1 + 1 ) );
+ }
+ }
+ while( nX1 < nWidth );
+ }
+
+ nY1 += nTileHeight; nY2 += nTileHeight;
+
+ if( nY2 >= nHeight )
+ nY2 = nHeight - 1;
+ }
+ while( nY1 < nHeight );
+
+ bRet = TRUE;
+ }
+
+ ReleaseAccess( pReadAcc );
+
+ if( pNewBmp )
+ {
+ pNewBmp->ReleaseAccess( pWriteAcc );
+
+ if( bRet )
+ {
+ const MapMode aMap( maPrefMapMode );
+ const Size aSize( maPrefSize );
+
+ *this = *pNewBmp;
+
+ maPrefMapMode = aMap;
+ maPrefSize = aSize;
+ }
+
+ delete pNewBmp;
+ }
+ }
+ else
+ bRet = TRUE;
+
+ return bRet;
+}
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
new file mode 100644
index 000000000000..a0e388a1db0f
--- /dev/null
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -0,0 +1,690 @@
+/*************************************************************************
+ *
+ * $RCSfile: bitmapex.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_BITMAPEX_CXX
+
+#ifndef _RTL_CRC_H_
+#include <rtl/crc.h>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_ALPHA_HXX
+#include <alpha.hxx>
+#endif
+#ifndef _SV_BITMAPEX_HXX
+#include <bitmapex.hxx>
+#endif
+
+// ------------
+// - BitmapEx -
+// ------------
+
+BitmapEx::BitmapEx() :
+ eTransparent( TRANSPARENT_NONE ),
+ bAlpha ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------
+
+BitmapEx::BitmapEx( const BitmapEx& rBitmapEx ) :
+ aBitmap ( rBitmapEx.aBitmap ),
+ aMask ( rBitmapEx.aMask ),
+ aBitmapSize ( rBitmapEx.aBitmapSize ),
+ aTransparentColor ( rBitmapEx.aTransparentColor ),
+ eTransparent ( rBitmapEx.eTransparent ),
+ bAlpha ( rBitmapEx.bAlpha )
+{
+}
+
+// ------------------------------------------------------------------
+
+BitmapEx::BitmapEx( const Bitmap& rBmp ) :
+ aBitmap ( rBmp ),
+ aBitmapSize ( aBitmap.GetSizePixel() ),
+ eTransparent( TRANSPARENT_NONE ),
+ bAlpha ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------
+
+BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) :
+ aBitmap ( rBmp ),
+ aMask ( rMask ),
+ aBitmapSize ( aBitmap.GetSizePixel() ),
+ eTransparent ( !rMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
+ bAlpha ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------
+
+BitmapEx::BitmapEx( const Bitmap& rBmp, const AlphaMask& rAlphaMask ) :
+ aBitmap ( rBmp ),
+ aMask ( rAlphaMask.ImplGetBitmap() ),
+ aBitmapSize ( aBitmap.GetSizePixel() ),
+ eTransparent ( !rAlphaMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
+ bAlpha ( !rAlphaMask ? FALSE : TRUE )
+{
+}
+
+// ------------------------------------------------------------------
+
+BitmapEx::BitmapEx( const Bitmap& rBmp, const Color& rTransparentColor ) :
+ aBitmap ( rBmp ),
+ aBitmapSize ( aBitmap.GetSizePixel() ),
+ aTransparentColor ( rTransparentColor ),
+ eTransparent ( TRANSPARENT_BITMAP ),
+ bAlpha ( FALSE )
+{
+ aMask = aBitmap.CreateMask( aTransparentColor );
+}
+
+// ------------------------------------------------------------------
+
+BitmapEx::~BitmapEx()
+{
+}
+
+// ------------------------------------------------------------------
+
+BitmapEx& BitmapEx::operator=( const BitmapEx& rBitmapEx )
+{
+ if( &rBitmapEx != this )
+ {
+ aBitmap = rBitmapEx.aBitmap;
+ aMask = rBitmapEx.aMask;
+ aBitmapSize = rBitmapEx.aBitmapSize;
+ aTransparentColor = rBitmapEx.aTransparentColor;
+ eTransparent = rBitmapEx.eTransparent;
+ bAlpha = rBitmapEx.bAlpha;
+ }
+
+ return *this;
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::operator==( const BitmapEx& rBitmapEx ) const
+{
+ if( eTransparent != rBitmapEx.eTransparent )
+ return FALSE;
+
+ if( aBitmap != rBitmapEx.aBitmap )
+ return FALSE;
+
+ if( aBitmapSize != rBitmapEx.aBitmapSize )
+ return FALSE;
+
+ if( eTransparent == TRANSPARENT_NONE )
+ return TRUE;
+
+ if( eTransparent == TRANSPARENT_COLOR )
+ return aTransparentColor == rBitmapEx.aTransparentColor;
+
+ return( ( aMask == rBitmapEx.aMask ) && ( bAlpha == rBitmapEx.bAlpha ) );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::IsEqual( const BitmapEx& rBmpEx ) const
+{
+ return( rBmpEx.eTransparent == eTransparent &&
+ rBmpEx.bAlpha == bAlpha &&
+ rBmpEx.aBitmap.IsEqual( aBitmap ) &&
+ rBmpEx.aMask.IsEqual( aMask ) );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::IsEmpty() const
+{
+ return( aBitmap.IsEmpty() && aMask.IsEmpty() );
+}
+
+// ------------------------------------------------------------------
+
+void BitmapEx::SetEmpty()
+{
+ aBitmap.SetEmpty();
+ aMask.SetEmpty();
+ eTransparent = TRANSPARENT_NONE;
+ bAlpha = FALSE;
+}
+
+// ------------------------------------------------------------------
+
+void BitmapEx::Clear()
+{
+ SetEmpty();
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::IsTransparent() const
+{
+ return( eTransparent != TRANSPARENT_NONE );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::IsAlpha() const
+{
+ return( IsTransparent() && bAlpha );
+}
+
+// ------------------------------------------------------------------
+
+Bitmap BitmapEx::GetBitmap( const Color* pTransReplaceColor ) const
+{
+ Bitmap aRetBmp( aBitmap );
+
+ if( pTransReplaceColor && ( eTransparent != TRANSPARENT_NONE ) )
+ {
+ Bitmap aTempMask;
+
+ if( eTransparent == TRANSPARENT_COLOR )
+ aTempMask = aBitmap.CreateMask( aTransparentColor );
+ else
+ aTempMask = aMask;
+
+ if( !IsAlpha() )
+ aRetBmp.Replace( aTempMask, *pTransReplaceColor );
+ else
+ aRetBmp.Replace( GetAlpha(), *pTransReplaceColor );
+ }
+
+ return aRetBmp;
+}
+
+// ------------------------------------------------------------------
+
+Bitmap BitmapEx::GetMask() const
+{
+ Bitmap aRet( aMask );
+
+ if( IsAlpha() )
+ aRet.ImplMakeMono( 255 );
+
+ return aRet;
+}
+
+// ------------------------------------------------------------------
+
+AlphaMask BitmapEx::GetAlpha() const
+{
+ AlphaMask aAlpha;
+
+ if( IsAlpha() )
+ aAlpha.ImplSetBitmap( aMask );
+ else
+ aAlpha = aMask;
+
+ return aAlpha;
+}
+
+// ------------------------------------------------------------------
+
+ULONG BitmapEx::GetSizeBytes() const
+{
+ ULONG nSizeBytes = aBitmap.GetSizeBytes();
+
+ if( eTransparent == TRANSPARENT_BITMAP )
+ nSizeBytes += aMask.GetSizeBytes();
+
+ return nSizeBytes;
+}
+
+// ------------------------------------------------------------------
+
+ULONG BitmapEx::GetChecksum() const
+{
+ sal_uInt32 nCrc = aBitmap.GetChecksum();
+ SVBT32 aBT32;
+
+ LongToSVBT32( (long) eTransparent, aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( (long) bAlpha, aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ if( ( TRANSPARENT_BITMAP == eTransparent ) && !aMask.IsEmpty() )
+ {
+ LongToSVBT32( aMask.GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+
+ return nCrc;
+}
+
+// ------------------------------------------------------------------
+
+void BitmapEx::SetSizePixel( const Size& rNewSize )
+{
+ Scale( rNewSize );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Invert()
+{
+ BOOL bRet = FALSE;
+
+ if( !!aBitmap )
+ {
+ bRet = aBitmap.Invert();
+
+ if( bRet && ( eTransparent == TRANSPARENT_COLOR ) )
+ aTransparentColor = BitmapColor( aTransparentColor ).Invert();
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Mirror( ULONG nMirrorFlags )
+{
+ BOOL bRet = FALSE;
+
+ if( !!aBitmap )
+ {
+ bRet = aBitmap.Mirror( nMirrorFlags );
+
+ if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
+ aMask.Mirror( nMirrorFlags );
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Scale( const double& rScaleX, const double& rScaleY, ULONG nScaleFlag )
+{
+ BOOL bRet = FALSE;
+
+ if( !!aBitmap )
+ {
+ bRet = aBitmap.Scale( rScaleX, rScaleY, nScaleFlag );
+
+ if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
+ aMask.Scale( rScaleX, rScaleY, BMP_SCALE_FAST );
+
+ aBitmapSize = aBitmap.GetSizePixel();
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL BitmapEx::Scale( const Size& rNewSize, ULONG nScaleFlag )
+{
+ BOOL bRet;
+
+ if( aBitmapSize.Width() && aBitmapSize.Height() )
+ {
+ bRet = Scale( (double) rNewSize.Width() / aBitmapSize.Width(),
+ (double) rNewSize.Height() / aBitmapSize.Height(),
+ nScaleFlag );
+ }
+ else
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Rotate( long nAngle10, const Color& rFillColor )
+{
+ BOOL bRet = FALSE;
+
+ if( !!aBitmap )
+ {
+ const BOOL bTransRotate = ( Color( COL_TRANSPARENT ) == rFillColor );
+
+ if( bTransRotate )
+ {
+ if( eTransparent == TRANSPARENT_COLOR )
+ bRet = aBitmap.Rotate( nAngle10, aTransparentColor );
+ else
+ {
+ bRet = aBitmap.Rotate( nAngle10, COL_BLACK );
+
+ if( eTransparent == TRANSPARENT_NONE )
+ {
+ aMask = Bitmap( aBitmapSize, 1 );
+ aMask.Erase( COL_BLACK );
+ eTransparent = TRANSPARENT_BITMAP;
+ }
+
+ if( bRet && !!aMask )
+ aMask.Rotate( nAngle10, COL_WHITE );
+ }
+ }
+ else
+ {
+ bRet = aBitmap.Rotate( nAngle10, rFillColor );
+
+ if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
+ aMask.Rotate( nAngle10, COL_WHITE );
+ }
+
+ aBitmapSize = aBitmap.GetSizePixel();
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Crop( const Rectangle& rRectPixel )
+{
+ BOOL bRet = FALSE;
+
+ if( !!aBitmap )
+ {
+ bRet = aBitmap.Crop( rRectPixel );
+
+ if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
+ aMask.Crop( rRectPixel );
+
+ aBitmapSize = aBitmap.GetSizePixel();
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Convert( BmpConversion eConversion )
+{
+ return( !!aBitmap ? aBitmap.Convert( eConversion ) : FALSE );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::ReduceColors( USHORT nNewColorCount, BmpReduce eReduce )
+{
+ return( !!aBitmap ? aBitmap.ReduceColors( nNewColorCount, eReduce ) : FALSE );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Expand( ULONG nDX, ULONG nDY, const Color* pInitColor, BOOL bExpandTransparent )
+{
+ BOOL bRet = FALSE;
+
+ if( !!aBitmap )
+ {
+ bRet = aBitmap.Expand( nDX, nDY, pInitColor );
+
+ if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
+ {
+ Color aColor( bExpandTransparent ? COL_WHITE : COL_BLACK );
+ aMask.Expand( nDX, nDY, &aColor );
+ }
+
+ aBitmapSize = aBitmap.GetSizePixel();
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Dither( ULONG nDitherFlags, const BitmapPalette* pDitherPal )
+{
+ return( !!aBitmap ? aBitmap.Dither( nDitherFlags, pDitherPal ) : FALSE );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Replace( const Color& rSearchColor, const Color& rReplaceColor, ULONG nTol )
+{
+ return( !!aBitmap ? aBitmap.Replace( rSearchColor, rReplaceColor, nTol ) : FALSE );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceColors, ULONG nColorCount, const ULONG* pTols )
+{
+ return( !!aBitmap ? aBitmap.Replace( pSearchColors, pReplaceColors, nColorCount, (ULONG*) pTols ) : FALSE );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent,
+ short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
+ double fGamma, BOOL bInvert )
+{
+ return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent,
+ nChannelRPercent, nChannelGPercent, nChannelBPercent,
+ fGamma, bInvert ) : FALSE );
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapEx::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
+{
+ return( !!aBitmap ? aBitmap.Filter( eFilter, pFilterParam, pProgress ) : FALSE );
+}
+
+// ------------------------------------------------------------------
+
+void BitmapEx::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const
+{
+ pOutDev->DrawBitmapEx( rDestPt, *this );
+}
+
+// ------------------------------------------------------------------
+
+void BitmapEx::Draw( OutputDevice* pOutDev,
+ const Point& rDestPt, const Size& rDestSize ) const
+{
+ pOutDev->DrawBitmapEx( rDestPt, rDestSize, *this );
+}
+
+// ------------------------------------------------------------------
+
+void BitmapEx::Draw( OutputDevice* pOutDev,
+ const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel ) const
+{
+ pOutDev->DrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, *this );
+}
+
+// ------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const BitmapEx& rBitmapEx )
+{
+ rBitmapEx.aBitmap.Write( rOStm );
+
+ rOStm << (UINT32) 0x25091962;
+ rOStm << (UINT32) 0xACB20201;
+ rOStm << (BYTE) rBitmapEx.eTransparent;
+
+ if( rBitmapEx.eTransparent == TRANSPARENT_BITMAP )
+ rBitmapEx.aMask.Write( rOStm );
+ else if( rBitmapEx.eTransparent == TRANSPARENT_COLOR )
+ rOStm << rBitmapEx.aTransparentColor;
+
+ return rOStm;
+}
+
+// ------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, BitmapEx& rBitmapEx )
+{
+ Bitmap aBmp;
+
+ rIStm >> aBmp;
+
+ if( !rIStm.GetError() )
+ {
+ const ULONG nStmPos = rIStm.Tell();
+ UINT32 nMagic1;
+ UINT32 nMagic2;
+
+ rIStm >> nMagic1 >> nMagic2;
+
+ if( ( nMagic1 != 0x25091962 ) || ( nMagic2 != 0xACB20201 ) || rIStm.GetError() )
+ {
+ rIStm.Seek( nStmPos );
+ rBitmapEx = aBmp;
+ }
+ else
+ {
+ BYTE bTransparent;
+
+ rIStm >> bTransparent;
+
+ if( bTransparent == (BYTE) TRANSPARENT_BITMAP )
+ {
+ Bitmap aMask;
+
+ rIStm >> aMask;
+
+ if( !!aMask)
+ {
+ // do we have an alpha mask?
+ if( ( 8 == aMask.GetBitCount() ) && aMask.HasGreyPalette() )
+ {
+ AlphaMask aAlpha;
+
+ // create alpha mask quickly (without greyscale conversion)
+ aAlpha.ImplSetBitmap( aMask );
+ rBitmapEx = BitmapEx( aBmp, aAlpha );
+ }
+ else
+ rBitmapEx = BitmapEx( aBmp, aMask );
+ }
+ else
+ rBitmapEx = aBmp;
+ }
+ else if( bTransparent == (BYTE) TRANSPARENT_COLOR )
+ {
+ Color aTransparentColor;
+
+ rIStm >> aTransparentColor;
+ rBitmapEx = BitmapEx( aBmp, aTransparentColor );
+ }
+ else
+ rBitmapEx = aBmp;
+ }
+ }
+
+ return rIStm;
+}
+
+// ------------------------------------------------------------------
+
+#ifdef REMOTE_APPSERVER
+
+void BitmapEx::ImplDrawRemote( OutputDevice* pOut,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Point& rDestPt, const Size& rDestSz ) const
+{
+ if( !!aBitmap )
+ {
+ switch( eTransparent )
+ {
+ case( TRANSPARENT_NONE ):
+ aBitmap.ImplDrawRemote( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz );
+ break;
+
+ case( TRANSPARENT_BITMAP ):
+ {
+ if( !!aMask )
+ {
+ if( IsAlpha() )
+ aBitmap.ImplDrawRemoteAlpha( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz, GetAlpha() );
+ else
+ aBitmap.ImplDrawRemoteEx( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz, aMask );
+ }
+ else
+ aBitmap.ImplDrawRemote( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz );
+ }
+ break;
+
+ default:
+ {
+ DBG_ERROR( "BitmapEx::ImplDrawRemote???" );
+ }
+ break;
+ }
+ }
+}
+
+#endif // REMOTE
diff --git a/vcl/source/gdi/bmpacc.cxx b/vcl/source/gdi/bmpacc.cxx
new file mode 100644
index 000000000000..6fc3657c90fd
--- /dev/null
+++ b/vcl/source/gdi/bmpacc.cxx
@@ -0,0 +1,448 @@
+/*************************************************************************
+ *
+ * $RCSfile: bmpacc.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_BMPACC_CXX
+
+#ifdef W31
+#include <tools/svwin.h>
+#endif
+
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_IMPBMP_HXX
+#include <impbmp.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#include <string.h>
+
+// --------------------
+// - BitmapReadAccess -
+// --------------------
+
+BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap, BOOL bModify ) :
+ mpBuffer ( NULL ),
+ mpScanBuf ( NULL ),
+ mbModify ( bModify ),
+ mFncGetPixel ( NULL ),
+ mFncSetPixel ( NULL )
+{
+ ImplCreate( rBitmap );
+}
+
+// ------------------------------------------------------------------
+
+BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap ) :
+ mpBuffer ( NULL ),
+ mpScanBuf ( NULL ),
+ mbModify ( FALSE ),
+ mFncGetPixel ( NULL ),
+ mFncSetPixel ( NULL )
+{
+ ImplCreate( rBitmap );
+}
+
+// ------------------------------------------------------------------
+
+BitmapReadAccess::~BitmapReadAccess()
+{
+ ImplDestroy();
+}
+
+// ------------------------------------------------------------------
+
+void BitmapReadAccess::ImplCreate( Bitmap& rBitmap )
+{
+ ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap();
+
+ BMP_ASSERT( pImpBmp, "Forbidden Access to empty bitmap!" );
+
+ if( pImpBmp )
+ {
+ if( mbModify && !maBitmap.ImplGetImpBitmap() )
+ {
+ rBitmap.ImplMakeUnique();
+ pImpBmp = rBitmap.ImplGetImpBitmap();
+ }
+ else
+ {
+ BMP_ASSERT( !mbModify || pImpBmp->ImplGetRefCount() == 2,
+ "Unpredictable results: bitmap is referenced more than once!" );
+ }
+
+ mpBuffer = pImpBmp->ImplAcquireBuffer( !mbModify );
+
+ if( !mpBuffer )
+ {
+ ImpBitmap* pNewImpBmp = new ImpBitmap;
+
+ if( pNewImpBmp->ImplCreate( *pImpBmp, rBitmap.GetBitCount() ) )
+ {
+ pImpBmp = pNewImpBmp;
+ rBitmap.ImplSetImpBitmap( pImpBmp );
+ mpBuffer = pImpBmp->ImplAcquireBuffer( !mbModify );
+ }
+ else
+ delete pNewImpBmp;
+ }
+
+ if( mpBuffer )
+ {
+ const long nHeight = mpBuffer->mnHeight;
+ Scanline pTmpLine = mpBuffer->mpBits;
+
+ mpScanBuf = new Scanline[ nHeight ];
+ maColorMask = mpBuffer->maColorMask;
+
+ if( BMP_SCANLINE_ADJUSTMENT( mpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
+ {
+ for( long nY = 0L; nY < nHeight; nY++, pTmpLine += mpBuffer->mnScanlineSize )
+ mpScanBuf[ nY ] = pTmpLine;
+ }
+ else
+ {
+ for( long nY = nHeight - 1; nY >= 0; nY--, pTmpLine += mpBuffer->mnScanlineSize )
+ mpScanBuf[ nY ] = pTmpLine;
+ }
+
+ if( !ImplSetAccessPointers( BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ) ) )
+ {
+ delete[] mpScanBuf;
+ mpScanBuf = NULL;
+
+ pImpBmp->ImplReleaseBuffer( mpBuffer, !mbModify );
+ mpBuffer = NULL;
+ }
+ else
+ maBitmap = rBitmap;
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+void BitmapReadAccess::ImplDestroy()
+{
+ ImpBitmap* pImpBmp = maBitmap.ImplGetImpBitmap();
+
+ delete[] mpScanBuf;
+ mpScanBuf = NULL;
+
+ if( mpBuffer && pImpBmp )
+ {
+ pImpBmp->ImplReleaseBuffer( mpBuffer, !mbModify );
+ mpBuffer = NULL;
+ }
+}
+
+// ------------------------------------------------------------------
+
+BOOL BitmapReadAccess::ImplSetAccessPointers( ULONG nFormat )
+{
+ BOOL bRet = TRUE;
+
+ switch( nFormat )
+ {
+ CASE_FORMAT( _1BIT_MSB_PAL )
+ CASE_FORMAT( _1BIT_LSB_PAL )
+ CASE_FORMAT( _4BIT_MSN_PAL )
+ CASE_FORMAT( _4BIT_LSN_PAL )
+ CASE_FORMAT( _8BIT_PAL )
+ CASE_FORMAT( _8BIT_TC_MASK )
+ CASE_FORMAT( _16BIT_TC_MASK )
+ CASE_FORMAT( _24BIT_TC_BGR )
+ CASE_FORMAT( _24BIT_TC_RGB )
+ CASE_FORMAT( _24BIT_TC_MASK )
+ CASE_FORMAT( _32BIT_TC_ABGR )
+ CASE_FORMAT( _32BIT_TC_ARGB )
+ CASE_FORMAT( _32BIT_TC_BGRA )
+ CASE_FORMAT( _32BIT_TC_RGBA )
+ CASE_FORMAT( _32BIT_TC_MASK )
+
+ default:
+ bRet = FALSE;
+ break;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+void BitmapReadAccess::ImplZeroInitUnusedBits()
+{
+ const sal_uInt32 nWidth = Width(), nHeight = Height(), nScanSize = GetScanlineSize();
+
+ if( nWidth && nHeight && nScanSize && GetBuffer() )
+ {
+ DBG_ASSERT( !( nScanSize % 4 ), "BitmapWriteAccess::ZeroInitUnusedBits: Unsupported scanline alignment" );
+
+ sal_uInt32 nBits;
+
+ switch( GetScanlineFormat() )
+ {
+ case( BMP_FORMAT_1BIT_MSB_PAL ):
+ nBits = 1;
+ break;
+
+ case( BMP_FORMAT_4BIT_MSN_PAL ):
+ nBits = 4;
+ break;
+
+ case( BMP_FORMAT_8BIT_PAL ):
+ case( BMP_FORMAT_8BIT_TC_MASK ):
+ nBits = 8;
+ break;
+
+ case( BMP_FORMAT_16BIT_TC_MASK ):
+ nBits = 16;
+ break;
+
+ case( BMP_FORMAT_24BIT_TC_BGR ):
+ case( BMP_FORMAT_24BIT_TC_RGB ):
+ case( BMP_FORMAT_24BIT_TC_MASK ):
+ nBits = 24;
+ break;
+
+ case( BMP_FORMAT_32BIT_TC_ABGR ):
+ case( BMP_FORMAT_32BIT_TC_ARGB ):
+ case( BMP_FORMAT_32BIT_TC_BGRA ):
+ case( BMP_FORMAT_32BIT_TC_RGBA ):
+ case( BMP_FORMAT_32BIT_TC_MASK ):
+ nBits = 32;
+ break;
+
+ default:
+ {
+ DBG_ERROR( "BitmapWriteAccess::ZeroInitUnusedBits: Unsupported pixel format" );
+ nBits = 0;
+ }
+ break;
+ }
+
+ if( ( nBits *= nWidth ) & 0x1f )
+ {
+ sal_uInt32 nMask = 0xffffffff << ( ( nScanSize << 3 ) - nBits );
+ BYTE* pLast4Bytes = (BYTE*) GetBuffer() + ( nScanSize - 4 );
+
+#ifdef __LITTLEENDIAN
+ nMask = SWAPLONG( nMask );
+#endif
+ for( long i = 0; i < nHeight; i++, pLast4Bytes += nScanSize )
+ ( *(long*) pLast4Bytes ) &= nMask;
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+void BitmapReadAccess::Flush()
+{
+ ImplDestroy();
+}
+
+// ------------------------------------------------------------------
+
+void BitmapReadAccess::ReAccess( BOOL bModify )
+{
+ const ImpBitmap* pImpBmp = maBitmap.ImplGetImpBitmap();
+
+ BMP_ASSERT( !mpBuffer, "No ReAccess possible while bitmap is being accessed!" );
+ BMP_ASSERT( pImpBmp && ( pImpBmp->ImplGetRefCount() > 1UL ), "Accessed bitmap does not exist anymore!" );
+
+ if( !mpBuffer && pImpBmp && ( pImpBmp->ImplGetRefCount() > 1UL ) )
+ {
+ mbModify = bModify;
+ ImplCreate( maBitmap );
+ }
+}
+
+// ------------------------------------------------------------------
+
+USHORT BitmapReadAccess::GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const
+{
+ return( HasPalette() ? mpBuffer->maPalette.GetBestIndex( rBitmapColor ) : 0 );
+}
+
+// ---------------------
+// - BitmapWriteAccess -
+// ---------------------
+
+BitmapWriteAccess::~BitmapWriteAccess()
+{
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::ImplInitDraw()
+{
+ if( HasPalette() )
+ {
+ if( !maLineColor.IsIndex() )
+ maLineColor = (BYTE) GetBestPaletteIndex( maLineColor );
+
+ if( !maFillColor.IsIndex() )
+ maFillColor = (BYTE) GetBestPaletteIndex( maFillColor );
+ }
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::CopyScanline( long nY, const BitmapReadAccess& rReadAcc )
+{
+ BMP_ASSERT( ( nY >= 0 ) && ( nY < mpBuffer->mnHeight ), "y-coordinate in destination out of range!" );
+ BMP_ASSERT( nY < rReadAcc.Height(), "y-coordinate in source out of range!" );
+ BMP_ASSERT( ( HasPalette() && rReadAcc.HasPalette() ) || ( !HasPalette() && !rReadAcc.HasPalette() ), "No copying possible between palette bitmap and TC bitmap!" );
+
+ if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
+ ( GetScanlineSize() >= rReadAcc.GetScanlineSize() ) )
+ {
+ HMEMCPY( mpScanBuf[ nY ], rReadAcc.GetScanline( nY ), rReadAcc.GetScanlineSize() );
+ }
+ else
+ for( long nX = 0L, nWidth = Min( mpBuffer->mnWidth, rReadAcc.Width() ); nX < nWidth; nX++ )
+ SetPixel( nY, nX, rReadAcc.GetPixel( nY, nX ) );
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::CopyScanline( long nY, const Scanline aSrcScanline,
+ ULONG nSrcScanlineFormat, ULONG nSrcScanlineSize )
+{
+ const ULONG nFormat = BMP_SCANLINE_FORMAT( nSrcScanlineFormat );
+
+ BMP_ASSERT( ( nY >= 0 ) && ( nY < mpBuffer->mnHeight ), "y-coordinate in destination out of range!" );
+ BMP_ASSERT( ( HasPalette() && nFormat <= BMP_FORMAT_8BIT_PAL ) ||
+ ( !HasPalette() && nFormat > BMP_FORMAT_8BIT_PAL ),
+ "No copying possible between palette and non palette scanlines!" );
+
+ const ULONG nCount = Min( GetScanlineSize(), nSrcScanlineSize );
+
+ if( nCount )
+ {
+ if( GetScanlineFormat() == BMP_SCANLINE_FORMAT( nSrcScanlineFormat ) )
+ HMEMCPY( mpScanBuf[ nY ], aSrcScanline, nCount );
+ else
+ {
+ BMP_ASSERT( nFormat != BMP_FORMAT_8BIT_TC_MASK && nFormat != BMP_FORMAT_16BIT_TC_MASK &&
+ nFormat != BMP_FORMAT_24BIT_TC_MASK && nFormat != BMP_FORMAT_32BIT_TC_MASK,
+ "No support for pixel formats with color masks yet!" );
+
+ FncGetPixel pFncGetPixel;
+
+ switch( nFormat )
+ {
+ case( BMP_FORMAT_1BIT_MSB_PAL ): pFncGetPixel = GetPixelFor_1BIT_MSB_PAL; break;
+ case( BMP_FORMAT_1BIT_LSB_PAL ): pFncGetPixel = GetPixelFor_1BIT_LSB_PAL; break;
+ case( BMP_FORMAT_4BIT_MSN_PAL ): pFncGetPixel = GetPixelFor_4BIT_MSN_PAL; break;
+ case( BMP_FORMAT_4BIT_LSN_PAL ): pFncGetPixel = GetPixelFor_4BIT_LSN_PAL; break;
+ case( BMP_FORMAT_8BIT_PAL ): pFncGetPixel = GetPixelFor_8BIT_PAL; break;
+ case( BMP_FORMAT_8BIT_TC_MASK ): pFncGetPixel = GetPixelFor_8BIT_TC_MASK; break;
+ case( BMP_FORMAT_16BIT_TC_MASK ): pFncGetPixel = GetPixelFor_16BIT_TC_MASK; break;
+ case( BMP_FORMAT_24BIT_TC_BGR ): pFncGetPixel = GetPixelFor_24BIT_TC_BGR; break;
+ case( BMP_FORMAT_24BIT_TC_RGB ): pFncGetPixel = GetPixelFor_24BIT_TC_RGB; break;
+ case( BMP_FORMAT_24BIT_TC_MASK ): pFncGetPixel = GetPixelFor_24BIT_TC_MASK; break;
+ case( BMP_FORMAT_32BIT_TC_ABGR ): pFncGetPixel = GetPixelFor_32BIT_TC_ABGR; break;
+ case( BMP_FORMAT_32BIT_TC_ARGB ): pFncGetPixel = GetPixelFor_32BIT_TC_ARGB; break;
+ case( BMP_FORMAT_32BIT_TC_BGRA ): pFncGetPixel = GetPixelFor_32BIT_TC_BGRA; break;
+ case( BMP_FORMAT_32BIT_TC_RGBA ): pFncGetPixel = GetPixelFor_32BIT_TC_RGBA; break;
+ case( BMP_FORMAT_32BIT_TC_MASK ): pFncGetPixel = GetPixelFor_32BIT_TC_MASK; break;
+
+ default:
+ pFncGetPixel = NULL;
+ break;
+ }
+
+ if( pFncGetPixel )
+ {
+ const ColorMask aDummyMask;
+
+ for( long nX = 0L, nWidth = mpBuffer->mnWidth; nX < nWidth; nX++ )
+ SetPixel( nY, nX, pFncGetPixel( aSrcScanline, nX, aDummyMask ) );
+ }
+ }
+ }
+}
+
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::CopyBuffer( const BitmapReadAccess& rReadAcc )
+{
+ BMP_ASSERT( ( HasPalette() && rReadAcc.HasPalette() ) || ( !HasPalette() && !rReadAcc.HasPalette() ), "No copying possible between palette bitmap and TC bitmap!" );
+
+ if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
+ ( GetScanlineSize() == rReadAcc.GetScanlineSize() ) )
+ {
+ const long nHeight = Min( mpBuffer->mnHeight, rReadAcc.Height() );
+ const ULONG nCount = nHeight * mpBuffer->mnScanlineSize;
+
+ HMEMCPY( mpBuffer->mpBits, rReadAcc.GetBuffer(), nCount );
+ }
+ else
+ for( long nY = 0L, nHeight = Min( mpBuffer->mnHeight, rReadAcc.Height() ); nY < nHeight; nY++ )
+ CopyScanline( nY, rReadAcc );
+}
diff --git a/vcl/source/gdi/bmpacc2.cxx b/vcl/source/gdi/bmpacc2.cxx
new file mode 100644
index 000000000000..a07f58815a88
--- /dev/null
+++ b/vcl/source/gdi/bmpacc2.cxx
@@ -0,0 +1,353 @@
+/*************************************************************************
+ *
+ * $RCSfile: bmpacc2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_BMPACC2_CXX
+
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+
+// ----------------
+// - BitmapAccess -
+// ----------------
+
+IMPL_FORMAT_GETPIXEL( _1BIT_MSB_PAL )
+{
+ return( pScanline[ nX >> 3 ] & ( 1 << ( 7 - ( nX & 7 ) ) ) ? 1 : 0 );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _1BIT_MSB_PAL )
+{
+ BYTE& rByte = pScanline[ nX >> 3 ];
+
+ ( rBitmapColor.GetIndex() & 1 ) ? ( rByte |= 1 << ( 7 - ( nX & 7 ) ) ) :
+ ( rByte &= ~( 1 << ( 7 - ( nX & 7 ) ) ) );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _1BIT_LSB_PAL )
+{
+ return( pScanline[ nX >> 3 ] & ( 1 << ( nX & 7 ) ) ? 1 : 0 );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _1BIT_LSB_PAL )
+{
+ BYTE& rByte = pScanline[ nX >> 3 ];
+
+ ( rBitmapColor.GetIndex() & 1 ) ? ( rByte |= 1 << ( nX & 7 ) ) :
+ ( rByte &= ~( 1 << ( nX & 7 ) ) );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _4BIT_MSN_PAL )
+{
+ return( ( pScanline[ nX >> 1 ] >> ( nX & 1 ? 0 : 4 ) ) & 0x0f );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _4BIT_MSN_PAL )
+{
+ BYTE& rByte = pScanline[ nX >> 1 ];
+
+ ( nX & 1 ) ? ( rByte &= 0xf0, rByte |= ( rBitmapColor.GetIndex() & 0x0f ) ) :
+ ( rByte &= 0x0f, rByte |= ( rBitmapColor.GetIndex() << 4 ) );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _4BIT_LSN_PAL )
+{
+ return( ( pScanline[ nX >> 1 ] >> ( nX & 1 ? 4 : 0 ) ) & 0x0f );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _4BIT_LSN_PAL )
+{
+ BYTE& rByte = pScanline[ nX >> 1 ];
+
+ ( nX & 1 ) ? ( rByte &= 0x0f, rByte |= ( rBitmapColor.GetIndex() << 4 ) ) :
+ ( rByte &= 0xf0, rByte |= ( rBitmapColor.GetIndex() & 0x0f ) );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _8BIT_PAL )
+{
+ return pScanline[ nX ];
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _8BIT_PAL )
+{
+ pScanline[ nX ] = rBitmapColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _8BIT_TC_MASK )
+{
+ BitmapColor aColor;
+ rMask.GetColorFor8Bit( aColor, pScanline + nX );
+ return aColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _8BIT_TC_MASK )
+{
+ rMask.SetColorFor8Bit( rBitmapColor, pScanline + nX );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _16BIT_TC_MASK )
+{
+ BitmapColor aColor;
+ rMask.GetColorFor16Bit( aColor, pScanline + ( nX << 1UL ) );
+ return aColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _16BIT_TC_MASK )
+{
+ rMask.SetColorFor16Bit( rBitmapColor, pScanline + ( nX << 1UL ) );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _24BIT_TC_BGR )
+{
+ BitmapColor aBitmapColor;
+
+ aBitmapColor.SetBlue( *( pScanline = pScanline + nX * 3 )++ );
+ aBitmapColor.SetGreen( *pScanline++ );
+ aBitmapColor.SetRed( *pScanline );
+
+ return aBitmapColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _24BIT_TC_BGR )
+{
+ *( pScanline = pScanline + nX * 3 )++ = rBitmapColor.GetBlue();
+ *pScanline++ = rBitmapColor.GetGreen();
+ *pScanline = rBitmapColor.GetRed();
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _24BIT_TC_RGB )
+{
+ BitmapColor aBitmapColor;
+
+ aBitmapColor.SetRed( *( pScanline = pScanline + nX * 3 )++ );
+ aBitmapColor.SetGreen( *pScanline++ );
+ aBitmapColor.SetBlue( *pScanline );
+
+ return aBitmapColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _24BIT_TC_RGB )
+{
+ *( pScanline = pScanline + nX * 3 )++ = rBitmapColor.GetRed();
+ *pScanline++ = rBitmapColor.GetGreen();
+ *pScanline = rBitmapColor.GetBlue();
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _24BIT_TC_MASK )
+{
+ BitmapColor aColor;
+ rMask.GetColorFor24Bit( aColor, pScanline + nX * 3L );
+ return aColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _24BIT_TC_MASK )
+{
+ rMask.SetColorFor24Bit( rBitmapColor, pScanline + nX * 3L );
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _32BIT_TC_ABGR )
+{
+ BitmapColor aBitmapColor;
+
+ aBitmapColor.SetBlue( *( pScanline = pScanline + ( nX << 2 ) + 1 )++ );
+ aBitmapColor.SetGreen( *pScanline++ );
+ aBitmapColor.SetRed( *pScanline );
+
+ return aBitmapColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _32BIT_TC_ABGR )
+{
+ *( pScanline = pScanline + ( nX << 2 ) )++ = 0;
+ *pScanline++ = rBitmapColor.GetBlue();
+ *pScanline++ = rBitmapColor.GetGreen();
+ *pScanline = rBitmapColor.GetRed();
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _32BIT_TC_ARGB )
+{
+ BitmapColor aBitmapColor;
+
+ aBitmapColor.SetRed( *( pScanline = pScanline + ( nX << 2 ) + 1 )++ );
+ aBitmapColor.SetGreen( *pScanline++ );
+ aBitmapColor.SetBlue( *pScanline );
+
+ return aBitmapColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _32BIT_TC_ARGB )
+{
+ *( pScanline = pScanline + ( nX << 2 ) )++ = 0;
+ *pScanline++ = rBitmapColor.GetRed();
+ *pScanline++ = rBitmapColor.GetGreen();
+ *pScanline = rBitmapColor.GetBlue();
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _32BIT_TC_BGRA )
+{
+ BitmapColor aBitmapColor;
+
+ aBitmapColor.SetBlue( *( pScanline = pScanline + ( nX << 2 ) )++ );
+ aBitmapColor.SetGreen( *pScanline++ );
+ aBitmapColor.SetRed( *pScanline );
+
+ return aBitmapColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _32BIT_TC_BGRA )
+{
+ *( pScanline = pScanline + ( nX << 2 ) )++ = rBitmapColor.GetBlue();
+ *pScanline++ = rBitmapColor.GetGreen();
+ *pScanline++ = rBitmapColor.GetRed();
+ *pScanline = 0;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _32BIT_TC_RGBA )
+{
+ BitmapColor aBitmapColor;
+
+ aBitmapColor.SetRed( *( pScanline = pScanline + ( nX << 2 ) )++ );
+ aBitmapColor.SetGreen( *pScanline++ );
+ aBitmapColor.SetBlue( *pScanline );
+
+ return aBitmapColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _32BIT_TC_RGBA )
+{
+ *( pScanline = pScanline + ( nX << 2 ) )++ = rBitmapColor.GetRed();
+ *pScanline++ = rBitmapColor.GetGreen();
+ *pScanline++ = rBitmapColor.GetBlue();
+ *pScanline = 0;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_GETPIXEL( _32BIT_TC_MASK )
+{
+ BitmapColor aColor;
+ rMask.GetColorFor32Bit( aColor, pScanline + ( nX << 2UL ) );
+ return aColor;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_FORMAT_SETPIXEL( _32BIT_TC_MASK )
+{
+ rMask.SetColorFor32Bit( rBitmapColor, pScanline + ( nX << 2UL ) );
+}
diff --git a/vcl/source/gdi/bmpacc3.cxx b/vcl/source/gdi/bmpacc3.cxx
new file mode 100644
index 000000000000..c26de8c7ecfa
--- /dev/null
+++ b/vcl/source/gdi/bmpacc3.cxx
@@ -0,0 +1,351 @@
+/*************************************************************************
+ *
+ * $RCSfile: bmpacc3.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_BMPACC_CXX
+
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_REGION_HXX
+#include <region.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+
+// ---------------------
+// - BitmapWriteAccess -
+// ---------------------
+
+void BitmapWriteAccess::Erase( const Color& rColor )
+{
+ const BitmapColor aOldFillColor( maFillColor );
+ const Point aPoint;
+ const Rectangle aRect( aPoint, maBitmap.GetSizePixel() );
+
+ SetFillColor( rColor );
+ FillRect( aRect );
+ maFillColor = aOldFillColor;
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
+{
+ long nX;
+ long nY;
+
+ ImplInitDraw();
+
+ if ( rStart.X() == rEnd.X() )
+ {
+ // vertikale Line
+ const long nEndY = rEnd.Y();
+
+ nX = rStart.X();
+ nY = rStart.Y();
+
+ if ( nEndY > nY )
+ {
+ for (; nY <= nEndY; nY++ )
+ SetPixel( nY, nX, maLineColor );
+ }
+ else
+ {
+ for (; nY >= nEndY; nY-- )
+ SetPixel( nY, nX, maLineColor );
+ }
+ }
+ else if ( rStart.Y() == rEnd.Y() )
+ {
+ // horizontale Line
+ const long nEndX = rEnd.X();
+
+ nX = rStart.X();
+ nY = rStart.Y();
+
+ if ( nEndX > nX )
+ {
+ for (; nX <= nEndX; nX++ )
+ SetPixel( nY, nX, maLineColor );
+ }
+ else
+ {
+ for (; nX >= nEndX; nX-- )
+ SetPixel( nY, nX, maLineColor );
+ }
+ }
+ else
+ {
+ const long nDX = labs( rEnd.X() - rStart.X() );
+ const long nDY = labs( rEnd.Y() - rStart.Y() );
+ long nX1;
+ long nY1;
+ long nX2;
+ long nY2;
+
+ if ( nDX >= nDY )
+ {
+ if ( rStart.X() < rEnd.X() )
+ {
+ nX1 = rStart.X();
+ nY1 = rStart.Y();
+ nX2 = rEnd.X();
+ nY2 = rEnd.Y();
+ }
+ else
+ {
+ nX1 = rEnd.X();
+ nY1 = rEnd.Y();
+ nX2 = rStart.X();
+ nY2 = rStart.Y();
+ }
+
+ const long nDYX = ( nDY - nDX ) << 1;
+ const long nDY2 = nDY << 1;
+ long nD = nDY2 - nDX;
+ BOOL bPos = nY1 < nY2;
+
+ for ( nX = nX1, nY = nY1; nX <= nX2; nX++ )
+ {
+ SetPixel( nY, nX, maLineColor );
+
+ if ( nD < 0 )
+ nD += nDY2;
+ else
+ {
+ nD += nDYX;
+
+ if ( bPos )
+ nY++;
+ else
+ nY--;
+ }
+ }
+ }
+ else
+ {
+ if ( rStart.Y() < rEnd.Y() )
+ {
+ nX1 = rStart.X();
+ nY1 = rStart.Y();
+ nX2 = rEnd.X();
+ nY2 = rEnd.Y();
+ }
+ else
+ {
+ nX1 = rEnd.X();
+ nY1 = rEnd.Y();
+ nX2 = rStart.X();
+ nY2 = rStart.Y();
+ }
+
+ const long nDYX = ( nDX - nDY ) << 1;
+ const long nDY2 = nDX << 1;
+ long nD = nDY2 - nDY;
+ BOOL bPos = nX1 < nX2;
+
+ for ( nX = nX1, nY = nY1; nY <= nY2; nY++ )
+ {
+ SetPixel( nY, nX, maLineColor );
+
+ if ( nD < 0 )
+ nD += nDY2;
+ else
+ {
+ nD += nDYX;
+
+ if ( bPos )
+ nX++;
+ else
+ nX--;
+ }
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::DrawRect( const Rectangle& rRect )
+{
+ ImplInitDraw();
+ FillRect( rRect );
+ DrawLine( rRect.TopLeft(), rRect.TopRight() );
+ DrawLine( rRect.TopRight(), rRect.BottomRight() );
+ DrawLine( rRect.BottomRight(), rRect.BottomLeft() );
+ DrawLine( rRect.BottomLeft(), rRect.TopLeft() );
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::FillRect( const Rectangle& rRect )
+{
+ Point aPoint;
+ Rectangle aRect( aPoint, maBitmap.GetSizePixel() );
+
+ aRect.Intersection( rRect );
+
+ if( !aRect.IsEmpty() )
+ {
+ const long nStartX = rRect.TopLeft().X();
+ const long nStartY = rRect.TopLeft().Y();
+ const long nEndX = rRect.BottomRight().X();
+ const long nEndY = rRect.BottomRight().Y();
+
+ ImplInitDraw();
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ for( long nX = nStartX; nX <= nEndX; nX++ )
+ SetPixel( nY, nX, maFillColor );
+ }
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::DrawPolygon( const Polygon& rPoly )
+{
+ const USHORT nSize = rPoly.GetSize();
+
+ if( nSize )
+ {
+ Region aRegion( rPoly );
+ Rectangle aRect;
+
+ aRegion.Intersect( Rectangle( Point(), Size( Width(), Height() ) ) );
+
+ if( !aRegion.IsEmpty() )
+ {
+ RegionHandle aRegHandle( aRegion.BeginEnumRects() );
+
+ ImplInitDraw();
+
+ while( aRegion.GetNextEnumRect( aRegHandle, aRect ) )
+ for( long nY = aRect.Top(), nEndY = aRect.Bottom(); nY <= nEndY; nY++ )
+ for( long nX = aRect.Left(), nEndX = aRect.Right(); nX <= nEndX; nX++ )
+ SetPixel( nY, nX, maFillColor );
+
+ aRegion.EndEnumRects( aRegHandle );
+ }
+
+ if( maLineColor != maFillColor )
+ {
+ for( USHORT i = 0, nSize1 = nSize - 1; i < nSize1; i++ )
+ DrawLine( rPoly[ i ], rPoly[ i + 1 ] );
+
+ if( rPoly[ nSize - 1 ] != rPoly[ 0 ] )
+ DrawLine( rPoly[ nSize - 1 ], rPoly[ 0 ] );
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
+{
+ const USHORT nCount = rPolyPoly.Count();
+
+ if( nCount )
+ {
+ Region aRegion( rPolyPoly );
+ Rectangle aRect;
+
+ aRegion.Intersect( Rectangle( Point(), Size( Width(), Height() ) ) );
+
+ if( !aRegion.IsEmpty() )
+ {
+ RegionHandle aRegHandle( aRegion.BeginEnumRects() );
+
+ ImplInitDraw();
+
+ while( aRegion.GetNextEnumRect( aRegHandle, aRect ) )
+ for( long nY = aRect.Top(), nEndY = aRect.Bottom(); nY <= nEndY; nY++ )
+ for( long nX = aRect.Left(), nEndX = aRect.Right(); nX <= nEndX; nX++ )
+ SetPixel( nY, nX, maFillColor );
+
+ aRegion.EndEnumRects( aRegHandle );
+ }
+
+ if( maLineColor != maFillColor )
+ {
+ for( USHORT n = 0; n < nCount; )
+ {
+ const Polygon& rPoly = rPolyPoly[ n++ ];
+ const USHORT nSize = rPoly.GetSize();
+
+ if( nSize )
+ {
+ for( USHORT i = 0, nSize1 = nSize - 1; i < nSize1; i++ )
+ DrawLine( rPoly[ i ], rPoly[ i + 1 ] );
+
+ if( rPoly[ nSize - 1 ] != rPoly[ 0 ] )
+ DrawLine( rPoly[ nSize - 1 ], rPoly[ 0 ] );
+ }
+ }
+ }
+ }
+}
diff --git a/vcl/source/gdi/cvtgrf.cxx b/vcl/source/gdi/cvtgrf.cxx
new file mode 100644
index 000000000000..1005cf3396d5
--- /dev/null
+++ b/vcl/source/gdi/cvtgrf.cxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * $RCSfile: cvtgrf.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_CVTGRF_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_CVTGRF_HXX
+#include <cvtgrf.hxx>
+#endif
+
+// --------------
+// - Callback -
+// --------------
+
+#ifndef REMOTE_APPSERVER
+
+ULONG ImplFilterCallback( void* pInst,
+ ULONG nInFormat, void* pInBuffer, ULONG nInBufSize,
+ ULONG nOutFormat, void** ppOutBuffer )
+{
+ return( ( (GraphicConverter*) pInst )->ImplConvert( nInFormat,
+ pInBuffer, nInBufSize,
+ ppOutBuffer, nOutFormat ) );
+}
+
+#endif
+
+// --------------------
+// - GraphicConverter -
+// --------------------
+
+GraphicConverter::GraphicConverter() :
+ mpConvertData( NULL )
+{
+#ifndef REMOTE_APPSERVER
+ SetFilterCallback( ImplFilterCallback, this );
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+GraphicConverter::~GraphicConverter()
+{
+}
+
+// ------------------------------------------------------------------------
+
+ULONG GraphicConverter::ImplConvert( ULONG nInFormat, void* pInBuffer, ULONG nInBufSize,
+ void** ppOutBuffer, ULONG nOutFormat )
+{
+ ULONG nRetBufSize = 0UL;
+
+ if( ( nInFormat != nOutFormat ) && pInBuffer )
+ {
+ if( ( nInFormat == CVT_SVM ) || ( nInFormat == CVT_BMP ) )
+ {
+ SvMemoryStream aIStm;
+ Graphic aGraphic;
+
+ aIStm.SetBuffer( (char*) pInBuffer, nInBufSize, FALSE, nInBufSize );
+ aIStm >> aGraphic;
+
+ if( !aIStm.GetError() )
+ {
+ SvMemoryStream aOStm( 64535, 64535 );
+
+ mpConvertData = new ConvertData( aGraphic, aOStm, nOutFormat );
+
+ if( maFilterHdl.IsSet() && maFilterHdl.Call( mpConvertData ) )
+ {
+ nRetBufSize = aOStm.Seek( STREAM_SEEK_TO_END );
+ *ppOutBuffer = (void*) aOStm.GetData();
+ aOStm.ObjectOwnsMemory( FALSE );
+ }
+
+ delete mpConvertData;
+ mpConvertData = NULL;
+ }
+ }
+ else if( ( nOutFormat == CVT_SVM ) || ( nOutFormat == CVT_BMP ) )
+ {
+ SvMemoryStream aIStm;
+
+ aIStm.SetBuffer( (char*) pInBuffer, nInBufSize, FALSE, nInBufSize );
+ mpConvertData = new ConvertData( Graphic(), aIStm, nInFormat );
+
+ if( maFilterHdl.IsSet() && maFilterHdl.Call( mpConvertData ) )
+ {
+ SvMemoryStream aOStm( 645535, 64535 );
+ Graphic& rGraphic = mpConvertData->maGraphic;
+
+ if( ( rGraphic.GetType() == GRAPHIC_BITMAP ) && ( CVT_SVM == nOutFormat ) )
+ {
+ GDIMetaFile aMtf;
+
+ aMtf.SetPrefSize( rGraphic.GetPrefSize() );
+ aMtf.SetPrefMapMode( rGraphic.GetPrefMapMode() );
+ aMtf.AddAction( new MetaBmpExScaleAction( Point(), aMtf.GetPrefSize(), rGraphic.GetBitmapEx() ) );
+ rGraphic = aMtf;
+ }
+ else if( ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) && ( CVT_BMP == nOutFormat ) )
+ rGraphic = rGraphic.GetBitmapEx();
+
+ aOStm << rGraphic;
+
+ if( !aOStm.GetError() )
+ {
+ nRetBufSize = aOStm.Seek( STREAM_SEEK_TO_END );
+ *ppOutBuffer = (void*) aOStm.GetData();
+ aOStm.ObjectOwnsMemory( FALSE );
+ }
+ }
+
+ delete mpConvertData;
+ mpConvertData = NULL;
+ }
+ }
+
+ return nRetBufSize;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG GraphicConverter::Import( SvStream& rIStm, Graphic& rGraphic, ULONG nFormat )
+{
+ GraphicConverter* pCvt = ImplGetSVData()->maGDIData.mpGrfConverter;
+ ULONG nRet = ERRCODE_IO_GENERAL;
+
+ if( pCvt && pCvt->GetFilterHdl().IsSet() )
+ {
+ ConvertData aData( rGraphic, rIStm, nFormat );
+
+ if( pCvt->GetFilterHdl().Call( &aData ) )
+ {
+ rGraphic = aData.maGraphic;
+ nRet = ERRCODE_NONE;
+ }
+ else if( rIStm.GetError() )
+ nRet = rIStm.GetError();
+ }
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG GraphicConverter::Export( SvStream& rOStm, const Graphic& rGraphic, ULONG nFormat )
+{
+ GraphicConverter* pCvt = ImplGetSVData()->maGDIData.mpGrfConverter;
+ ULONG nRet = ERRCODE_IO_GENERAL;
+
+ if( pCvt && pCvt->GetFilterHdl().IsSet() )
+ {
+ ConvertData aData( rGraphic, rOStm, nFormat );
+
+ if( pCvt->GetFilterHdl().Call( &aData ) )
+ nRet = ERRCODE_NONE;
+ else if( rOStm.GetError() )
+ nRet = rOStm.GetError();
+ }
+
+ return nRet;
+}
diff --git a/vcl/source/gdi/cvtsvm.cxx b/vcl/source/gdi/cvtsvm.cxx
new file mode 100644
index 000000000000..f2ac9be53d5d
--- /dev/null
+++ b/vcl/source/gdi/cvtsvm.cxx
@@ -0,0 +1,2106 @@
+/*************************************************************************
+ *
+ * $RCSfile: cvtsvm.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_CVTSVM_CXX
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+
+#include <string.h>
+
+#ifndef _STACK_HXX //autogen
+#include <tools/stack.hxx>
+#endif
+#ifndef _DEBUG_HXX //autogen
+#include <tools/debug.hxx>
+#endif
+#ifndef _STREAM_HXX //autogen
+#include <tools/stream.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_GRAPH_HXX
+#include <graph.hxx>
+#endif
+#ifndef _SV_LINEINFO_HXX
+#include <lineinfo.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#include <cvtsvm.hxx>
+
+// -----------
+// - Defines -
+// -----------
+
+#define CVTSVM_WRITE_SUBACTIONCOUNT 1
+
+// -----------
+// - Inlines -
+// -----------
+
+void ImplReadRect( SvStream& rIStm, Rectangle& rRect )
+{
+ Point aTL;
+ Point aBR;
+
+ rIStm >> aTL;
+ rIStm >> aBR;
+
+ rRect = Rectangle( aTL, aBR );
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWriteRect( SvStream& rOStm, const Rectangle& rRect )
+{
+ rOStm << rRect.TopLeft();
+ rOStm << rRect.BottomRight();
+}
+
+// ------------------------------------------------------------------------
+
+void ImplReadPoly( SvStream& rIStm, Polygon& rPoly )
+{
+ INT32 nSize;
+
+ rIStm >> nSize;
+ rPoly = Polygon( (USHORT) nSize );
+
+ for( USHORT i = 0; i < (USHORT) nSize; i++ )
+ rIStm >> rPoly[ i ];
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWritePoly( SvStream& rOStm, const Polygon& rPoly )
+{
+ INT32 nSize = rPoly.GetSize();
+
+ rOStm << nSize;
+
+ for( INT32 i = 0; i < nSize; i++ )
+ rOStm << rPoly[ (USHORT) i ];
+}
+
+// ------------------------------------------------------------------------
+
+void ImplReadPolyPoly( SvStream& rIStm, PolyPolygon& rPolyPoly )
+{
+ Polygon aPoly;
+ INT32 nPolyCount;
+
+ rIStm >> nPolyCount;
+
+ for( USHORT i = 0; i < (USHORT) nPolyCount; i++ )
+ {
+ ImplReadPoly( rIStm, aPoly );
+ rPolyPoly.Insert( aPoly );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWritePolyPolyAction( SvStream& rOStm, const PolyPolygon& rPolyPoly )
+{
+ const USHORT nPoly = rPolyPoly.Count();
+ USHORT nPoints = 0;
+ USHORT n;
+
+ for( n = 0; n < nPoly; n++ )
+ nPoints += rPolyPoly[ n ].GetSize();
+
+ rOStm << (INT16) GDI_POLYPOLYGON_ACTION;
+ rOStm << (INT32) ( 8 + ( nPoly << 2 ) + ( nPoints << 3 ) );
+ rOStm << (INT32) nPoly;
+
+ for( n = 0; n < nPoly; n++ )
+ {
+ const Polygon& rPoly = rPolyPoly[ n ];
+ const USHORT nSize = rPoly.GetSize();
+
+ rOStm << (INT32) nSize;
+
+ for( USHORT j = 0; j < nSize; j++ )
+ rOStm << rPoly[ j ];
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ImplReadColor( SvStream& rIStm, Color& rColor )
+{
+ INT16 nVal;
+
+ rIStm >> nVal; rColor.SetRed( (USHORT) nVal >> 8 );
+ rIStm >> nVal; rColor.SetGreen( (USHORT) nVal >> 8 );
+ rIStm >> nVal; rColor.SetBlue( (USHORT) nVal >> 8 );
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWriteColor( SvStream& rOStm, const Color& rColor )
+{
+ INT16 nVal;
+
+ nVal = ( (INT16) rColor.GetRed() << 8 ) | rColor.GetRed();
+ rOStm << nVal;
+
+ nVal = ( (INT16) rColor.GetGreen() << 8 ) | rColor.GetGreen();
+ rOStm << nVal;
+
+ nVal = ( (INT16) rColor.GetBlue() << 8 ) | rColor.GetBlue();
+ rOStm << nVal;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplReadMapMode( SvStream& rIStm, MapMode& rMapMode )
+{
+ Point aOrg;
+ INT32 nXNum;
+ INT32 nXDenom;
+ INT32 nYNum;
+ INT32 nYDenom;
+ INT16 nUnit;
+
+ rIStm >> nUnit >> aOrg >> nXNum >> nXDenom >> nYNum >> nYDenom;
+ rMapMode = MapMode( (MapUnit) nUnit, aOrg, Fraction( nXNum, nXDenom ), Fraction( nYNum, nYDenom ) );
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWriteMapMode( SvStream& rOStm, const MapMode& rMapMode )
+{
+ rOStm << (INT16) rMapMode.GetMapUnit();
+ rOStm << rMapMode.GetOrigin();
+ rOStm << (INT32) rMapMode.GetScaleX().GetNumerator();
+ rOStm << (INT32) rMapMode.GetScaleX().GetDenominator();
+ rOStm << (INT32) rMapMode.GetScaleY().GetNumerator();
+ rOStm << (INT32) rMapMode.GetScaleY().GetDenominator();
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWritePushAction( SvStream& rOStm )
+{
+ rOStm << (INT16) GDI_PUSH_ACTION;
+ rOStm << (INT32) 4;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWritePopAction( SvStream& rOStm )
+{
+ rOStm << (INT16) GDI_POP_ACTION;
+ rOStm << (INT32) 4;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWriteLineColor( SvStream& rOStm, const Color& rColor, INT16 nStyle, INT32 nWidth = 0L )
+{
+ if( rColor.GetTransparency() > 127 )
+ nStyle = 0;
+
+ rOStm << (INT16) GDI_PEN_ACTION;
+ rOStm << (INT32) 16;
+ ImplWriteColor( rOStm, rColor );
+ rOStm << nWidth;
+ rOStm << nStyle;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWriteFillColor( SvStream& rOStm, const Color& rColor, INT16 nStyle )
+{
+ rOStm << (INT16) GDI_FILLBRUSH_ACTION;
+ rOStm << (INT32) 20;
+ ImplWriteColor( rOStm, rColor );
+
+ if( rColor.GetTransparency() > 127 )
+ nStyle = 0;
+
+ if( nStyle > 1 )
+ {
+ ImplWriteColor( rOStm, COL_WHITE );
+ rOStm << nStyle;
+ rOStm << (INT16) 1;
+ }
+ else
+ {
+ ImplWriteColor( rOStm, COL_BLACK );
+ rOStm << nStyle;
+ rOStm << (INT16) 0;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWriteFont( SvStream& rOStm, const Font& rFont,
+ rtl_TextEncoding& rActualCharSet )
+{
+ char aName[32];
+ short nWeight;
+
+ ByteString aByteName( rFont.GetName(), rOStm.GetStreamCharSet() );
+ strncpy( aName, aByteName.GetBuffer(), 32 );
+
+ switch ( rFont.GetWeight() )
+ {
+ case WEIGHT_THIN:
+ case WEIGHT_ULTRALIGHT:
+ case WEIGHT_LIGHT:
+ nWeight = 1;
+ break;
+
+ case WEIGHT_NORMAL:
+ case WEIGHT_MEDIUM:
+ nWeight = 2;
+ break;
+
+ case WEIGHT_BOLD:
+ case WEIGHT_ULTRABOLD:
+ case WEIGHT_BLACK:
+ nWeight = 3;
+ break;
+
+ default:
+ nWeight = 0;
+ break;
+ }
+
+ rOStm << (INT16) GDI_FONT_ACTION;
+ rOStm << (INT32) 78;
+
+ rActualCharSet = GetStoreCharSet( rFont.GetCharSet(), rOStm.GetVersion() );
+ ImplWriteColor( rOStm, rFont.GetColor() );
+ ImplWriteColor( rOStm, rFont.GetFillColor() );
+ rOStm.Write( aName, 32 );
+ rOStm << rFont.GetSize();
+ rOStm << (INT16) 0; // no character orientation anymore
+ rOStm << (INT16) rFont.GetOrientation();
+ rOStm << (INT16) rActualCharSet;
+ rOStm << (INT16) rFont.GetFamily();
+ rOStm << (INT16) rFont.GetPitch();
+ rOStm << (INT16) rFont.GetAlign();
+ rOStm << (INT16) nWeight;
+ rOStm << (INT16) rFont.GetUnderline();
+ rOStm << (INT16) rFont.GetStrikeout();
+ rOStm << (BOOL) ( rFont.GetItalic() != ITALIC_NONE );
+ rOStm << rFont.IsOutline();
+ rOStm << rFont.IsShadow();
+ rOStm << rFont.IsTransparent();
+ if ( rActualCharSet == RTL_TEXTENCODING_DONTKNOW )
+ rActualCharSet = gsl_getSystemTextEncoding();
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWriteRasterOpAction( SvStream& rOStm, INT16 nRasterOp )
+{
+ rOStm << (INT16) GDI_RASTEROP_ACTION << (INT32) 6 << nRasterOp;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplSkipActions( SvStream& rIStm, ULONG nSkipCount )
+{
+ INT32 nActionSize;
+ INT16 nType;
+
+ for( ULONG i = 0UL; i < nSkipCount; i++ )
+ {
+ rIStm >> nType >> nActionSize;
+ rIStm.SeekRel( nActionSize - 4L );
+ }
+}
+
+// ----------------
+// - SVMConverter -
+// ----------------
+
+SVMConverter::SVMConverter( SvStream& rStm, GDIMetaFile& rMtf, ULONG nConvertMode )
+{
+ if( !rStm.GetError() )
+ {
+ if( CONVERT_FROM_SVM1 == nConvertMode )
+ ImplConvertFromSVM1( rStm, rMtf );
+ else if( CONVERT_TO_SVM1 == nConvertMode )
+ ImplConvertToSVM1( rStm, rMtf );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf )
+{
+ LineInfo aLineInfo( LINE_NONE, 0 );
+ Stack aLIStack;
+ ULONG nPos = rIStm.Tell();
+ const USHORT nOldFormat = rIStm.GetNumberFormatInt();
+ rtl_TextEncoding eActualCharSet = gsl_getSystemTextEncoding();
+ BOOL bFatLine = FALSE;
+
+ rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ char aCode[ 5 ];
+ MapMode aMapMode;
+ Size aPrefSz;
+ INT32 nActions;
+ INT16 nSize;
+ INT16 nVersion;
+
+ // Header lesen
+ rIStm.Read( (char*) &aCode, sizeof( aCode ) ); // Kennung
+ rIStm >> nSize; // Size
+ rIStm >> nVersion; // Version
+ rIStm >> aPrefSz; // PrefSize
+ ImplReadMapMode( rIStm, aMapMode ); // MapMode
+ rIStm >> nActions; // Action count
+
+ // Header-Kennung und Versionsnummer pruefen
+ if( ( memcmp( aCode, "SVGDI", sizeof( aCode ) ) != 0 ) || ( nVersion != 200 ) )
+ {
+ rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ rIStm.SetNumberFormatInt( nOldFormat );
+ rIStm.Seek( nPos );
+ }
+ else
+ {
+ Polygon aPoly;
+ Rectangle aRect;
+ Point aPt, aPt1;
+ Size aSz;
+ Color aColor;
+ INT32 nTmp, nTmp1, nActionSize;
+ INT16 nType;
+
+ rMtf.SetPrefSize( aPrefSz );
+ rMtf.SetPrefMapMode( aMapMode );
+
+ for( INT32 i = 0L; i < nActions; i++ )
+ {
+ rIStm >> nType;
+ rIStm >> nActionSize;
+
+ DBG_ASSERT( ( nType <= 33 ) || ( nType >= 1024 ), "Unknown GDIMetaAction while converting!" );
+
+ switch( nType )
+ {
+ case( GDI_PIXEL_ACTION ):
+ {
+ rIStm >> aPt;
+ ImplReadColor( rIStm, aColor );
+ rMtf.AddAction( new MetaPixelAction( aPt, aColor ) );
+ }
+ break;
+
+ case( GDI_POINT_ACTION ):
+ {
+ rIStm >> aPt;
+ rMtf.AddAction( new MetaPointAction( aPt ) );
+ }
+ break;
+
+ case( GDI_LINE_ACTION ):
+ {
+ rIStm >> aPt >> aPt1;
+ rMtf.AddAction( new MetaLineAction( aPt, aPt1, aLineInfo ) );
+ }
+ break;
+
+ case( GDI_RECT_ACTION ):
+ {
+ ImplReadRect( rIStm, aRect );
+ rIStm >> nTmp >> nTmp1;
+
+ if( nTmp || nTmp1 )
+ rMtf.AddAction( new MetaRoundRectAction( aRect, nTmp, nTmp1 ) );
+ else
+ {
+ rMtf.AddAction( new MetaRectAction( aRect ) );
+
+ if( bFatLine )
+ rMtf.AddAction( new MetaPolyLineAction( aRect, aLineInfo ) );
+ }
+ }
+ break;
+
+ case( GDI_ELLIPSE_ACTION ):
+ {
+ ImplReadRect( rIStm, aRect );
+
+ if( bFatLine )
+ {
+ const Polygon aPoly( aRect.Center(), aRect.GetWidth() >> 1, aRect.GetHeight() >> 1 );
+
+ rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, FALSE ) );
+ rMtf.AddAction( new MetaPolygonAction( aPoly ) );
+ rMtf.AddAction( new MetaPopAction() );
+ rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
+ }
+ else
+ rMtf.AddAction( new MetaEllipseAction( aRect ) );
+ }
+ break;
+
+ case( GDI_ARC_ACTION ):
+ {
+ ImplReadRect( rIStm, aRect );
+ rIStm >> aPt >> aPt1;
+
+ if( bFatLine )
+ {
+ const Polygon aPoly( aRect, aPt, aPt1, POLY_ARC );
+
+ rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, FALSE ) );
+ rMtf.AddAction( new MetaPolygonAction( aPoly ) );
+ rMtf.AddAction( new MetaPopAction() );
+ rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
+ }
+ else
+ rMtf.AddAction( new MetaArcAction( aRect, aPt, aPt1 ) );
+ }
+ break;
+
+ case( GDI_PIE_ACTION ):
+ {
+ ImplReadRect( rIStm, aRect );
+ rIStm >> aPt >> aPt1;
+
+ if( bFatLine )
+ {
+ const Polygon aPoly( aRect, aPt, aPt1, POLY_PIE );
+
+ rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, FALSE ) );
+ rMtf.AddAction( new MetaPolygonAction( aPoly ) );
+ rMtf.AddAction( new MetaPopAction() );
+ rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
+ }
+ else
+ rMtf.AddAction( new MetaPieAction( aRect, aPt, aPt1 ) );
+ }
+ break;
+
+ case( GDI_INVERTRECT_ACTION ):
+ case( GDI_HIGHLIGHTRECT_ACTION ):
+ {
+ ImplReadRect( rIStm, aRect );
+ rMtf.AddAction( new MetaPushAction( PUSH_RASTEROP ) );
+ rMtf.AddAction( new MetaRasterOpAction( ROP_INVERT ) );
+ rMtf.AddAction( new MetaRectAction( aRect ) );
+ rMtf.AddAction( new MetaPopAction() );
+ }
+ break;
+
+ case( GDI_POLYLINE_ACTION ):
+ {
+ ImplReadPoly( rIStm, aPoly );
+
+ if( bFatLine )
+ rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
+ else
+ rMtf.AddAction( new MetaPolyLineAction( aPoly ) );
+ }
+ break;
+
+ case( GDI_POLYGON_ACTION ):
+ {
+ ImplReadPoly( rIStm, aPoly );
+
+ if( bFatLine )
+ {
+ rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, FALSE ) );
+ rMtf.AddAction( new MetaPolygonAction( aPoly ) );
+ rMtf.AddAction( new MetaPopAction() );
+ rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
+ }
+ else
+ rMtf.AddAction( new MetaPolygonAction( aPoly ) );
+ }
+ break;
+
+ case( GDI_POLYPOLYGON_ACTION ):
+ {
+ PolyPolygon aPolyPoly;
+
+ ImplReadPolyPoly( rIStm, aPolyPoly );
+
+ if( bFatLine )
+ {
+ rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, FALSE ) );
+ rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
+ rMtf.AddAction( new MetaPopAction() );
+
+ for( USHORT nPoly = 0, nCount = aPolyPoly.Count(); nPoly < nCount; nPoly++ )
+ rMtf.AddAction( new MetaPolyLineAction( aPolyPoly[ nPoly ], aLineInfo ) );
+ }
+ else
+ rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
+ }
+ break;
+
+ case( GDI_FONT_ACTION ):
+ {
+ Font aFont;
+ char aName[ 32 ];
+ INT32 nWidth, nHeight;
+ INT16 nCharSet, nFamily, nPitch, nAlign, nWeight, nUnderline, nStrikeout;
+ INT16 nCharOrient, nLineOrient;
+ BOOL bItalic, bOutline, bShadow, bTransparent;
+
+ ImplReadColor( rIStm, aColor ); aFont.SetColor( aColor );
+ ImplReadColor( rIStm, aColor ); aFont.SetFillColor( aColor );
+ rIStm.Read( aName, 32 );
+ aFont.SetName( UniString( aName, rIStm.GetStreamCharSet() ) );
+ rIStm >> nWidth >> nHeight;
+ rIStm >> nCharOrient >> nLineOrient;
+ rIStm >> nCharSet >> nFamily >> nPitch >> nAlign >> nWeight >> nUnderline >> nStrikeout;
+ rIStm >> bItalic >> bOutline >> bShadow >> bTransparent;
+
+ aFont.SetSize( Size( nWidth, nHeight ) );
+ aFont.SetCharSet( (CharSet) nCharSet );
+ aFont.SetFamily( (FontFamily) nFamily );
+ aFont.SetPitch( (FontPitch) nPitch );
+ aFont.SetAlign( (FontAlign) nAlign );
+ aFont.SetWeight( ( nWeight == 1 ) ? WEIGHT_LIGHT : ( nWeight == 2 ) ? WEIGHT_NORMAL :
+ ( nWeight == 3 ) ? WEIGHT_BOLD : WEIGHT_DONTKNOW );
+ aFont.SetUnderline( (FontUnderline) nUnderline );
+ aFont.SetStrikeout( (FontStrikeout) nStrikeout );
+ aFont.SetItalic( bItalic ? ITALIC_NORMAL : ITALIC_NONE );
+ aFont.SetOutline( bOutline );
+ aFont.SetShadow( bShadow );
+ aFont.SetOrientation( nLineOrient );
+ aFont.SetTransparent( bTransparent );
+
+ eActualCharSet = aFont.GetCharSet();
+ if ( eActualCharSet == RTL_TEXTENCODING_DONTKNOW )
+ eActualCharSet = gsl_getSystemTextEncoding();
+ rMtf.AddAction( new MetaFontAction( aFont ) );
+ }
+ break;
+
+ case( GDI_TEXT_ACTION ):
+ {
+ ByteString aByteStr;
+ INT32 nIndex, nLen;
+
+ rIStm >> aPt >> nIndex >> nLen >> nTmp;
+ rIStm.Read( aByteStr.AllocBuffer( (USHORT)nTmp ), nTmp + 1 );
+ UniString aStr( aByteStr, eActualCharSet );
+ rMtf.AddAction( new MetaTextAction( aPt, aStr, (USHORT) nIndex, (USHORT) nLen ) );
+ }
+ break;
+
+ case( GDI_TEXTARRAY_ACTION ):
+ {
+ ByteString aByteStr;
+ long* pDXAry = NULL;
+ INT32 nIndex, nLen, nAryLen;
+
+ rIStm >> aPt >> nIndex >> nLen >> nTmp >> nAryLen;
+ rIStm.Read( aByteStr.AllocBuffer( (USHORT)nTmp ), nTmp + 1 );
+ UniString aStr( aByteStr, eActualCharSet );
+
+ if( nAryLen > 0L )
+ {
+ pDXAry = new long[ nAryLen ];
+
+ for( long i = 0L; i < nAryLen; i++ )
+ rIStm >> nTmp, pDXAry[ i ] = nTmp;
+ }
+
+ rMtf.AddAction( new MetaTextArrayAction( aPt, aStr, pDXAry, (USHORT) nIndex, (USHORT) nLen ) );
+
+ if( pDXAry )
+ delete[] pDXAry;
+ }
+ break;
+
+ case( GDI_STRETCHTEXT_ACTION ):
+ {
+ ByteString aByteStr;
+ INT32 nIndex, nLen, nWidth;
+
+ rIStm >> aPt >> nIndex >> nLen >> nTmp >> nWidth;
+ rIStm.Read( aByteStr.AllocBuffer( (USHORT)nTmp ), nTmp + 1 );
+ UniString aStr( aByteStr, eActualCharSet );
+ rMtf.AddAction( new MetaStretchTextAction( aPt, nWidth, aStr, (USHORT) nIndex, (USHORT) nLen ) );
+ }
+ break;
+
+ case( GDI_BITMAP_ACTION ):
+ {
+ Bitmap aBmp;
+
+ rIStm >> aPt >> aBmp;
+ rMtf.AddAction( new MetaBmpAction( aPt, aBmp ) );
+ }
+ break;
+
+ case( GDI_BITMAPSCALE_ACTION ):
+ {
+ Bitmap aBmp;
+
+ rIStm >> aPt >> aSz >> aBmp;
+ rMtf.AddAction( new MetaBmpScaleAction( aPt, aSz, aBmp ) );
+ }
+ break;
+
+ case( GDI_BITMAPSCALEPART_ACTION ):
+ {
+ Bitmap aBmp;
+ Size aSz2;
+
+ rIStm >> aPt >> aSz >> aPt1 >> aSz2 >> aBmp;
+ rMtf.AddAction( new MetaBmpScalePartAction( aPt, aSz, aPt1, aSz2, aBmp ) );
+ }
+ break;
+
+ case( GDI_PEN_ACTION ):
+ {
+ INT32 nPenWidth;
+ INT16 nPenStyle;
+
+ ImplReadColor( rIStm, aColor );
+ rIStm >> nPenWidth >> nPenStyle;
+
+ aLineInfo.SetStyle( nPenStyle ? LINE_SOLID : LINE_NONE );
+ aLineInfo.SetWidth( nPenWidth );
+ bFatLine = nPenStyle && !aLineInfo.IsDefault();
+
+ rMtf.AddAction( new MetaLineColorAction( aColor, nPenStyle != 0 ) );
+ }
+ break;
+
+ case( GDI_FILLBRUSH_ACTION ):
+ {
+ INT16 nBrushStyle;
+
+ ImplReadColor( rIStm, aColor );
+ rIStm.SeekRel( 6L );
+ rIStm >> nBrushStyle;
+ rMtf.AddAction( new MetaFillColorAction( aColor, nBrushStyle != 0 ) );
+ rIStm.SeekRel( 2L );
+ }
+ break;
+
+ case( GDI_MAPMODE_ACTION ):
+ {
+ ImplReadMapMode( rIStm, aMapMode );
+ rMtf.AddAction( new MetaMapModeAction( aMapMode ) );
+ }
+ break;
+
+ case( GDI_CLIPREGION_ACTION ):
+ {
+ Region aRegion;
+ INT16 nRegType;
+ INT16 bIntersect;
+ BOOL bClip = FALSE;
+
+ rIStm >> nRegType >> bIntersect;
+ ImplReadRect( rIStm, aRect );
+
+ switch( nRegType )
+ {
+ case( 0 ):
+ break;
+
+ case( 1 ):
+ {
+ Rectangle aRegRect;
+
+ ImplReadRect( rIStm, aRegRect );
+ aRegion = Region( aRegRect );
+ bClip = TRUE;
+ }
+ break;
+
+ case( 2 ):
+ {
+ ImplReadPoly( rIStm, aPoly );
+ aRegion = Region( aPoly );
+ bClip = TRUE;
+ }
+ break;
+
+ case( 3 ):
+ {
+ PolyPolygon aPolyPoly;
+ INT32 nPolyCount;
+
+ rIStm >> nPolyCount;
+
+ for( USHORT i = 0; i < (USHORT) nPolyCount; i++ )
+ {
+ ImplReadPoly( rIStm, aPoly );
+ aPolyPoly.Insert( aPoly );
+ }
+
+ aRegion = Region( aPolyPoly );
+ bClip = TRUE;
+ }
+ break;
+ }
+
+ if( bIntersect )
+ aRegion.Intersect( aRect );
+
+ rMtf.AddAction( new MetaClipRegionAction( aRegion, bClip ) );
+ }
+ break;
+
+ case( GDI_MOVECLIPREGION_ACTION ):
+ {
+ rIStm >> nTmp >> nTmp1;
+ rMtf.AddAction( new MetaMoveClipRegionAction( nTmp, nTmp1 ) );
+ }
+ break;
+
+ case( GDI_ISECTCLIPREGION_ACTION ):
+ {
+ ImplReadRect( rIStm, aRect );
+ rMtf.AddAction( new MetaISectRectClipRegionAction( aRect ) );
+ }
+ break;
+
+ case( GDI_RASTEROP_ACTION ):
+ {
+ RasterOp eRasterOp;
+ INT16 nRasterOp;
+
+ rIStm >> nRasterOp;
+
+ switch( nRasterOp )
+ {
+ case( 1 ):
+ eRasterOp = ROP_INVERT;
+ break;
+
+ case( 4 ):
+ case( 5 ):
+ eRasterOp = ROP_XOR;
+ break;
+
+ default:
+ eRasterOp = ROP_OVERPAINT;
+ break;
+ }
+
+ rMtf.AddAction( new MetaRasterOpAction( eRasterOp ) );
+ }
+ break;
+
+ case( GDI_PUSH_ACTION ):
+ {
+ aLIStack.Push( new LineInfo( aLineInfo ) );
+ rMtf.AddAction( new MetaPushAction( PUSH_ALL ) );
+ }
+ break;
+
+ case( GDI_POP_ACTION ):
+ {
+
+ LineInfo* pLineInfo = (LineInfo*) aLIStack.Pop();
+
+ // restore line info
+ if( pLineInfo )
+ {
+ aLineInfo = *pLineInfo;
+ delete pLineInfo;
+ bFatLine = ( LINE_NONE != aLineInfo.GetStyle() ) && !aLineInfo.IsDefault();
+ }
+
+ rMtf.AddAction( new MetaPopAction() );
+ }
+ break;
+
+ case( GDI_GRADIENT_ACTION ):
+ {
+ Color aStartCol;
+ Color aEndCol;
+ INT16 nStyle;
+ INT16 nAngle;
+ INT16 nBorder;
+ INT16 nOfsX;
+ INT16 nOfsY;
+ INT16 nIntensityStart;
+ INT16 nIntensityEnd;
+
+ ImplReadRect( rIStm, aRect );
+ rIStm >> nStyle;
+ ImplReadColor( rIStm, aStartCol );
+ ImplReadColor( rIStm, aEndCol );
+ rIStm >> nAngle >> nBorder >> nOfsX >> nOfsY >> nIntensityStart >> nIntensityEnd;
+
+ Gradient aGrad( (GradientStyle) nStyle, aStartCol, aEndCol );
+
+ aGrad.SetAngle( nAngle );
+ aGrad.SetBorder( nBorder );
+ aGrad.SetOfsX( nOfsX );
+ aGrad.SetOfsY( nOfsY );
+ aGrad.SetStartIntensity( nIntensityStart );
+ aGrad.SetEndIntensity( nIntensityEnd );
+ rMtf.AddAction( new MetaGradientAction( aRect, aGrad ) );
+ }
+ break;
+
+ case( GDI_TRANSPARENT_COMMENT ):
+ {
+ PolyPolygon aPolyPoly;
+ INT32 nFollowingActionCount;
+ INT16 nTrans;
+
+ rIStm >> aPolyPoly >> nTrans >> nFollowingActionCount;
+ ImplSkipActions( rIStm, nFollowingActionCount );
+ rMtf.AddAction( new MetaTransparentAction( aPolyPoly, nTrans ) );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ i += nFollowingActionCount;
+#endif
+ }
+ break;
+
+ case( GDI_FLOATTRANSPARENT_COMMENT ):
+ {
+ GDIMetaFile aMtf;
+ Point aPos;
+ Size aSize;
+ Gradient aGradient;
+ INT32 nFollowingActionCount;
+
+ rIStm >> aMtf >> aPos >> aSize >> aGradient >> nFollowingActionCount;
+ ImplSkipActions( rIStm, nFollowingActionCount );
+ rMtf.AddAction( new MetaFloatTransparentAction( aMtf, aPos, aSize, aGradient ) );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ i += nFollowingActionCount;
+#endif
+ }
+ break;
+
+ case( GDI_HATCH_COMMENT ):
+ {
+ PolyPolygon aPolyPoly;
+ Hatch aHatch;
+ INT32 nFollowingActionCount;
+
+ rIStm >> aPolyPoly >> aHatch >> nFollowingActionCount;
+ ImplSkipActions( rIStm, nFollowingActionCount );
+ rMtf.AddAction( new MetaHatchAction( aPolyPoly, aHatch ) );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ i += nFollowingActionCount;
+#endif
+ }
+ break;
+
+ case( GDI_REFPOINT_COMMENT ):
+ {
+ Point aRefPoint;
+ BOOL bSet;
+ INT32 nFollowingActionCount;
+
+ rIStm >> aRefPoint >> bSet >> nFollowingActionCount;
+ ImplSkipActions( rIStm, nFollowingActionCount );
+ rMtf.AddAction( new MetaRefPointAction( aRefPoint, bSet ) );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ i += nFollowingActionCount;
+#endif
+ }
+ break;
+
+ case( GDI_TEXTLINECOLOR_COMMENT ):
+ {
+ Color aColor;
+ BOOL bSet;
+ INT32 nFollowingActionCount;
+
+ rIStm >> aColor >> bSet >> nFollowingActionCount;
+ ImplSkipActions( rIStm, nFollowingActionCount );
+ rMtf.AddAction( new MetaTextLineColorAction( aColor, bSet ) );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ i += nFollowingActionCount;
+#endif
+ }
+ break;
+
+ case( GDI_TEXTLINE_COMMENT ):
+ {
+ Point aStartPt;
+ long nWidth;
+ ULONG nStrikeout;
+ ULONG nUnderline;
+ INT32 nFollowingActionCount;
+
+ rIStm >> aStartPt >> nWidth >> nStrikeout >> nUnderline >> nFollowingActionCount;
+ ImplSkipActions( rIStm, nFollowingActionCount );
+ rMtf.AddAction( new MetaTextLineAction( aStartPt, nWidth,
+ (FontStrikeout) nStrikeout,
+ (FontUnderline) nUnderline ) );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ i += nFollowingActionCount;
+#endif
+ }
+ break;
+
+ case( GDI_GRADIENTEX_COMMENT ):
+ {
+ PolyPolygon aPolyPoly;
+ Gradient aGradient;
+ INT32 nFollowingActionCount;
+
+ rIStm >> aPolyPoly >> aGradient >> nFollowingActionCount;
+ ImplSkipActions( rIStm, nFollowingActionCount );
+ rMtf.AddAction( new MetaGradientExAction( aPolyPoly, aGradient ) );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ i += nFollowingActionCount;
+#endif
+ }
+ break;
+
+ case( GDI_COMMENT_COMMENT ):
+ {
+ ByteString aComment;
+ long nValue;
+ ULONG nDataSize;
+ BYTE* pData;
+ INT32 nFollowingActionCount;
+
+ rIStm >> aComment >> nValue >> nDataSize;
+
+ if( nDataSize )
+ {
+ pData = new BYTE[ nDataSize ];
+ rIStm.Read( pData, nDataSize );
+ }
+ else
+ pData = NULL;
+
+ rIStm >> nFollowingActionCount;
+ ImplSkipActions( rIStm, nFollowingActionCount );
+ rMtf.AddAction( new MetaCommentAction( aComment, nValue, pData, nDataSize ) );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ i += nFollowingActionCount;
+#endif
+ }
+ break;
+
+ default:
+ rIStm.SeekRel( nActionSize - 4L );
+ break;
+ }
+ }
+
+ // cleanup push-pop stack if neccessary
+ for( void* pLineInfo = aLIStack.Pop(); pLineInfo; pLineInfo = aLIStack.Pop() )
+ delete (LineInfo*) pLineInfo;
+ }
+
+ rIStm.SetNumberFormatInt( nOldFormat );
+}
+
+// ------------------------------------------------------------------------
+
+void SVMConverter::ImplConvertToSVM1( SvStream& rOStm, GDIMetaFile& rMtf )
+{
+ ULONG nPos;
+ ULONG nCountPos;
+ Font aSaveFont;
+ const ULONG nActionCount = rMtf.GetActionCount();
+ const USHORT nOldFormat = rOStm.GetNumberFormatInt();
+ rtl_TextEncoding eActualCharSet = gsl_getSystemTextEncoding();
+ const Size aPrefSize( rMtf.GetPrefSize() );
+ BOOL bRop_0_1 = FALSE;
+ VirtualDevice aSaveVDev;
+ Color aLineCol( COL_BLACK );
+ Stack aLineColStack;
+
+ rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ //MagicCode schreiben
+ rOStm << "SVGDI"; // Kennung
+ nPos = rOStm.Tell();
+ rOStm << (INT16) 42; // HeaderSize
+ rOStm << (INT16) 200; // VERSION
+ rOStm << (INT32) aPrefSize.Width();
+ rOStm << (INT32) aPrefSize.Height();
+ ImplWriteMapMode( rOStm, rMtf.GetPrefMapMode() );
+
+ // ActionCount wird spaeter geschrieben
+ nCountPos = rOStm.Tell();
+ rOStm.SeekRel( 4L );
+
+ const INT32 nActCount = ImplWriteActions( rOStm, rMtf, aSaveVDev, bRop_0_1, aLineCol, aLineColStack, eActualCharSet );
+ const ULONG nActPos = rOStm.Tell();
+
+ rOStm.Seek( nCountPos );
+ rOStm << nActCount;
+ rOStm.Seek( nActPos );
+ rOStm.SetNumberFormatInt( nOldFormat );
+
+ // cleanup push-pop stack if neccessary
+ for( void* pCol = aLineColStack.Pop(); pCol; pCol = aLineColStack.Pop() )
+ delete (Color*) pCol;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
+ VirtualDevice& rSaveVDev, BOOL& rRop_0_1,
+ Color& rLineCol, Stack& rLineColStack,
+ rtl_TextEncoding& rActualCharSet )
+{
+ ULONG nCount = 0;
+ for( ULONG i = 0, nActionCount = rMtf.GetActionCount(); i < nActionCount; i++ )
+ {
+ const MetaAction* pAction = rMtf.GetAction( i );
+
+ switch( pAction->GetType() )
+ {
+ case( META_PIXEL_ACTION ):
+ {
+ MetaPixelAction* pAct = (MetaPixelAction*) pAction;
+
+ rOStm << (INT16) GDI_PIXEL_ACTION;
+ rOStm << (INT32) 18;
+ rOStm << pAct->GetPoint();
+ ImplWriteColor( rOStm, pAct->GetColor() );
+ nCount++;
+ }
+ break;
+
+ case( META_POINT_ACTION ):
+ {
+ MetaPointAction* pAct = (MetaPointAction*) pAction;
+
+ rOStm << (INT16) GDI_POINT_ACTION;
+ rOStm << (INT32) 12;
+ rOStm << pAct->GetPoint();
+ nCount++;
+ }
+ break;
+
+ case( META_LINE_ACTION ):
+ {
+ MetaLineAction* pAct = (MetaLineAction*) pAction;
+ const LineInfo& rInfo = pAct->GetLineInfo();
+ const BOOL bFatLine = ( !rInfo.IsDefault() && ( LINE_NONE != rInfo.GetStyle() ) );
+
+ if( bFatLine )
+ {
+ ImplWritePushAction( rOStm );
+ ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
+ }
+
+ rOStm << (INT16) GDI_LINE_ACTION;
+ rOStm << (INT32) 20;
+ rOStm << pAct->GetStartPoint();
+ rOStm << pAct->GetEndPoint();
+ nCount++;
+
+ if( bFatLine )
+ {
+ ImplWritePopAction( rOStm );
+ nCount += 3;
+ }
+ }
+ break;
+
+ case( META_RECT_ACTION ):
+ {
+ MetaRectAction* pAct = (MetaRectAction*) pAction;
+
+ rOStm << (INT16) GDI_RECT_ACTION;
+ rOStm << (INT32) 28;
+ ImplWriteRect( rOStm, pAct->GetRect() );
+ rOStm << (INT32) 0;
+ rOStm << (INT32) 0;
+ nCount++;
+ }
+ break;
+
+ case( META_ROUNDRECT_ACTION ):
+ {
+ MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction;
+
+ rOStm << (INT16) GDI_RECT_ACTION;
+ rOStm << (INT32) 28;
+ ImplWriteRect( rOStm, pAct->GetRect() );
+ rOStm << (INT32) pAct->GetHorzRound();
+ rOStm << (INT32) pAct->GetVertRound();
+ nCount++;
+ }
+ break;
+
+ case( META_ELLIPSE_ACTION ):
+ {
+ MetaEllipseAction* pAct = (MetaEllipseAction*) pAction;
+
+ rOStm << (INT16) GDI_ELLIPSE_ACTION;
+ rOStm << (INT32) 20;
+ ImplWriteRect( rOStm, pAct->GetRect() );
+ nCount++;
+ }
+ break;
+
+ case( META_ARC_ACTION ):
+ {
+ MetaArcAction* pAct = (MetaArcAction*) pAction;
+
+ rOStm << (INT16) GDI_ARC_ACTION;
+ rOStm << (INT32) 36;
+ ImplWriteRect( rOStm, pAct->GetRect() );
+ rOStm << pAct->GetStartPoint();
+ rOStm << pAct->GetEndPoint();
+ nCount++;
+ }
+ break;
+
+ case( META_PIE_ACTION ):
+ {
+ MetaPieAction* pAct = (MetaPieAction*) pAction;
+
+ rOStm << (INT16) GDI_PIE_ACTION;
+ rOStm << (INT32) 36;
+ ImplWriteRect( rOStm, pAct->GetRect() );
+ rOStm << pAct->GetStartPoint();
+ rOStm << pAct->GetEndPoint();
+ nCount++;
+ }
+ break;
+
+ case( META_CHORD_ACTION ):
+ {
+ MetaChordAction* pAct = (MetaChordAction*) pAction;
+ Polygon aChordPoly( pAct->GetRect(), pAct->GetStartPoint(),
+ pAct->GetEndPoint(), POLY_CHORD );
+ const USHORT nPoints = aChordPoly.GetSize();
+
+ rOStm << (INT16) GDI_POLYGON_ACTION;
+ rOStm << (INT32) ( 8 + ( nPoints << 3 ) );
+ rOStm << (INT32) nPoints;
+
+ for( USHORT n = 0; n < nPoints; n++ )
+ rOStm << aChordPoly[ n ];
+
+ nCount++;
+ }
+ break;
+
+ case( META_POLYLINE_ACTION ):
+ {
+ MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction;
+ const Polygon& rPoly = pAct->GetPolygon();
+ const LineInfo& rInfo = pAct->GetLineInfo();
+ const USHORT nPoints = rPoly.GetSize();
+ const BOOL bFatLine = ( !rInfo.IsDefault() && ( LINE_NONE != rInfo.GetStyle() ) );
+
+ if( bFatLine )
+ {
+ ImplWritePushAction( rOStm );
+ ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
+ }
+
+ rOStm << (INT16) GDI_POLYLINE_ACTION;
+ rOStm << (INT32) ( 8 + ( nPoints << 3 ) );
+ rOStm << (INT32) nPoints;
+
+ for( USHORT n = 0; n < nPoints; n++ )
+ rOStm << rPoly[ n ];
+
+ nCount++;
+
+ if( bFatLine )
+ {
+ ImplWritePopAction( rOStm );
+ nCount += 3;
+ }
+ }
+ break;
+
+ case( META_POLYGON_ACTION ):
+ {
+ MetaPolygonAction* pAct = (MetaPolygonAction*) pAction;
+ const Polygon& rPoly = pAct->GetPolygon();
+ const USHORT nPoints = rPoly.GetSize();
+
+ rOStm << (INT16) GDI_POLYGON_ACTION;
+ rOStm << (INT32) ( 8 + ( nPoints << 3 ) );
+ rOStm << (INT32) nPoints;
+
+ for( USHORT n = 0; n < nPoints; n++ )
+ rOStm << rPoly[ n ];
+
+ nCount++;
+ }
+ break;
+
+ case( META_POLYPOLYGON_ACTION ):
+ {
+ MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction;
+ ImplWritePolyPolyAction( rOStm, pAct->GetPolyPolygon() );
+ nCount++;
+ }
+ break;
+
+ case( META_TEXT_ACTION ):
+ {
+ MetaTextAction* pAct = (MetaTextAction*) pAction;
+ ByteString aText( pAct->GetText(), rActualCharSet );
+ const ULONG nStrLen = aText.Len();
+
+ rOStm << (INT16) GDI_TEXT_ACTION;
+ rOStm << (INT32) ( 24 + ( nStrLen + 1 ) );
+ rOStm << pAct->GetPoint();
+ rOStm << (INT32) pAct->GetIndex();
+ rOStm << (INT32) pAct->GetLen();
+ rOStm << (INT32) nStrLen;
+ rOStm.Write( aText.GetBuffer(), nStrLen + 1 );
+ nCount++;
+ }
+ break;
+
+ case( META_TEXTARRAY_ACTION ):
+ {
+ MetaTextArrayAction* pAct = (MetaTextArrayAction*)pAction;
+ ByteString aText( pAct->GetText(), rActualCharSet );
+ ULONG nAryLen;
+ ULONG nLen = pAct->GetLen();
+ const ULONG nTextLen = aText.Len();
+ long* pDXArray = pAct->GetDXArray();
+
+ if( ( nLen + pAct->GetIndex() ) > nTextLen )
+ {
+ if( pAct->GetIndex() <= nTextLen )
+ nLen = nTextLen - pAct->GetIndex();
+ else
+ nLen = 0UL;
+ }
+
+ if( !pDXArray || !nLen )
+ nAryLen = 0;
+ else
+ nAryLen = nLen - 1;
+
+ rOStm << (INT16) GDI_TEXTARRAY_ACTION;
+ rOStm << (INT32) ( 28 + ( nLen + 1 ) + ( nAryLen * 4 ) );
+ rOStm << pAct->GetPoint();
+ rOStm << (INT32) 0;
+ rOStm << (INT32) nLen;
+ rOStm << (INT32) nLen;
+ rOStm << (INT32) nAryLen;
+ rOStm.Write( aText.GetBuffer()+pAct->GetIndex(), nLen + 1 );
+
+ for( ULONG n = 0UL ; n < nAryLen; n++ )
+ rOStm << (INT32) pDXArray[ n ];
+
+ nCount++;
+ }
+ break;
+
+ case( META_STRETCHTEXT_ACTION ):
+ {
+ MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction;
+ ByteString aText( pAct->GetText(), rActualCharSet );
+ const ULONG nStrLen = aText.Len();
+
+ rOStm << (INT16) GDI_STRETCHTEXT_ACTION;
+ rOStm << (INT32) ( 28 + ( nStrLen + 1 ) );
+ rOStm << pAct->GetPoint();
+ rOStm << (INT32) pAct->GetIndex();
+ rOStm << (INT32) pAct->GetLen();
+ rOStm << (INT32) nStrLen;
+ rOStm << (INT32) pAct->GetWidth();
+ rOStm.Write( aText.GetBuffer(), nStrLen + 1 );
+ nCount++;
+ }
+ break;
+
+ case( META_BMP_ACTION ):
+ {
+ MetaBmpAction* pAct = (MetaBmpAction*) pAction;
+
+ rOStm << (INT16) GDI_BITMAP_ACTION;
+ rOStm << (INT32) 12;
+ rOStm << pAct->GetPoint();
+ rOStm << pAct->GetBitmap();
+ nCount++;
+ }
+ break;
+
+ case( META_BMPSCALE_ACTION ):
+ {
+ MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
+
+ rOStm << (INT16) GDI_BITMAPSCALE_ACTION;
+ rOStm << (INT32) 20;
+ rOStm << pAct->GetPoint();
+ rOStm << pAct->GetSize();
+ rOStm << pAct->GetBitmap();
+ nCount++;
+ }
+ break;
+
+ case( META_BMPSCALEPART_ACTION ):
+ {
+ MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
+
+ rOStm << (INT16) GDI_BITMAPSCALEPART_ACTION;
+ rOStm << (INT32) 36;
+ rOStm << pAct->GetDestPoint();
+ rOStm << pAct->GetDestSize();
+ rOStm << pAct->GetSrcPoint();
+ rOStm << pAct->GetSrcSize();
+ rOStm << pAct->GetBitmap();
+ nCount++;
+ }
+ break;
+
+ case( META_BMPEX_ACTION ):
+ {
+ MetaBmpExAction* pAct = (MetaBmpExAction*) pAction;
+ const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
+
+ rOStm << (INT16) GDI_BITMAP_ACTION;
+ rOStm << (INT32) 12;
+ rOStm << pAct->GetPoint();
+ rOStm << aBmp;
+ nCount++;
+ }
+ break;
+
+ case( META_BMPEXSCALE_ACTION ):
+ {
+ MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction;
+ const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
+
+ rOStm << (INT16) GDI_BITMAPSCALE_ACTION;
+ rOStm << (INT32) 20;
+ rOStm << pAct->GetPoint();
+ rOStm << pAct->GetSize();
+ rOStm << aBmp;
+ nCount++;
+ }
+ break;
+
+ case( META_BMPEXSCALEPART_ACTION ):
+ {
+ MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction;
+ const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
+
+ rOStm << (INT16) GDI_BITMAPSCALEPART_ACTION;
+ rOStm << (INT32) 36;
+ rOStm << pAct->GetDestPoint();
+ rOStm << pAct->GetDestSize();
+ rOStm << pAct->GetSrcPoint();
+ rOStm << pAct->GetSrcSize();
+ rOStm << aBmp;
+ nCount++;
+ }
+ break;
+
+ case( META_GRADIENT_ACTION ):
+ {
+ MetaGradientAction* pAct = (MetaGradientAction*) pAction;
+ const Gradient& rGrad = pAct->GetGradient();
+
+ rOStm << (INT16) GDI_GRADIENT_ACTION;
+ rOStm << (INT32) 46;
+ ImplWriteRect( rOStm, pAct->GetRect() );
+ rOStm << (INT16) rGrad.GetStyle();
+ ImplWriteColor( rOStm, rGrad.GetStartColor() );
+ ImplWriteColor( rOStm, rGrad.GetEndColor() );
+ rOStm << (INT16) rGrad.GetAngle();
+ rOStm << (INT16) rGrad.GetBorder();
+ rOStm << (INT16) rGrad.GetOfsX();
+ rOStm << (INT16) rGrad.GetOfsY();
+ rOStm << (INT16) rGrad.GetStartIntensity();
+ rOStm << (INT16) rGrad.GetEndIntensity();
+ nCount++;
+ }
+ break;
+
+ case( META_GRADIENTEX_ACTION ):
+ {
+ const MetaGradientExAction* pA = (MetaGradientExAction*) pAction;
+ ULONG nOldPos, nNewPos;
+
+ // write RefPoint comment
+ rOStm << (INT16) GDI_GRADIENTEX_COMMENT;
+
+ // we'll write the ActionSize later
+ nOldPos = rOStm.Tell();
+ rOStm.SeekRel( 4 );
+
+ // write data
+ rOStm << pA->GetPolyPolygon() << pA->GetGradient();
+ rOStm << (INT32) 0; // number of actions that follow this comment
+
+ // calculate and write ActionSize of comment
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) ( nNewPos - nOldPos );
+ rOStm.Seek( nNewPos );
+
+ nCount++;
+ }
+ break;
+
+ case( META_WALLPAPER_ACTION ):
+ {
+ MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction;
+ const Color& rColor = pAct->GetWallpaper().GetColor();
+
+ ImplWritePushAction( rOStm );
+ ImplWriteLineColor( rOStm, rColor, 1 );
+ ImplWriteFillColor( rOStm, rColor, 1 );
+
+ rOStm << (INT16) GDI_RECT_ACTION;
+ rOStm << (INT32) 28;
+ ImplWriteRect( rOStm, pAct->GetRect() );
+ rOStm << (INT32) 0;
+ rOStm << (INT32) 0;
+
+ ImplWritePopAction( rOStm );
+ nCount += 5;
+ }
+ break;
+
+ case( META_CLIPREGION_ACTION ):
+ {
+ MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction;
+ const Region& rRegion = pAct->GetRegion();
+ Rectangle aClipRect;
+
+ rOStm << (INT16) GDI_CLIPREGION_ACTION;
+ rOStm << (INT32) 24;
+
+ if( pAct->IsClipping() )
+ {
+ aClipRect = rRegion.GetBoundRect();
+ rOStm << (INT16) 1;
+ }
+ else
+ rOStm << (INT16) 0;
+
+ rOStm << (INT16) 0;
+ ImplWriteRect( rOStm, aClipRect );
+
+ if( pAct->IsClipping() )
+ ImplWriteRect( rOStm, aClipRect );
+
+ nCount++;
+ }
+ break;
+
+ case( META_ISECTRECTCLIPREGION_ACTION ):
+ {
+ MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction;
+
+ rOStm << (INT16) GDI_ISECTCLIPREGION_ACTION;
+ rOStm << (INT32) 20;
+ rOStm << pAct->GetRect();
+ nCount++;
+ }
+ break;
+
+ case( META_MOVECLIPREGION_ACTION ):
+ {
+ MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction;
+
+ rOStm << (INT16) GDI_MOVECLIPREGION_ACTION;
+ rOStm << (INT32) 12;
+ rOStm << (INT32) pAct->GetHorzMove();
+ rOStm << (INT32) pAct->GetVertMove();
+ nCount++;
+ }
+ break;
+
+ case( META_LINECOLOR_ACTION ):
+ {
+ MetaLineColorAction* pAct = (MetaLineColorAction*) pAction;
+ ImplWriteLineColor( rOStm, rLineCol = pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
+ nCount++;
+ }
+ break;
+
+ case( META_FILLCOLOR_ACTION ):
+ {
+ MetaFillColorAction* pAct = (MetaFillColorAction*) pAction;
+ ImplWriteFillColor( rOStm, pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
+ nCount++;
+ }
+ break;
+
+ case( META_FONT_ACTION ):
+ {
+ rSaveVDev.SetFont( ( (MetaFontAction*) pAction )->GetFont() );
+ ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
+ nCount++;
+ }
+ break;
+
+ case( META_TEXTCOLOR_ACTION ):
+ {
+ Font aSaveFont( rSaveVDev.GetFont() );
+
+ aSaveFont.SetColor( ( (MetaTextColorAction*) pAction )->GetColor() );
+ rSaveVDev.SetFont( aSaveFont );
+ ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
+ nCount++;
+ }
+ break;
+
+ case( META_TEXTFILLCOLOR_ACTION ):
+ {
+ MetaTextFillColorAction* pAct = (MetaTextFillColorAction*) pAction;
+ Font aSaveFont( rSaveVDev.GetFont() );
+
+ if( pAct->IsSetting() )
+ aSaveFont.SetFillColor( pAct->GetColor() );
+ else
+ aSaveFont.SetFillColor( Color( COL_TRANSPARENT ) );
+
+ rSaveVDev.SetFont( aSaveFont );
+ ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
+ nCount++;
+ }
+ break;
+
+ case( META_TEXTALIGN_ACTION ):
+ {
+ Font aSaveFont( rSaveVDev.GetFont() );
+
+ aSaveFont.SetAlign( ( (MetaTextAlignAction*) pAction )->GetTextAlign() );
+ rSaveVDev.SetFont( aSaveFont );
+ ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
+ nCount++;
+ }
+ break;
+
+ case( META_MAPMODE_ACTION ):
+ {
+ MetaMapModeAction* pAct = (MetaMapModeAction*) pAction;
+
+ rOStm << (INT16) GDI_MAPMODE_ACTION;
+ rOStm << (INT32) 30;
+ ImplWriteMapMode( rOStm, pAct->GetMapMode() );
+ nCount++;
+ }
+ break;
+
+ case( META_PUSH_ACTION ):
+ {
+ ImplWritePushAction( rOStm );
+ rLineColStack.Push( new Color( rLineCol ) );
+ rSaveVDev.Push();
+ nCount++;
+ }
+ break;
+
+ case( META_POP_ACTION ):
+ {
+ Color* pCol = (Color*) rLineColStack.Pop();
+
+ if( pCol )
+ {
+ rLineCol = *pCol;
+ delete pCol;
+ }
+
+ ImplWritePopAction( rOStm );
+ rSaveVDev.Pop();
+ nCount++;
+ }
+ break;
+
+ case( META_RASTEROP_ACTION ):
+ {
+ MetaRasterOpAction* pAct = (MetaRasterOpAction*) pAction;
+
+ if( ( pAct->GetRasterOp() != ROP_0 ) && ( pAct->GetRasterOp() != ROP_1 ) )
+ {
+ INT16 nRasterOp;
+
+ // Falls vorher ROP_0/1 gesetzt war, alten
+ // Zustand durch Pop erst wieder herstellen
+ if( rRop_0_1 )
+ {
+ ImplWritePopAction( rOStm );
+ rSaveVDev.Pop();
+ rRop_0_1 = FALSE;
+ nCount++;
+ }
+
+ switch( pAct->GetRasterOp() )
+ {
+ case( ROP_OVERPAINT ) : nRasterOp = 0; break;
+ case( ROP_XOR ) : nRasterOp = 4; break;
+ case( ROP_INVERT ): nRasterOp = 1; break;
+ default: nRasterOp = 0; break;
+ }
+
+ ImplWriteRasterOpAction( rOStm, nRasterOp );
+ nCount++;
+ }
+ else
+ {
+ ImplWritePushAction( rOStm );
+ rSaveVDev.Push();
+
+ if( pAct->GetRasterOp() == ROP_0 )
+ {
+ ImplWriteLineColor( rOStm, COL_BLACK, 1 );
+ ImplWriteFillColor( rOStm, COL_BLACK, 1 );
+ }
+ else
+ {
+ ImplWriteLineColor( rOStm, COL_WHITE, 1 );
+ ImplWriteFillColor( rOStm, COL_WHITE, 1 );
+ }
+
+ ImplWriteRasterOpAction( rOStm, 0 );
+ rRop_0_1 = TRUE;
+ nCount += 4;
+ }
+ }
+ break;
+
+ case( META_TRANSPARENT_ACTION ):
+ {
+ const PolyPolygon& rPolyPoly = ( (MetaTransparentAction*) pAction )->GetPolyPolygon();
+ const INT16 nTrans = ( (MetaTransparentAction*) pAction )->GetTransparence();
+ const INT16 nBrushStyle = ( nTrans < 38 ) ? 8 : ( nTrans < 63 ) ? 9 : 10;
+ ULONG nOldPos, nNewPos;
+
+ // write transparence comment
+ rOStm << (INT16) GDI_TRANSPARENT_COMMENT;
+
+ // we'll write the ActionSize later
+ nOldPos = rOStm.Tell();
+ rOStm.SeekRel( 4 );
+
+ // write comment data
+ rOStm << rPolyPoly;
+ rOStm << nTrans;
+ rOStm << (INT32) 15; // number of actions that follow this comment
+
+ // calculate and write ActionSize of comment
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) ( nNewPos - nOldPos );
+ rOStm.Seek( nNewPos );
+
+ {
+ // write actions for transparence
+ ImplWritePushAction( rOStm );
+ {
+ ImplWriteRasterOpAction( rOStm, 4 );
+ ImplWritePolyPolyAction( rOStm, rPolyPoly );
+
+ ImplWritePushAction( rOStm );
+ {
+ ImplWriteRasterOpAction( rOStm, 2 );
+ ImplWriteFillColor( rOStm, COL_BLACK, nBrushStyle );
+ ImplWritePolyPolyAction( rOStm, rPolyPoly );
+ }
+ ImplWritePopAction( rOStm );
+
+ ImplWriteRasterOpAction( rOStm, 4 );
+ ImplWritePolyPolyAction( rOStm, rPolyPoly );
+ }
+ ImplWritePopAction( rOStm );
+
+ ImplWritePushAction( rOStm );
+ {
+ ImplWriteFillColor( rOStm, Color(), 0 );
+ ImplWritePolyPolyAction( rOStm, rPolyPoly );
+ }
+ ImplWritePopAction( rOStm );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ nCount += 15;
+#endif
+ }
+
+ nCount++;
+ }
+ break;
+
+ case( META_FLOATTRANSPARENT_ACTION ):
+ {
+ const MetaFloatTransparentAction* pA = (MetaFloatTransparentAction*) pAction;
+ const GDIMetaFile& rTransMtf = pA->GetGDIMetaFile();
+ const Point& rPos = pA->GetPoint();
+ const Size& rSize = pA->GetSize();
+ const Gradient& rGradient = pA->GetGradient();
+ ULONG nOldPos, nNewPos;
+
+ // write RefPoint comment
+ rOStm << (INT16) GDI_FLOATTRANSPARENT_COMMENT;
+
+ // we'll write the ActionSize later
+ nOldPos = rOStm.Tell();
+ rOStm.SeekRel( 4 );
+
+ // write comment data
+ rOStm << rTransMtf << rPos << rSize << rGradient;
+
+ // calculate and write ActionSize of comment
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) ( nNewPos - nOldPos + 4 );
+ rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
+
+ {
+ // write actions for float transparence
+ ULONG nAddCount;
+ GDIMetaFile aMtf( rTransMtf );
+ const Size aSrcSize( rTransMtf.GetPrefSize() );
+ Point aSrcPt( rTransMtf.GetPrefMapMode().GetOrigin() );
+ const double fScaleX = aSrcSize.Width() ? (double) rSize.Width() / aSrcSize.Width() : 1.0;
+ const double fScaleY = aSrcSize.Height() ? (double) rSize.Height() / aSrcSize.Height() : 1.0;
+ long nMoveX, nMoveY;
+
+ if( fScaleX != 1.0 || fScaleY != 1.0 )
+ {
+ aMtf.Scale( fScaleX, fScaleY );
+ aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
+ }
+
+ nMoveX = rPos.X() - aSrcPt.X(), nMoveY = rPos.Y() - aSrcPt.Y();
+
+ if( nMoveX || nMoveY )
+ aMtf.Move( nMoveX, nMoveY );
+
+ nAddCount = ImplWriteActions( rOStm, aMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) nAddCount;
+ rOStm.Seek( nNewPos );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ nCount += nAddCount;
+#endif
+ }
+
+ nCount++;
+ }
+ break;
+
+ case( META_HATCH_ACTION ):
+ {
+ const MetaHatchAction* pA = (MetaHatchAction*) pAction;
+ const PolyPolygon& rPolyPoly = pA->GetPolyPolygon();
+ const Hatch& rHatch = pA->GetHatch();
+ ULONG nOldPos, nNewPos, nAddCount;
+
+ // write hatch comment
+ rOStm << (INT16) GDI_HATCH_COMMENT;
+
+ // we'll write the ActionSize later
+ nOldPos = rOStm.Tell();
+ rOStm.SeekRel( 4 );
+
+ // write comment data
+ rOStm << rPolyPoly;
+ rOStm << rHatch;
+
+ // calculate and write ActionSize of comment
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) ( nNewPos - nOldPos + 4 );
+ rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
+
+ {
+ // write actions for hatch
+ VirtualDevice aVDev;
+ GDIMetaFile aTmpMtf;
+
+ aVDev.AddHatchActions( rPolyPoly, rHatch, aTmpMtf );
+ nAddCount = ImplWriteActions( rOStm, aTmpMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) nAddCount;
+ rOStm.Seek( nNewPos );
+
+#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
+ nCount += nAddCount;
+#endif
+ }
+
+ nCount++;
+ }
+ break;
+
+ case( META_REFPOINT_ACTION ):
+ {
+ const MetaRefPointAction* pA = (MetaRefPointAction*) pAction;
+ const Point& rRefPoint = pA->GetRefPoint();
+ const BOOL bSet = pA->IsSetting();
+ ULONG nOldPos, nNewPos;
+
+ // write RefPoint comment
+ rOStm << (INT16) GDI_REFPOINT_COMMENT;
+
+ // we'll write the ActionSize later
+ nOldPos = rOStm.Tell();
+ rOStm.SeekRel( 4 );
+
+ // write data
+ rOStm << rRefPoint << bSet;
+ rOStm << (INT32) 0; // number of actions that follow this comment
+
+ // calculate and write ActionSize of comment
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) ( nNewPos - nOldPos );
+ rOStm.Seek( nNewPos );
+
+ nCount++;
+ }
+ break;
+
+ case( META_TEXTLINECOLOR_ACTION ):
+ {
+ const MetaTextLineColorAction* pA = (MetaTextLineColorAction*) pAction;
+ const Color& rColor = pA->GetColor();
+ const BOOL bSet = pA->IsSetting();
+ ULONG nOldPos, nNewPos;
+
+ // write RefPoint comment
+ rOStm << (INT16) GDI_TEXTLINECOLOR_COMMENT;
+
+ // we'll write the ActionSize later
+ nOldPos = rOStm.Tell();
+ rOStm.SeekRel( 4 );
+
+ // write data
+ rOStm << rColor << bSet;
+ rOStm << (INT32) 0; // number of actions that follow this comment
+
+ // calculate and write ActionSize of comment
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) ( nNewPos - nOldPos );
+ rOStm.Seek( nNewPos );
+
+ nCount++;
+ }
+ break;
+
+ case( META_TEXTLINE_ACTION ):
+ {
+ const MetaTextLineAction* pA = (MetaTextLineAction*) pAction;
+ const Point& rStartPt = pA->GetStartPoint();
+ const long nWidth = pA->GetWidth();
+ const FontStrikeout eStrikeout = pA->GetStrikeout();
+ const FontUnderline eUnderline = pA->GetUnderline();
+ ULONG nOldPos, nNewPos;
+
+ // write RefPoint comment
+ rOStm << (INT16) GDI_TEXTLINE_COMMENT;
+
+ // we'll write the ActionSize later
+ nOldPos = rOStm.Tell();
+ rOStm.SeekRel( 4 );
+
+ // write data
+ rOStm << rStartPt << nWidth << (ULONG) eStrikeout << (ULONG) eUnderline;
+ rOStm << (INT32) 0; // number of actions that follow this comment
+
+ // calculate and write ActionSize of comment
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) ( nNewPos - nOldPos );
+ rOStm.Seek( nNewPos );
+
+ nCount++;
+ }
+ break;
+
+ case( META_EPS_ACTION ):
+ break;
+
+ case( META_COMMENT_ACTION ):
+ {
+ const MetaCommentAction* pA = (MetaCommentAction*) pAction;
+ const ULONG nDataSize = pA->GetDataSize();
+ ULONG nOldPos, nNewPos;
+
+ // write RefPoint comment
+ rOStm << (INT16) GDI_COMMENT_COMMENT;
+
+ // we'll write the ActionSize later
+ nOldPos = rOStm.Tell();
+ rOStm.SeekRel( 4 );
+
+ // write data
+ rOStm << pA->GetComment() << pA->GetValue() << nDataSize;
+
+ if( nDataSize )
+ rOStm.Write( pA->GetData(), nDataSize );
+
+ rOStm << (INT32) 0; // number of actions that follow this comment
+
+ // calculate and write ActionSize of comment
+ nNewPos = rOStm.Tell();
+ rOStm.Seek( nOldPos );
+ rOStm << (INT32) ( nNewPos - nOldPos );
+ rOStm.Seek( nNewPos );
+
+ nCount++;
+ }
+ break;
+
+#ifdef DBG_UTIL
+ default:
+ {
+ ByteString aStr( "Missing implementation for Action#: " );
+ aStr += ByteString::CreateFromInt32( pAction->GetType() );
+ aStr += '!';
+ DBG_ERROR( aStr.GetBuffer() );
+ }
+ break;
+#endif
+
+/*
+ case( META_TEXTRECT_ACTION ):
+ {
+ MetaTextRectAction* pAct = (MetaTextRectAction*) pAction;
+
+ rOStm << ;
+ rOStm << ;
+
+ nCount++;
+ }
+ break;
+*/
+
+/*
+ case( META_MASK_ACTION ):
+ {
+ MetaMaskAction* pAct = (MetaMaskAction*) pAction;
+
+ rOStm << ;
+ rOStm << ;
+
+ nCount++;
+ }
+ break;
+*/
+
+/*
+ case( META_MASKSCALE_ACTION ):
+ {
+ MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction;
+
+ rOStm << ;
+ rOStm << ;
+
+ nCount++;
+ }
+ break;
+*/
+
+/*
+ case( META_MASKSCALEPART_ACTION ):
+ {
+ MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
+
+ rOStm << ;
+ rOStm << ;
+
+ nCount++;
+ }
+ break;
+*/
+
+/*
+ case( META_ISECTREGIONCLIPREGION_ACTION ):
+ {
+ MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction;
+
+ rOStm << ;
+ rOStm << ;
+
+ nCount++;
+ }
+ break;
+*/
+ }
+ }
+
+ return nCount;
+}
diff --git a/vcl/source/gdi/font.cxx b/vcl/source/gdi/font.cxx
new file mode 100644
index 000000000000..657d42a21546
--- /dev/null
+++ b/vcl/source/gdi/font.cxx
@@ -0,0 +1,625 @@
+/*************************************************************************
+ *
+ * $RCSfile: font.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_FONT_CXX
+
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_FONT_HXX
+#include <font.hxx>
+#endif
+
+// =======================================================================
+
+DBG_NAME( Font );
+
+// -----------------------------------------------------------------------
+
+Impl_Font::Impl_Font() :
+ maColor( COL_BLACK ),
+ maFillColor( COL_TRANSPARENT )
+{
+ mnRefCount = 1;
+ meCharSet = RTL_TEXTENCODING_DONTKNOW;
+ meLanguage = LANGUAGE_DONTKNOW;
+ meFamily = FAMILY_DONTKNOW;
+ mePitch = PITCH_DONTKNOW;
+ meAlign = ALIGN_TOP;
+ meWeight = WEIGHT_DONTKNOW;
+ meWidthType = WIDTH_DONTKNOW;
+ meUnderline = UNDERLINE_NONE;
+ meStrikeout = STRIKEOUT_NONE;
+ meItalic = ITALIC_NONE;
+ mbWordLine = FALSE;
+ mbOutline = FALSE;
+ mbShadow = FALSE;
+ mbKerning = FALSE;
+ mbTransparent = TRUE;
+ mnOrientation = 0;
+}
+
+// -----------------------------------------------------------------------
+
+Impl_Font::Impl_Font( const Impl_Font& rImplFont ) :
+ maColor( rImplFont.maColor ),
+ maFillColor( rImplFont.maFillColor ),
+ maName( rImplFont.maName ),
+ maStyleName( rImplFont.maStyleName ),
+ maSize( rImplFont.maSize )
+{
+ mnRefCount = 1;
+ meCharSet = rImplFont.meCharSet;
+ meLanguage = rImplFont.meLanguage;
+ meFamily = rImplFont.meFamily;
+ mePitch = rImplFont.mePitch;
+ meAlign = rImplFont.meAlign;
+ meWeight = rImplFont.meWeight;
+ meWidthType = rImplFont.meWidthType;
+ meUnderline = rImplFont.meUnderline;
+ meStrikeout = rImplFont.meStrikeout;
+ meItalic = rImplFont.meItalic;
+ mbWordLine = rImplFont.mbWordLine;
+ mbOutline = rImplFont.mbOutline;
+ mbShadow = rImplFont.mbShadow;
+ mbKerning = rImplFont.mbKerning;
+ mbTransparent = rImplFont.mbTransparent;
+ mnOrientation = rImplFont.mnOrientation;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::MakeUnique()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpImplFont->mnRefCount != 1 )
+ {
+ if ( mpImplFont->mnRefCount )
+ mpImplFont->mnRefCount--;
+ mpImplFont = new Impl_Font( *mpImplFont );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Font::Font()
+{
+ DBG_CTOR( Font, NULL );
+
+#ifdef WIN
+ static Impl_Font _near aStaticImplFont;
+#else
+ static Impl_Font aStaticImplFont;
+#endif
+ // RefCount == 0 fuer statische Objekte
+ aStaticImplFont.mnRefCount = 0;
+ mpImplFont = &aStaticImplFont;
+}
+
+// -----------------------------------------------------------------------
+
+Font::Font( const Font& rFont )
+{
+ DBG_CTOR( Font, NULL );
+ DBG_CHKOBJ( &rFont, Font, NULL );
+ DBG_ASSERT( rFont.mpImplFont->mnRefCount < 0xFFFE, "Font: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpImplFont = rFont.mpImplFont;
+ // RefCount == 0 fuer statische Objekte
+ if ( mpImplFont->mnRefCount )
+ mpImplFont->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+Font::Font( const XubString& rName, const Size& rSize )
+{
+ DBG_CTOR( Font, NULL );
+
+ mpImplFont = new Impl_Font;
+ mpImplFont->maName = rName;
+ mpImplFont->maSize = rSize;
+}
+
+// -----------------------------------------------------------------------
+
+Font::Font( const XubString& rName, const XubString& rStyleName, const Size& rSize )
+{
+ DBG_CTOR( Font, NULL );
+
+ mpImplFont = new Impl_Font;
+ mpImplFont->maName = rName;
+ mpImplFont->maStyleName = rStyleName;
+ mpImplFont->maSize = rSize;
+}
+
+// -----------------------------------------------------------------------
+
+Font::Font( FontFamily eFamily, const Size& rSize )
+{
+ DBG_CTOR( Font, NULL );
+
+ mpImplFont = new Impl_Font;
+ mpImplFont->meFamily = eFamily;
+ mpImplFont->maSize = rSize;
+}
+
+// -----------------------------------------------------------------------
+
+Font::~Font()
+{
+ DBG_DTOR( Font, NULL );
+
+ // Wenn es keine statischen ImplDaten sind, dann loeschen, wenn es
+ // die letzte Referenz ist, sonst Referenzcounter decrementieren
+ if ( mpImplFont->mnRefCount )
+ {
+ if ( mpImplFont->mnRefCount == 1 )
+ delete mpImplFont;
+ else
+ mpImplFont->mnRefCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetColor( const Color& rColor )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->maColor = rColor;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetFillColor( const Color& rColor )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->maFillColor = rColor;
+ if ( rColor.GetTransparency() )
+ mpImplFont->mbTransparent = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetTransparent( BOOL bTransparent )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->mbTransparent = bTransparent;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetAlign( FontAlign eAlign )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->meAlign = eAlign;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetName( const XubString& rName )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->maName = rName;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetStyleName( const XubString& rStyleName )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->maStyleName = rStyleName;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetSize( const Size& rSize )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->maSize = rSize;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetFamily( FontFamily eFamily )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->meFamily = eFamily;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetCharSet( CharSet eCharSet )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->meCharSet = eCharSet;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetLanguage( LanguageType eLanguage )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->meLanguage = eLanguage;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetPitch( FontPitch ePitch )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->mePitch = ePitch;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetOrientation( short nOrientation )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->mnOrientation = nOrientation;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetKerning( BOOL bKerning )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->mbKerning = bKerning;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetWeight( FontWeight eWeight )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->meWeight = eWeight;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetWidthType( FontWidth eWidth )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->meWidthType = eWidth;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetItalic( FontItalic eItalic )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->meItalic = eItalic;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetOutline( BOOL bOutline )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->mbOutline = bOutline;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetShadow( BOOL bShadow )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->mbShadow = bShadow;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetUnderline( FontUnderline eUnderline )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->meUnderline = eUnderline;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetStrikeout( FontStrikeout eStrikeout )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->meStrikeout = eStrikeout;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::SetWordLineMode( BOOL bWordLine )
+{
+ DBG_CHKTHIS( Font, NULL );
+
+ MakeUnique();
+ mpImplFont->mbWordLine = bWordLine;
+}
+
+// -----------------------------------------------------------------------
+
+Font& Font::operator=( const Font& rFont )
+{
+ DBG_CHKTHIS( Font, NULL );
+ DBG_CHKOBJ( &rFont, Font, NULL );
+ DBG_ASSERT( rFont.mpImplFont->mnRefCount < 0xFFFE, "Font: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ // RefCount == 0 fuer statische Objekte
+ if ( rFont.mpImplFont->mnRefCount )
+ rFont.mpImplFont->mnRefCount++;
+
+ // Wenn es keine statischen ImplDaten sind, dann loeschen, wenn es
+ // die letzte Referenz ist, sonst Referenzcounter decrementieren
+ if ( mpImplFont->mnRefCount )
+ {
+ if ( mpImplFont->mnRefCount == 1 )
+ delete mpImplFont;
+ else
+ mpImplFont->mnRefCount--;
+ }
+
+ mpImplFont = rFont.mpImplFont;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Font::operator==( const Font& rFont ) const
+{
+ DBG_CHKTHIS( Font, NULL );
+ DBG_CHKOBJ( &rFont, Font, NULL );
+
+ if ( mpImplFont == rFont.mpImplFont )
+ return TRUE;
+
+ if ( (mpImplFont->meWeight == rFont.mpImplFont->meWeight ) &&
+ (mpImplFont->meItalic == rFont.mpImplFont->meItalic ) &&
+ (mpImplFont->meUnderline == rFont.mpImplFont->meUnderline ) &&
+ (mpImplFont->mbWordLine == rFont.mpImplFont->mbWordLine ) &&
+ (mpImplFont->meFamily == rFont.mpImplFont->meFamily ) &&
+ (mpImplFont->mePitch == rFont.mpImplFont->mePitch ) &&
+ (mpImplFont->meCharSet == rFont.mpImplFont->meCharSet ) &&
+ (mpImplFont->meAlign == rFont.mpImplFont->meAlign ) &&
+ (mpImplFont->maName == rFont.mpImplFont->maName ) &&
+ (mpImplFont->maStyleName == rFont.mpImplFont->maStyleName ) &&
+ (mpImplFont->maColor == rFont.mpImplFont->maColor ) &&
+ (mpImplFont->maFillColor == rFont.mpImplFont->maFillColor ) &&
+ (mpImplFont->maSize == rFont.mpImplFont->maSize ) &&
+ (mpImplFont->mnOrientation == rFont.mpImplFont->mnOrientation ) &&
+ (mpImplFont->meStrikeout == rFont.mpImplFont->meStrikeout ) &&
+ (mpImplFont->mbOutline == rFont.mpImplFont->mbOutline ) &&
+ (mpImplFont->mbShadow == rFont.mpImplFont->mbShadow ) &&
+ (mpImplFont->mbKerning == rFont.mpImplFont->mbKerning ) &&
+ (mpImplFont->mbTransparent == rFont.mpImplFont->mbTransparent ) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Font::Merge( const Font& rFont )
+{
+ if ( rFont.GetName().Len() )
+ {
+ SetName( rFont.GetName() );
+ SetStyleName( rFont.GetStyleName() );
+ SetFamily( rFont.GetFamily() );
+ SetCharSet( GetCharSet() );
+ SetLanguage( rFont.GetLanguage() );
+ SetPitch( rFont.GetPitch() );
+ }
+
+ if ( rFont.GetSize().Height() )
+ SetSize( rFont.GetSize() );
+ if ( rFont.GetWeight() != WEIGHT_DONTKNOW )
+ SetWeight( rFont.GetWeight() );
+ if ( rFont.GetWidthType() != WIDTH_DONTKNOW )
+ SetWidthType( rFont.GetWidthType() );
+ if ( rFont.GetItalic() != ITALIC_DONTKNOW )
+ SetItalic( rFont.GetItalic() );
+ if ( rFont.GetUnderline() != UNDERLINE_DONTKNOW )
+ {
+ SetUnderline( rFont.GetUnderline() );
+ SetWordLineMode( rFont.IsWordLineMode() );
+ }
+ if ( rFont.GetStrikeout() != STRIKEOUT_DONTKNOW )
+ {
+ SetStrikeout( rFont.GetStrikeout() );
+ SetWordLineMode( rFont.IsWordLineMode() );
+ }
+
+ // Defaults?
+ SetOrientation( rFont.GetOrientation() );
+ SetKerning( rFont.IsKerning() );
+ SetOutline( rFont.IsOutline() );
+ SetShadow( rFont.IsShadow() );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, Impl_Font& rImpl_Font )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ UINT16 nTmp16;
+ BOOL bTmp;
+
+ rIStm.ReadByteString( rImpl_Font.maName, rIStm.GetStreamCharSet() );
+ rIStm.ReadByteString( rImpl_Font.maStyleName, rIStm.GetStreamCharSet() );
+ rIStm >> rImpl_Font.maSize;
+// rIStm >> rImpl_Font.maColor; // removed since SUPD396
+// rIStm >> rImpl_Font.maFillColor; // removed since SUPD396
+
+ rIStm >> nTmp16; rImpl_Font.meCharSet = (rtl_TextEncoding) nTmp16;
+ rIStm >> nTmp16; rImpl_Font.meFamily = (FontFamily) nTmp16;
+ rIStm >> nTmp16; rImpl_Font.mePitch = (FontPitch) nTmp16;
+// rIStm >> nTmp16; rImpl_Font.meAlign = (FontAlign) nTmp16; // removed since SUPD396
+ rIStm >> nTmp16; rImpl_Font.meWeight = (FontWeight) nTmp16;
+ rIStm >> nTmp16; rImpl_Font.meUnderline = (FontUnderline) nTmp16;
+ rIStm >> nTmp16; rImpl_Font.meStrikeout = (FontStrikeout) nTmp16;
+ rIStm >> nTmp16; rImpl_Font.meItalic = (FontItalic) nTmp16;
+ rIStm >> nTmp16; rImpl_Font.meLanguage = (LanguageType) nTmp16; // new since SUPD 396
+ rIStm >> nTmp16; rImpl_Font.meWidthType = (FontWidth) nTmp16; // new since SUPD 396
+
+ rIStm >> rImpl_Font.mnOrientation;
+
+ rIStm >> bTmp; rImpl_Font.mbWordLine = bTmp;
+ rIStm >> bTmp; rImpl_Font.mbOutline = bTmp;
+ rIStm >> bTmp; rImpl_Font.mbShadow = bTmp;
+ rIStm >> bTmp; rImpl_Font.mbKerning = bTmp;
+// rIStm >> bTmp; rImpl_Font.mbTransparent = bTmp; // removed since SUPD396
+
+ return rIStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const Impl_Font& rImpl_Font )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 1 );
+ rOStm.WriteByteString( rImpl_Font.maName, rOStm.GetStreamCharSet() );
+ rOStm.WriteByteString( rImpl_Font.maStyleName, rOStm.GetStreamCharSet() );
+ rOStm << rImpl_Font.maSize;
+// rOStm << rImpl_Font.maColor; // removed since SUPD396
+// rOStm << rImpl_Font.maFillColor; // removed since SUPD396
+
+ rOStm << (UINT16) GetStoreCharSet( rImpl_Font.meCharSet, rOStm.GetVersion() );
+ rOStm << (UINT16) rImpl_Font.meFamily;
+ rOStm << (UINT16) rImpl_Font.mePitch;
+// rOStm << (UINT16) rImpl_Font.meAlign; // removed since SUPD396
+ rOStm << (UINT16) rImpl_Font.meWeight;
+ rOStm << (UINT16) rImpl_Font.meUnderline;
+ rOStm << (UINT16) rImpl_Font.meStrikeout;
+ rOStm << (UINT16) rImpl_Font.meItalic;
+ rOStm << (UINT16) rImpl_Font.meLanguage; // new since SUPD 396
+ rOStm << (UINT16) rImpl_Font.meWidthType; // new since SUPD 396
+
+ rOStm << rImpl_Font.mnOrientation;
+
+ rOStm << (BOOL) rImpl_Font.mbWordLine;
+ rOStm << (BOOL) rImpl_Font.mbOutline;
+ rOStm << (BOOL) rImpl_Font.mbShadow;
+ rOStm << (BOOL) rImpl_Font.mbKerning;
+// rOStm << (BOOL) rImpl_Font.mbTransparent; // removed since SUPD396
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, Font& rFont )
+{
+ rFont.MakeUnique();
+ return( rIStm >> *rFont.mpImplFont );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const Font& rFont )
+{
+ return( rOStm << *rFont.mpImplFont );
+}
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
new file mode 100644
index 000000000000..852dbfcb87a3
--- /dev/null
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -0,0 +1,1724 @@
+/*************************************************************************
+ *
+ * $RCSfile: gdimtf.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_GDIMTF_CXX
+
+#ifndef _RTL_CRC_H_
+#include <rtl/crc.h>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_CVTSVM_HXX
+#include <cvtsvm.hxx>
+#endif
+#include <gdimtf.hxx>
+
+// -----------
+// - Defines -
+// -----------
+
+#define GAMMA( _def_cVal, _def_InvGamma ) ((BYTE)MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0L,255L))
+
+// --------------------------
+// - Color exchange structs -
+// --------------------------
+
+struct ImplColAdjustParam
+{
+ BYTE* pMapR;
+ BYTE* pMapG;
+ BYTE* pMapB;
+};
+
+struct ImplBmpAdjustParam
+{
+ short nLuminancePercent;
+ short nContrastPercent;
+ short nChannelRPercent;
+ short nChannelGPercent;
+ short nChannelBPercent;
+ double fGamma;
+ BOOL bInvert;
+};
+
+// -----------------------------------------------------------------------------
+
+struct ImplColConvertParam
+{
+ MtfConversion eConversion;
+};
+
+struct ImplBmpConvertParam
+{
+ BmpConversion eConversion;
+};
+
+// -----------------------------------------------------------------------------
+
+struct ImplColMonoParam
+{
+ Color aColor;
+};
+
+struct ImplBmpMonoParam
+{
+ Color aColor;
+};
+
+// -----------------------------------------------------------------------------
+
+struct ImplColReplaceParam
+{
+ ULONG* pMinR;
+ ULONG* pMaxR;
+ ULONG* pMinG;
+ ULONG* pMaxG;
+ ULONG* pMinB;
+ ULONG* pMaxB;
+ const Color* pDstCols;
+ ULONG nCount;
+};
+
+struct ImplBmpReplaceParam
+{
+ const Color* pSrcCols;
+ const Color* pDstCols;
+ ULONG nCount;
+ const ULONG* pTols;
+};
+
+
+// ---------
+// - Label -
+// ---------
+
+struct ImpLabel
+{
+ String aLabelName;
+ ULONG nActionPos;
+
+ ImpLabel( const String& rLabelName, ULONG _nActionPos ) :
+ aLabelName( rLabelName ),
+ nActionPos( _nActionPos ) {}
+};
+
+// -------------
+// - LabelList -
+// -------------
+
+class ImpLabelList : private List
+{
+public:
+
+ ImpLabelList() : List( 8, 4, 4 ) {}
+ ImpLabelList( const ImpLabelList& rList );
+ ~ImpLabelList();
+
+ void ImplInsert( ImpLabel* p ) { Insert( p, LIST_APPEND ); }
+ ImpLabel* ImplRemove( ULONG nPos ) { return (ImpLabel*) Remove( nPos ); }
+ void ImplReplace( ImpLabel* p ) { Replace( (void*)p ); }
+ ImpLabel* ImplFirst() { return (ImpLabel*) First(); }
+ ImpLabel* ImplNext() { return (ImpLabel*) Next(); }
+ ImpLabel* ImplGetLabel( ULONG nPos ) const { return (ImpLabel*) GetObject( nPos ); }
+ ULONG ImplGetLabelPos( const String& rLabelName );
+ ULONG ImplCount() const { return Count(); }
+};
+
+// ------------------------------------------------------------------------
+
+ImpLabelList::ImpLabelList( const ImpLabelList& rList ) :
+ List( rList )
+{
+ for( ImpLabel* pLabel = ImplFirst(); pLabel; pLabel = ImplNext() )
+ ImplReplace( new ImpLabel( *pLabel ) );
+}
+
+// ------------------------------------------------------------------------
+
+ImpLabelList::~ImpLabelList()
+{
+ for( ImpLabel* pLabel = ImplFirst(); pLabel; pLabel = ImplNext() )
+ delete pLabel;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ImpLabelList::ImplGetLabelPos( const String& rLabelName )
+{
+ ULONG nLabelPos = METAFILE_LABEL_NOTFOUND;
+
+ for( ImpLabel* pLabel = ImplFirst(); pLabel; pLabel = ImplNext() )
+ {
+ if ( rLabelName == pLabel->aLabelName )
+ {
+ nLabelPos = GetCurPos();
+ break;
+ }
+ }
+
+ return nLabelPos;
+}
+
+// ---------------
+// - GDIMetaFile -
+// ---------------
+
+GDIMetaFile::GDIMetaFile() :
+ List ( 0x3EFF, 64, 64 ),
+ aPrefSize ( 1, 1 ),
+ pPrev ( NULL ),
+ pNext ( NULL ),
+ pOutDev ( NULL ),
+ pLabelList ( NULL ),
+ bPause ( FALSE ),
+ bRecord ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------------
+
+GDIMetaFile::GDIMetaFile( const GDIMetaFile& rMtf ) :
+ List ( rMtf ),
+ aPrefMapMode ( rMtf.aPrefMapMode ),
+ aPrefSize ( rMtf.aPrefSize ),
+ aHookHdlLink ( rMtf.aHookHdlLink ),
+ pPrev ( rMtf.pPrev ),
+ pNext ( rMtf.pNext ),
+ pOutDev ( NULL ),
+ bPause ( FALSE ),
+ bRecord ( FALSE )
+{
+ // RefCount der MetaActions erhoehen
+ for( void* pAct = First(); pAct; pAct = Next() )
+ ( (MetaAction*) pAct )->Duplicate();
+
+ if( rMtf.pLabelList )
+ pLabelList = new ImpLabelList( *rMtf.pLabelList );
+ else
+ pLabelList = NULL;
+
+ if( rMtf.bRecord )
+ {
+ Record( rMtf.pOutDev );
+
+ if ( rMtf.bPause )
+ Pause( TRUE );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+GDIMetaFile::~GDIMetaFile()
+{
+ Clear();
+}
+
+// ------------------------------------------------------------------------
+
+GDIMetaFile& GDIMetaFile::operator=( const GDIMetaFile& rMtf )
+{
+ if( this != &rMtf )
+ {
+ Clear();
+
+ List::operator=( rMtf );
+
+ // RefCount der MetaActions erhoehen
+ for( void* pAct = First(); pAct; pAct = Next() )
+ ( (MetaAction*) pAct )->Duplicate();
+
+ if( rMtf.pLabelList )
+ pLabelList = new ImpLabelList( *rMtf.pLabelList );
+ else
+ pLabelList = NULL;
+
+ aPrefMapMode = rMtf.aPrefMapMode;
+ aPrefSize = rMtf.aPrefSize;
+ aHookHdlLink = rMtf.aHookHdlLink;
+ pPrev = rMtf.pPrev;
+ pNext = rMtf.pNext;
+ pOutDev = NULL;
+ bPause = FALSE;
+ bRecord = FALSE;
+
+ if( rMtf.bRecord )
+ {
+ Record( rMtf.pOutDev );
+
+ if( rMtf.bPause )
+ Pause( TRUE );
+ }
+ }
+
+ return *this;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GDIMetaFile::operator==( const GDIMetaFile& rMtf ) const
+{
+ const ULONG nCount = Count();
+ BOOL bRet = FALSE;
+
+ if( this == &rMtf )
+ bRet = TRUE;
+ else if( rMtf.GetActionCount() == nCount &&
+ rMtf.GetPrefSize() == aPrefSize &&
+ rMtf.GetPrefMapMode() == aPrefMapMode )
+ {
+ bRet = TRUE;
+
+ for( ULONG n = 0UL; n < nCount; n++ )
+ {
+ if( GetObject( n ) != rMtf.GetObject( n ) )
+ {
+ bRet = FALSE;
+ break;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Clear()
+{
+ if( bRecord )
+ Stop();
+
+ for( void* pAct = First(); pAct; pAct = Next() )
+ ( (MetaAction*) pAct )->Delete();
+
+ List::Clear();
+
+ delete pLabelList;
+ pLabelList = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Linker( OutputDevice* pOut, BOOL bLink )
+{
+ if( bLink )
+ {
+ pNext = NULL;
+ pPrev = pOut->GetConnectMetaFile();
+ pOut->SetConnectMetaFile( this );
+
+ if( pPrev )
+ pPrev->pNext = this;
+ }
+ else
+ {
+ if( pNext )
+ {
+ pNext->pPrev = pPrev;
+
+ if( pPrev )
+ pPrev->pNext = pNext;
+ }
+ else
+ {
+ if( pPrev )
+ pPrev->pNext = NULL;
+
+ pOut->SetConnectMetaFile( pPrev );
+ }
+
+ pPrev = NULL;
+ pNext = NULL;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+long GDIMetaFile::Hook()
+{
+ return aHookHdlLink.Call( this );
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Record( OutputDevice* pOut )
+{
+ if( bRecord )
+ Stop();
+
+ Last();
+ pOutDev = pOut;
+ bRecord = TRUE;
+ Linker( pOut, TRUE );
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Play( GDIMetaFile& rMtf, ULONG nPos )
+{
+ if ( !bRecord && !rMtf.bRecord )
+ {
+ MetaAction* pAction = GetCurAction();
+ const ULONG nCount = Count();
+
+ if( nPos > nCount )
+ nPos = nCount;
+
+ for( ULONG nCurPos = GetCurPos(); nCurPos < nPos; nCurPos++ )
+ {
+ if( !Hook() )
+ {
+ pAction->Duplicate();
+ rMtf.AddAction( pAction );
+ }
+
+ pAction = (MetaAction*) Next();
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Play( OutputDevice* pOut, ULONG nPos )
+{
+ if( !bRecord )
+ {
+ MetaAction* pAction = GetCurAction();
+ const ULONG nCount = Count();
+ ULONG i = 0, nSyncCount = ( pOut->GetOutDevType() == OUTDEV_WINDOW ) ? 0x000000ff : 0xffffffff;
+
+ if( nPos > nCount )
+ nPos = nCount;
+
+ for( ULONG nCurPos = GetCurPos(); nCurPos < nPos; nCurPos++ )
+ {
+ if( !Hook() )
+ {
+ pAction->Execute( pOut );
+
+ // flush output from time to time
+ if( i++ > nSyncCount )
+ ( (Window*) pOut )->Flush(), i = 0;
+ }
+
+ pAction = (MetaAction*) Next();
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos,
+ const Size& rSize, ULONG nPos )
+{
+ Region aDrawClipRegion;
+ MapMode aDrawMap( GetPrefMapMode() );
+ Size aDestSize( pOut->LogicToPixel( rSize ) );
+
+ if( aDestSize.Width() && aDestSize.Height() )
+ {
+ Size aTmpPrefSize( pOut->LogicToPixel( GetPrefSize(), aDrawMap ) );
+ GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
+
+ if( !aTmpPrefSize.Width() )
+ aTmpPrefSize.Width() = aDestSize.Width();
+
+ if( !aTmpPrefSize.Height() )
+ aTmpPrefSize.Height() = aDestSize.Height();
+
+ Fraction aScaleX( aDestSize.Width(), aTmpPrefSize.Width() );
+ Fraction aScaleY( aDestSize.Height(), aTmpPrefSize.Height() );
+
+ aScaleX *= aDrawMap.GetScaleX(); aDrawMap.SetScaleX( aScaleX );
+ aScaleY *= aDrawMap.GetScaleY(); aDrawMap.SetScaleY( aScaleY );
+
+ aDrawMap.SetOrigin( pOut->PixelToLogic( pOut->LogicToPixel( rPos ), aDrawMap ) );
+
+ pOut->Push();
+
+ if ( pMtf && pMtf->IsRecord() && ( pOut->GetOutDevType() != OUTDEV_PRINTER ) )
+ pOut->SetRelativeMapMode( aDrawMap );
+ else
+ pOut->SetMapMode( aDrawMap );
+
+ Play( pOut, nPos );
+
+ pOut->Pop();
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Pause( BOOL _bPause )
+{
+ if( bRecord )
+ {
+ if( _bPause )
+ {
+ if( !bPause )
+ Linker( pOutDev, FALSE );
+ }
+ else
+ {
+ if( bPause )
+ Linker( pOutDev, TRUE );
+ }
+
+ bPause = _bPause;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Stop()
+{
+ if( bRecord )
+ {
+ bRecord = FALSE;
+
+ if( !bPause )
+ Linker( pOutDev, FALSE );
+ else
+ bPause = FALSE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::WindStart()
+{
+ if( !bRecord )
+ First();
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::WindEnd()
+{
+ if( !bRecord )
+ Last();
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Wind( ULONG nActionPos )
+{
+ if( !bRecord )
+ Seek( nActionPos );
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::WindPrev()
+{
+ if( !bRecord )
+ Prev();
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::WindNext()
+{
+ if( !bRecord )
+ Next();
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::AddAction( MetaAction* pAction )
+{
+ Insert( pAction, LIST_APPEND );
+
+ if( pPrev )
+ {
+ pAction->Duplicate();
+ pPrev->AddAction( pAction );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::AddAction( MetaAction* pAction, ULONG nPos )
+{
+ Insert( pAction, nPos );
+
+ if( pPrev )
+ {
+ pAction->Duplicate();
+ pPrev->AddAction( pAction, nPos );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* GDIMetaFile::CopyAction( ULONG nPos ) const
+{
+ return ( (MetaAction*) GetObject( nPos ) )->Clone();
+}
+
+// ------------------------------------------------------------------------
+
+ULONG GDIMetaFile::GetActionPos( const String& rLabel )
+{
+ ImpLabel* pLabel = NULL;
+
+ if( pLabelList )
+ pLabel = pLabelList->ImplGetLabel( pLabelList->ImplGetLabelPos( rLabel ) );
+ else
+ pLabel = NULL;
+
+ return( pLabel ? pLabel->nActionPos : METAFILE_LABEL_NOTFOUND );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GDIMetaFile::InsertLabel( const String& rLabel, ULONG nActionPos )
+{
+ BOOL bRet = FALSE;
+
+ if( !pLabelList )
+ pLabelList = new ImpLabelList;
+
+ if( pLabelList->ImplGetLabelPos( rLabel ) == METAFILE_LABEL_NOTFOUND )
+ {
+ pLabelList->ImplInsert( new ImpLabel( rLabel, nActionPos ) );
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::RemoveLabel( const String& rLabel )
+{
+ if( pLabelList )
+ {
+ const ULONG nLabelPos = pLabelList->ImplGetLabelPos( rLabel );
+
+ if( nLabelPos != METAFILE_LABEL_NOTFOUND )
+ delete pLabelList->ImplRemove( nLabelPos );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::RenameLabel( const String& rLabel, const String& rNewLabel )
+{
+ if( pLabelList )
+ {
+ const ULONG nLabelPos = pLabelList->ImplGetLabelPos( rLabel );
+
+ if ( nLabelPos != METAFILE_LABEL_NOTFOUND )
+ pLabelList->ImplGetLabel( nLabelPos )->aLabelName = rNewLabel;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ULONG GDIMetaFile::GetLabelCount() const
+{
+ return( pLabelList ? pLabelList->ImplCount() : 0UL );
+}
+
+// ------------------------------------------------------------------------
+
+String GDIMetaFile::GetLabel( ULONG nLabel )
+{
+ String aString;
+
+ if( pLabelList )
+ {
+ const ImpLabel* pLabel = pLabelList->ImplGetLabel( nLabel );
+
+ if( pLabel )
+ aString = pLabel->aLabelName;
+ }
+
+ return aString;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GDIMetaFile::SaveStatus()
+{
+ if ( bRecord )
+ {
+ if ( bPause )
+ Linker( pOutDev, TRUE );
+
+ AddAction( new MetaLineColorAction( pOutDev->GetLineColor(),
+ pOutDev->IsLineColor() ) );
+ AddAction( new MetaFillColorAction( pOutDev->GetFillColor(),
+ pOutDev->IsFillColor() ) );
+ AddAction( new MetaFontAction( pOutDev->GetFont() ) );
+ AddAction( new MetaTextColorAction( pOutDev->GetTextColor() ) );
+ AddAction( new MetaTextFillColorAction( pOutDev->GetTextFillColor(),
+ pOutDev->IsTextFillColor() ) );
+ AddAction( new MetaTextLineColorAction( pOutDev->GetTextLineColor(),
+ pOutDev->IsTextLineColor() ) );
+ AddAction( new MetaTextAlignAction( pOutDev->GetTextAlign() ) );
+ AddAction( new MetaRasterOpAction( pOutDev->GetRasterOp() ) );
+ AddAction( new MetaMapModeAction( pOutDev->GetMapMode() ) );
+ AddAction( new MetaClipRegionAction( pOutDev->GetClipRegion(),
+ pOutDev->IsClipRegion() ) );
+
+ if ( bPause )
+ Linker( pOutDev, FALSE );
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Move( long nX, long nY )
+{
+ for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() )
+ {
+ MetaAction* pModAct;
+
+ if( pAct->GetRefCount() > 1 )
+ {
+ Replace( pModAct = pAct->Clone(), pAct );
+ pAct->Delete();
+ }
+ else
+ pModAct = pAct;
+
+ pModAct->Move( nX, nY );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Scale( double fScaleX, double fScaleY )
+{
+ for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() )
+ {
+ MetaAction* pModAct;
+
+ if( pAct->GetRefCount() > 1 )
+ {
+ Replace( pModAct = pAct->Clone(), pAct );
+ pAct->Delete();
+ }
+ else
+ pModAct = pAct;
+
+ pModAct->Scale( fScaleX, fScaleY );
+ }
+
+ aPrefSize.Width() = FRound( aPrefSize.Width() * fScaleX );
+ aPrefSize.Height() = FRound( aPrefSize.Height() * fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Scale( const Fraction& rScaleX, const Fraction& rScaleY )
+{
+ Scale( (double) rScaleX, (double) rScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+Color GDIMetaFile::ImplColAdjustFnc( const Color& rColor, const void* pColParam )
+{
+ return Color( rColor.GetTransparency(),
+ ( (const ImplColAdjustParam*) pColParam )->pMapR[ rColor.GetRed() ],
+ ( (const ImplColAdjustParam*) pColParam )->pMapG[ rColor.GetGreen() ],
+ ( (const ImplColAdjustParam*) pColParam )->pMapB[ rColor.GetBlue() ] );
+
+}
+
+// ------------------------------------------------------------------------
+
+BitmapEx GDIMetaFile::ImplBmpAdjustFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
+{
+ const ImplBmpAdjustParam* p = (const ImplBmpAdjustParam*) pBmpParam;
+ BitmapEx aRet( rBmpEx );
+
+ aRet.Adjust( p->nLuminancePercent, p->nContrastPercent,
+ p->nChannelRPercent, p->nChannelGPercent, p->nChannelBPercent,
+ p->fGamma, p->bInvert );
+
+ return aRet;
+}
+
+// ------------------------------------------------------------------------
+
+Color GDIMetaFile::ImplColConvertFnc( const Color& rColor, const void* pColParam )
+{
+ BYTE cLum = rColor.GetLuminance();
+
+ if( MTF_CONVERSION_1BIT_THRESHOLD == ( (const ImplColConvertParam*) pColParam )->eConversion )
+ cLum = ( cLum < 128 ) ? 0 : 255;
+
+ return Color( rColor.GetTransparency(), cLum, cLum, cLum );
+}
+
+// ------------------------------------------------------------------------
+
+BitmapEx GDIMetaFile::ImplBmpConvertFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
+{
+ BitmapEx aRet( rBmpEx );
+
+ aRet.Convert( ( (const ImplBmpConvertParam*) pBmpParam )->eConversion );
+
+ return aRet;
+}
+
+// ------------------------------------------------------------------------
+
+Color GDIMetaFile::ImplColMonoFnc( const Color& rColor, const void* pColParam )
+{
+ return( ( (const ImplColMonoParam*) pColParam )->aColor );
+}
+
+// ------------------------------------------------------------------------
+
+BitmapEx GDIMetaFile::ImplBmpMonoFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
+{
+ BitmapPalette aPal( 3 );
+
+ aPal[ 0 ] = Color( COL_BLACK );
+ aPal[ 1 ] = Color( COL_WHITE );
+ aPal[ 2 ] = ( (const ImplBmpMonoParam*) pBmpParam )->aColor;
+
+ Bitmap aBmp( rBmpEx.GetSizePixel(), 4, &aPal );
+ aBmp.Erase( ( (const ImplBmpMonoParam*) pBmpParam )->aColor );
+
+ if( rBmpEx.IsAlpha() )
+ return BitmapEx( aBmp, rBmpEx.GetAlpha() );
+ else if( rBmpEx.IsTransparent() )
+ return BitmapEx( aBmp, rBmpEx.GetMask() );
+ else
+ return aBmp;
+}
+
+// ------------------------------------------------------------------------
+
+Color GDIMetaFile::ImplColReplaceFnc( const Color& rColor, const void* pColParam )
+{
+ const ULONG nR = rColor.GetRed(), nG = rColor.GetGreen(), nB = rColor.GetBlue();
+
+ for( ULONG i = 0; i < ( (const ImplColReplaceParam*) pColParam )->nCount; i++ )
+ {
+ if( ( ( (const ImplColReplaceParam*) pColParam )->pMinR[ i ] <= nR ) &&
+ ( ( (const ImplColReplaceParam*) pColParam )->pMaxR[ i ] >= nR ) &&
+ ( ( (const ImplColReplaceParam*) pColParam )->pMinG[ i ] <= nG ) &&
+ ( ( (const ImplColReplaceParam*) pColParam )->pMaxG[ i ] >= nG ) &&
+ ( ( (const ImplColReplaceParam*) pColParam )->pMinB[ i ] <= nB ) &&
+ ( ( (const ImplColReplaceParam*) pColParam )->pMaxB[ i ] >= nB ) )
+ {
+ return( ( (const ImplColReplaceParam*) pColParam )->pDstCols[ i ] );
+ }
+ }
+
+ return rColor;
+}
+
+// ------------------------------------------------------------------------
+
+BitmapEx GDIMetaFile::ImplBmpReplaceFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
+{
+ const ImplBmpReplaceParam* p = (const ImplBmpReplaceParam*) pBmpParam;
+ BitmapEx aRet( rBmpEx );
+
+ aRet.Replace( p->pSrcCols, p->pDstCols, p->nCount, p->pTols );
+
+ return aRet;
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol, const void* pColParam,
+ BmpExchangeFnc pFncBmp, const void* pBmpParam )
+{
+ GDIMetaFile aMtf;
+
+ aMtf.aPrefSize = aPrefSize;
+ aMtf.aPrefMapMode = aPrefMapMode;
+
+ for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() )
+ {
+ const USHORT nType = pAction->GetType();
+
+ switch( nType )
+ {
+ case( META_PIXEL_ACTION ):
+ {
+ MetaPixelAction* pAct = (MetaPixelAction*) pAction;
+ aMtf.Insert( new MetaPixelAction( pAct->GetPoint(), pFncCol( pAct->GetColor(), pColParam ) ), LIST_APPEND );
+ }
+ break;
+
+ case( META_LINECOLOR_ACTION ):
+ {
+ MetaLineColorAction* pAct = (MetaLineColorAction*) pAction;
+
+ if( !pAct->IsSetting() )
+ pAct->Duplicate();
+ else
+ pAct = new MetaLineColorAction( pFncCol( pAct->GetColor(), pColParam ), TRUE );
+
+ aMtf.Insert( pAct, LIST_APPEND );
+ }
+ break;
+
+ case( META_FILLCOLOR_ACTION ):
+ {
+ MetaFillColorAction* pAct = (MetaFillColorAction*) pAction;
+
+ if( !pAct->IsSetting() )
+ pAct->Duplicate();
+ else
+ pAct = new MetaFillColorAction( pFncCol( pAct->GetColor(), pColParam ), TRUE );
+
+ aMtf.Insert( pAct, LIST_APPEND );
+ }
+ break;
+
+ case( META_TEXTCOLOR_ACTION ):
+ {
+ MetaTextColorAction* pAct = (MetaTextColorAction*) pAction;
+ aMtf.Insert( new MetaTextColorAction( pFncCol( pAct->GetColor(), pColParam ) ), LIST_APPEND );
+ }
+ break;
+
+ case( META_TEXTFILLCOLOR_ACTION ):
+ {
+ MetaTextFillColorAction* pAct = (MetaTextFillColorAction*) pAction;
+
+ if( !pAct->IsSetting() )
+ pAct->Duplicate();
+ else
+ pAct = new MetaTextFillColorAction( pFncCol( pAct->GetColor(), pColParam ), TRUE );
+
+ aMtf.Insert( pAct, LIST_APPEND );
+ }
+ break;
+
+ case( META_TEXTLINECOLOR_ACTION ):
+ {
+ MetaTextLineColorAction* pAct = (MetaTextLineColorAction*) pAction;
+
+ if( !pAct->IsSetting() )
+ pAct->Duplicate();
+ else
+ pAct = new MetaTextLineColorAction( pFncCol( pAct->GetColor(), pColParam ), TRUE );
+
+ aMtf.Insert( pAct, LIST_APPEND );
+ }
+ break;
+
+ case( META_FONT_ACTION ):
+ {
+ MetaFontAction* pAct = (MetaFontAction*) pAction;
+ Font aFont( pAct->GetFont() );
+
+ aFont.SetColor( pFncCol( aFont.GetColor(), pColParam ) );
+ aFont.SetFillColor( pFncCol( aFont.GetFillColor(), pColParam ) );
+ aMtf.Insert( new MetaFontAction( aFont ), LIST_APPEND );
+ }
+ break;
+
+ case( META_WALLPAPER_ACTION ):
+ {
+ MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction;
+ Wallpaper aWall( pAct->GetWallpaper() );
+ const Rectangle& rRect = pAct->GetRect();
+
+ aWall.SetColor( pFncCol( aWall.GetColor(), pColParam ) );
+
+ if( aWall.IsBitmap() )
+ aWall.SetBitmap( pFncBmp( aWall.GetBitmap(), pBmpParam ) );
+
+ if( aWall.IsGradient() )
+ {
+ Gradient aGradient( aWall.GetGradient() );
+
+ aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) );
+ aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) );
+ aWall.SetGradient( aGradient );
+ }
+
+ aMtf.Insert( new MetaWallpaperAction( rRect, aWall ), LIST_APPEND );
+ }
+ break;
+
+ case( META_BMP_ACTION ):
+ case( META_BMPEX_ACTION ):
+ case( META_MASK_ACTION ):
+ {
+ DBG_ERROR( "Don't use bitmap actions of this type in metafiles!" );
+ }
+ break;
+
+ case( META_BMPSCALE_ACTION ):
+ {
+ MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
+ aMtf.Insert( new MetaBmpScaleAction( pAct->GetPoint(), pAct->GetSize(),
+ pFncBmp( pAct->GetBitmap(), pBmpParam ).GetBitmap() ),
+ LIST_APPEND );
+ }
+ break;
+
+ case( META_BMPSCALEPART_ACTION ):
+ {
+ MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
+ aMtf.Insert( new MetaBmpScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
+ pAct->GetSrcPoint(), pAct->GetSrcSize(),
+ pFncBmp( pAct->GetBitmap(), pBmpParam ).GetBitmap() ),
+ LIST_APPEND );
+ }
+ break;
+
+ case( META_BMPEXSCALE_ACTION ):
+ {
+ MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction;
+ aMtf.Insert( new MetaBmpExScaleAction( pAct->GetPoint(), pAct->GetSize(),
+ pFncBmp( pAct->GetBitmapEx(), pBmpParam ) ),
+ LIST_APPEND );
+ }
+ break;
+
+ case( META_BMPEXSCALEPART_ACTION ):
+ {
+ MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction;
+ aMtf.Insert( new MetaBmpExScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
+ pAct->GetSrcPoint(), pAct->GetSrcSize(),
+ pFncBmp( pAct->GetBitmapEx(), pBmpParam ) ),
+ LIST_APPEND );
+ }
+ break;
+
+ case( META_MASKSCALE_ACTION ):
+ {
+ MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction;
+ aMtf.Insert( new MetaMaskScaleAction( pAct->GetPoint(), pAct->GetSize(),
+ pAct->GetBitmap(),
+ pFncCol( pAct->GetColor(), pColParam ) ),
+ LIST_APPEND );
+ }
+ break;
+
+ case( META_MASKSCALEPART_ACTION ):
+ {
+ MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
+ aMtf.Insert( new MetaMaskScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
+ pAct->GetSrcPoint(), pAct->GetSrcSize(),
+ pAct->GetBitmap(),
+ pFncCol( pAct->GetColor(), pColParam ) ),
+ LIST_APPEND );
+ }
+ break;
+
+ case( META_GRADIENT_ACTION ):
+ {
+ MetaGradientAction* pAct = (MetaGradientAction*) pAction;
+ Gradient aGradient( pAct->GetGradient() );
+
+ aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) );
+ aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) );
+ aMtf.Insert( new MetaGradientAction( pAct->GetRect(), aGradient ), LIST_APPEND );
+ }
+ break;
+
+ case( META_GRADIENTEX_ACTION ):
+ {
+ MetaGradientExAction* pAct = (MetaGradientExAction*) pAction;
+ Gradient aGradient( pAct->GetGradient() );
+
+ aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) );
+ aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) );
+ aMtf.Insert( new MetaGradientExAction( pAct->GetPolyPolygon(), aGradient ), LIST_APPEND );
+ }
+ break;
+
+ case( META_HATCH_ACTION ):
+ {
+ MetaHatchAction* pAct = (MetaHatchAction*) pAction;
+ Hatch aHatch( pAct->GetHatch() );
+
+ aHatch.SetColor( pFncCol( aHatch.GetColor(), pColParam ) );
+ aMtf.Insert( new MetaHatchAction( pAct->GetPolyPolygon(), aHatch ), LIST_APPEND );
+ }
+ break;
+
+ case( META_FLOATTRANSPARENT_ACTION ):
+ {
+ MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction;
+ GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() );
+
+ aTransMtf.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam );
+ aMtf.Insert( new MetaFloatTransparentAction( aTransMtf,
+ pAct->GetPoint(), pAct->GetSize(),
+ pAct->GetGradient() ),
+ LIST_APPEND );
+ }
+ break;
+
+ case( META_EPS_ACTION ):
+ {
+ MetaEPSAction* pAct = (MetaEPSAction*) pAction;
+ GDIMetaFile aSubst( pAct->GetSubstitute() );
+
+ aSubst.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam );
+ aMtf.Insert( new MetaEPSAction( pAct->GetPoint(), pAct->GetSize(),
+ pAct->GetLink(), aSubst ),
+ LIST_APPEND );
+ }
+ break;
+
+ default:
+ {
+ pAction->Duplicate();
+ aMtf.Insert( pAction, LIST_APPEND );
+ }
+ break;
+ }
+ }
+
+ *this = aMtf;
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent,
+ short nChannelRPercent, short nChannelGPercent,
+ short nChannelBPercent, double fGamma, BOOL bInvert )
+{
+ // nothing to do? => return quickly
+ if( nLuminancePercent || nContrastPercent ||
+ nChannelRPercent || nChannelGPercent || nChannelBPercent ||
+ ( fGamma != 1.0 ) || bInvert )
+ {
+ double fM, fROff, fGOff, fBOff, fOff;
+ ImplColAdjustParam aColParam;
+ ImplBmpAdjustParam aBmpParam;
+
+ aColParam.pMapR = new BYTE[ 256 ];
+ aColParam.pMapG = new BYTE[ 256 ];
+ aColParam.pMapB = new BYTE[ 256 ];
+
+ // calculate slope
+ if( nContrastPercent >= 0 )
+ fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0L, 100L ) );
+ else
+ fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0;
+
+ // total offset = luminance offset + contrast offset
+ fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0;
+
+ // channel offset = channel offset + total offset
+ fROff = nChannelRPercent * 2.55 + fOff;
+ fGOff = nChannelGPercent * 2.55 + fOff;
+ fBOff = nChannelBPercent * 2.55 + fOff;
+
+ // calculate gamma value
+ fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma );
+ const BOOL bGamma = ( fGamma != 1.0 );
+
+ // create mapping table
+ for( long nX = 0L; nX < 256L; nX++ )
+ {
+ aColParam.pMapR[ nX ] = (BYTE) MinMax( FRound( nX * fM + fROff ), 0L, 255L );
+ aColParam.pMapG[ nX ] = (BYTE) MinMax( FRound( nX * fM + fGOff ), 0L, 255L );
+ aColParam.pMapB[ nX ] = (BYTE) MinMax( FRound( nX * fM + fBOff ), 0L, 255L );
+
+ if( bGamma )
+ {
+ aColParam.pMapR[ nX ] = GAMMA( aColParam.pMapR[ nX ], fGamma );
+ aColParam.pMapG[ nX ] = GAMMA( aColParam.pMapG[ nX ], fGamma );
+ aColParam.pMapB[ nX ] = GAMMA( aColParam.pMapB[ nX ], fGamma );
+ }
+
+ if( bInvert )
+ {
+ aColParam.pMapR[ nX ] = ~aColParam.pMapR[ nX ];
+ aColParam.pMapG[ nX ] = ~aColParam.pMapG[ nX ];
+ aColParam.pMapB[ nX ] = ~aColParam.pMapB[ nX ];
+ }
+ }
+
+ aBmpParam.nLuminancePercent = nLuminancePercent;
+ aBmpParam.nContrastPercent = nContrastPercent;
+ aBmpParam.nChannelRPercent = nChannelRPercent;
+ aBmpParam.nChannelGPercent = nChannelGPercent;
+ aBmpParam.nChannelBPercent = nChannelBPercent;
+ aBmpParam.fGamma = fGamma;
+ aBmpParam.bInvert = bInvert;
+
+ // do color adjustment
+ ImplExchangeColors( ImplColAdjustFnc, &aColParam, ImplBmpAdjustFnc, &aBmpParam );
+
+ delete[] aColParam.pMapR;
+ delete[] aColParam.pMapG;
+ delete[] aColParam.pMapB;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::Convert( MtfConversion eConversion )
+{
+ // nothing to do? => return quickly
+ if( eConversion != MTF_CONVERSION_NONE )
+ {
+ ImplColConvertParam aColParam;
+ ImplBmpConvertParam aBmpParam;
+
+ aColParam.eConversion = eConversion;
+ aBmpParam.eConversion = ( MTF_CONVERSION_1BIT_THRESHOLD == eConversion ) ? BMP_CONVERSION_1BIT_THRESHOLD : BMP_CONVERSION_8BIT_GREYS;
+
+ ImplExchangeColors( ImplColConvertFnc, &aColParam, ImplBmpConvertFnc, &aBmpParam );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::ReplaceColors( const Color& rSearchColor, const Color& rReplaceColor, ULONG nTol )
+{
+ ReplaceColors( &rSearchColor, &rReplaceColor, 1, &nTol );
+}
+
+// ------------------------------------------------------------------------
+
+void GDIMetaFile::ReplaceColors( const Color* pSearchColors, const Color* pReplaceColors, ULONG nColorCount, ULONG* pTols )
+{
+ ImplColReplaceParam aColParam;
+ ImplBmpReplaceParam aBmpParam;
+
+ aColParam.pMinR = new ULONG[ nColorCount ];
+ aColParam.pMaxR = new ULONG[ nColorCount ];
+ aColParam.pMinG = new ULONG[ nColorCount ];
+ aColParam.pMaxG = new ULONG[ nColorCount ];
+ aColParam.pMinB = new ULONG[ nColorCount ];
+ aColParam.pMaxB = new ULONG[ nColorCount ];
+
+ for( ULONG i = 0; i < nColorCount; i++ )
+ {
+ const long nTol = pTols ? ( pTols[ i ] * 255 ) / 100 : 0;
+ long nVal;
+
+ nVal = pSearchColors[ i ].GetRed();
+ aColParam.pMinR[ i ] = (ULONG) Max( nVal - nTol, 0L );
+ aColParam.pMaxR[ i ] = (ULONG) Min( nVal + nTol, 255L );
+
+ nVal = pSearchColors[ i ].GetGreen();
+ aColParam.pMinG[ i ] = (ULONG) Max( nVal - nTol, 0L );
+ aColParam.pMaxG[ i ] = (ULONG) Min( nVal + nTol, 255L );
+
+ nVal = pSearchColors[ i ].GetBlue();
+ aColParam.pMinB[ i ] = (ULONG) Max( nVal - nTol, 0L );
+ aColParam.pMaxB[ i ] = (ULONG) Min( nVal + nTol, 255L );
+ }
+
+ aColParam.pDstCols = pReplaceColors;
+ aColParam.nCount = nColorCount;
+
+ aBmpParam.pSrcCols = pSearchColors;
+ aBmpParam.pDstCols = pReplaceColors;
+ aBmpParam.nCount = nColorCount;
+ aBmpParam.pTols = pTols;
+
+ ImplExchangeColors( ImplColReplaceFnc, &aColParam, ImplBmpReplaceFnc, &aBmpParam );
+
+ delete[] aColParam.pMinR;
+ delete[] aColParam.pMaxR;
+ delete[] aColParam.pMinG;
+ delete[] aColParam.pMaxG;
+ delete[] aColParam.pMinB;
+ delete[] aColParam.pMaxB;
+};
+
+// ------------------------------------------------------------------------
+
+GDIMetaFile GDIMetaFile::GetMonochromeMtf( const Color& rColor ) const
+{
+ GDIMetaFile aRet( *this );
+
+ ImplColMonoParam aColParam;
+ ImplBmpMonoParam aBmpParam;
+
+ aColParam.aColor = rColor;
+ aBmpParam.aColor = rColor;
+
+ aRet.ImplExchangeColors( ImplColMonoFnc, &aColParam, ImplBmpMonoFnc, &aBmpParam );
+
+ return aRet;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG GDIMetaFile::GetChecksum() const
+{
+ GDIMetaFile aMtf;
+ SvMemoryStream aMemStm( 65535, 65535 );
+ ImplMetaWriteData aWriteData; aWriteData.meActualCharSet = aMemStm.GetStreamCharSet();
+ SVBT16 aBT16;
+ SVBT32 aBT32;
+ ULONG nCrc = 0;
+
+ for( ULONG i = 0, nCount = GetActionCount(); i < nCount; i++ )
+ {
+ MetaAction* pAction = GetAction( i );
+
+ switch( pAction->GetType() )
+ {
+ case( META_BMP_ACTION ):
+ {
+ MetaBmpAction* pAct = (MetaBmpAction*) pAction;
+
+ ShortToSVBT16( pAct->GetType(), aBT16 );
+ nCrc = rtl_crc32( nCrc, aBT16, 2 );
+
+ LongToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+ break;
+
+ case( META_BMPSCALE_ACTION ):
+ {
+ MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
+
+ ShortToSVBT16( pAct->GetType(), aBT16 );
+ nCrc = rtl_crc32( nCrc, aBT16, 2 );
+
+ LongToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSize().Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSize().Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+ break;
+
+ case( META_BMPSCALEPART_ACTION ):
+ {
+ MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
+
+ ShortToSVBT16( pAct->GetType(), aBT16 );
+ nCrc = rtl_crc32( nCrc, aBT16, 2 );
+
+ LongToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestSize().Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestSize().Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcSize().Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcSize().Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+ break;
+
+ case( META_BMPEX_ACTION ):
+ {
+ MetaBmpExAction* pAct = (MetaBmpExAction*) pAction;
+
+ ShortToSVBT16( pAct->GetType(), aBT16 );
+ nCrc = rtl_crc32( nCrc, aBT16, 2 );
+
+ LongToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+ break;
+
+ case( META_BMPEXSCALE_ACTION ):
+ {
+ MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction;
+
+ ShortToSVBT16( pAct->GetType(), aBT16 );
+ nCrc = rtl_crc32( nCrc, aBT16, 2 );
+
+ LongToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSize().Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSize().Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+ break;
+
+ case( META_BMPEXSCALEPART_ACTION ):
+ {
+ MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction;
+
+ ShortToSVBT16( pAct->GetType(), aBT16 );
+ nCrc = rtl_crc32( nCrc, aBT16, 2 );
+
+ LongToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestSize().Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestSize().Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcSize().Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcSize().Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+ break;
+
+ case( META_MASK_ACTION ):
+ {
+ MetaMaskAction* pAct = (MetaMaskAction*) pAction;
+
+ ShortToSVBT16( pAct->GetType(), aBT16 );
+ nCrc = rtl_crc32( nCrc, aBT16, 2 );
+
+ LongToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetColor().GetColor(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+ break;
+
+ case( META_MASKSCALE_ACTION ):
+ {
+ MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction;
+
+ ShortToSVBT16( pAct->GetType(), aBT16 );
+ nCrc = rtl_crc32( nCrc, aBT16, 2 );
+
+ LongToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetColor().GetColor(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSize().Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSize().Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+ break;
+
+ case( META_MASKSCALEPART_ACTION ):
+ {
+ MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
+
+ ShortToSVBT16( pAct->GetType(), aBT16 );
+ nCrc = rtl_crc32( nCrc, aBT16, 2 );
+
+ LongToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetColor().GetColor(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestSize().Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetDestSize().Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcPoint().X(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcPoint().Y(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcSize().Width(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+
+ LongToSVBT32( pAct->GetSrcSize().Height(), aBT32 );
+ nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ }
+ break;
+
+ default:
+ {
+ pAction->Write( aMemStm, &aWriteData );
+ nCrc = rtl_crc32( nCrc, aMemStm.GetData(), aMemStm.Tell() );
+ aMemStm.Seek( 0 );
+ }
+ break;
+ }
+ }
+
+ return nCrc;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, GDIMetaFile& rGDIMetaFile )
+{
+ if( !rIStm.GetError() )
+ {
+ char aId[ 7 ];
+ ULONG nStmPos = rIStm.Tell();
+ USHORT nOldFormat = rIStm.GetNumberFormatInt();
+ BOOL bError = FALSE;
+
+ rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ rIStm.Read( aId, 6 );
+ aId[ 6 ] = 0;
+
+ if ( !strcmp( aId, "VCLMTF" ) )
+ {
+ // new format
+ VersionCompat* pCompat;
+ MetaAction* pAction;
+ UINT32 nStmCompressMode;
+ UINT32 nCount;
+
+ pCompat = new VersionCompat( rIStm, STREAM_READ );
+
+ rIStm >> nStmCompressMode;
+ rIStm >> rGDIMetaFile.aPrefMapMode;
+ rIStm >> rGDIMetaFile.aPrefSize;
+ rIStm >> nCount;
+
+ delete pCompat;
+
+ ImplMetaReadData aReadData;
+ aReadData.meActualCharSet = rIStm.GetStreamCharSet();
+
+ for( UINT32 nAction = 0UL; ( nAction < nCount ) && !rIStm.IsEof(); nAction++ )
+ {
+ pAction = MetaAction::ReadMetaAction( rIStm, &aReadData );
+
+ if( pAction )
+ rGDIMetaFile.AddAction( pAction );
+ }
+ }
+ else
+ {
+ // to avoid possible compiler optimizations => new/delete
+ rIStm.Seek( nStmPos );
+ delete( new SVMConverter( rIStm, rGDIMetaFile, CONVERT_FROM_SVM1 ) );
+ }
+
+ // check for errors
+ if( rIStm.GetError() )
+ {
+ rGDIMetaFile.Clear();
+ rIStm.Seek( nStmPos );
+ }
+
+ rIStm.SetNumberFormatInt( nOldFormat );
+ }
+
+ return rIStm;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile )
+{
+ if( !rOStm.GetError() )
+ {
+ if( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 )
+ ((GDIMetaFile&) rGDIMetaFile ).Write( rOStm );
+ else
+ delete( new SVMConverter( rOStm, (GDIMetaFile&) rGDIMetaFile, CONVERT_TO_SVM1 ) );
+ }
+
+ return rOStm;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& GDIMetaFile::Read( SvStream& rIStm )
+{
+ Clear();
+ rIStm >> *this;
+
+ return rIStm;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& GDIMetaFile::Write( SvStream& rOStm )
+{
+ VersionCompat* pCompat;
+ const UINT32 nStmCompressMode = rOStm.GetCompressMode();
+ USHORT nOldFormat = rOStm.GetNumberFormatInt();
+
+ rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rOStm.Write( "VCLMTF", 6 );
+
+ pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 );
+
+ rOStm << nStmCompressMode;
+ rOStm << aPrefMapMode;
+ rOStm << aPrefSize;
+ rOStm << (UINT32) GetActionCount();
+
+ delete pCompat;
+
+ ImplMetaWriteData aWriteData;
+ aWriteData.meActualCharSet = rOStm.GetStreamCharSet();
+
+ MetaAction* pAct = (MetaAction*)First();
+ while ( pAct )
+ {
+ pAct->Write( rOStm, &aWriteData );
+ pAct = (MetaAction*)Next();
+ }
+
+ rOStm.SetNumberFormatInt( nOldFormat );
+
+ return rOStm;
+}
diff --git a/vcl/source/gdi/gfxlink.cxx b/vcl/source/gdi/gfxlink.cxx
new file mode 100644
index 000000000000..3a175017708e
--- /dev/null
+++ b/vcl/source/gdi/gfxlink.cxx
@@ -0,0 +1,450 @@
+/*************************************************************************
+ *
+ * $RCSfile: gfxlink.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <tools/vcompat.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+#include <tools/tempfile.hxx>
+#include <ucbhelper/content.hxx>
+#include "graph.hxx"
+#include "gfxlink.hxx"
+#include "cvtgrf.hxx"
+
+// -----------
+// - GfxLink -
+// -----------
+
+GfxLink::GfxLink() :
+ meType ( GFX_LINK_TYPE_NONE ),
+ mnBufSize ( 0 ),
+ mpBuf ( NULL ),
+ mpSwap ( NULL ),
+ mnUserId ( 0UL )
+{
+}
+
+// ------------------------------------------------------------------------
+
+GfxLink::GfxLink( const GfxLink& rGfxLink )
+{
+ ImplCopy( rGfxLink );
+}
+
+// ------------------------------------------------------------------------
+
+GfxLink::GfxLink( const String& rPath, GfxLinkType nType )
+{
+ sal_Int64 nFileSize = 0;
+
+ try
+ {
+ ::ucb::Content aCnt( INetURLObject( rPath, INET_PROT_FILE ).GetMainURL(),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ aCnt.getPropertyValue( ::rtl::OUString::createFromAscii( "Size" ) ) >>= nFileSize;
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ... )
+ {
+ DBG_ERRORFILE( "Any other exception" );
+ }
+
+ meType = nType;
+ mnBufSize = nFileSize;
+ mpSwap = NULL;
+ mnUserId = 0UL;
+
+ if( mnBufSize )
+ {
+ SvFileStream aFileStream( rPath, STREAM_READ );
+
+ mpBuf = new ImpBuffer( mnBufSize );
+ aFileStream.Read( mpBuf->mpBuffer, mnBufSize );
+ }
+ else
+ mpBuf = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+GfxLink::GfxLink( BYTE* pBuf, ULONG nSize, GfxLinkType nType, BOOL bOwns )
+{
+ meType = nType;
+ mnBufSize = nSize;
+ mpSwap = NULL;
+ mnUserId = 0UL;
+
+ if( bOwns )
+ mpBuf = new ImpBuffer( pBuf );
+ else if( nSize )
+ {
+ mpBuf = new ImpBuffer( nSize );
+ memcpy( mpBuf->mpBuffer, pBuf, nSize );
+ }
+ else
+ mpBuf = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+GfxLink::~GfxLink()
+{
+ if( mpBuf && !( --mpBuf->mnRefCount ) )
+ delete mpBuf;
+
+ if( mpSwap && !( --mpSwap->mnRefCount ) )
+ delete mpSwap;
+}
+
+// ------------------------------------------------------------------------
+
+GfxLink& GfxLink::operator=( const GfxLink& rGfxLink )
+{
+ if( &rGfxLink != this )
+ {
+ if ( mpBuf && !( --mpBuf->mnRefCount ) )
+ delete mpBuf;
+
+ if( mpSwap && !( --mpSwap->mnRefCount ) )
+ delete mpSwap;
+
+ ImplCopy( rGfxLink );
+ }
+
+ return *this;
+}
+
+// ------------------------------------------------------------------------
+
+void GfxLink::ImplCopy( const GfxLink& rGfxLink )
+{
+ mnBufSize = rGfxLink.mnBufSize;
+ meType = rGfxLink.meType;
+ mpBuf = rGfxLink.mpBuf;
+ mpSwap = rGfxLink.mpSwap;
+ mnUserId = rGfxLink.mnUserId;
+
+ if( mpBuf )
+ mpBuf->mnRefCount++;
+
+ if( mpSwap )
+ mpSwap->mnRefCount++;
+}
+
+// ------------------------------------------------------------------------
+
+GfxLinkType GfxLink::GetType() const
+{
+ return meType;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GfxLink::IsNative() const
+{
+ return( meType >= GFX_LINK_FIRST_NATIVE_ID && meType <= GFX_LINK_LAST_NATIVE_ID );
+}
+
+// ------------------------------------------------------------------------
+
+ULONG GfxLink::GetDataSize() const
+{
+ return mnBufSize;
+}
+
+// ------------------------------------------------------------------------
+
+const BYTE* GfxLink::GetData() const
+{
+ if( IsSwappedOut() )
+ ( (GfxLink*) this )->SwapIn();
+
+ return( mpBuf ? mpBuf->mpBuffer : NULL );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL GfxLink::LoadNative( Graphic& rGraphic )
+{
+ BOOL bRet = FALSE;
+
+ if( IsNative() && mnBufSize )
+ {
+ const BYTE* pData = GetData();
+
+ if( pData )
+ {
+ SvMemoryStream aMemStm;
+ ULONG nCvtType;
+
+ aMemStm.SetBuffer( (char*) pData, mnBufSize, FALSE, mnBufSize );
+
+ switch( meType )
+ {
+ case( GFX_LINK_TYPE_NATIVE_GIF ): nCvtType = CVT_GIF; break;
+ case( GFX_LINK_TYPE_NATIVE_JPG ): nCvtType = CVT_JPG; break;
+ case( GFX_LINK_TYPE_NATIVE_PNG ): nCvtType = CVT_PNG; break;
+ case( GFX_LINK_TYPE_NATIVE_TIF ): nCvtType = CVT_TIF; break;
+ case( GFX_LINK_TYPE_NATIVE_WMF ): nCvtType = CVT_WMF; break;
+ case( GFX_LINK_TYPE_NATIVE_MET ): nCvtType = CVT_MET; break;
+ case( GFX_LINK_TYPE_NATIVE_PCT ): nCvtType = CVT_PCT; break;
+
+ default: nCvtType = CVT_UNKNOWN; break;
+ }
+
+ if( nCvtType && ( GraphicConverter::Import( aMemStm, rGraphic, nCvtType ) == ERRCODE_NONE ) )
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void GfxLink::SwapOut()
+{
+ if( !IsSwappedOut() && mpBuf )
+ {
+ mpSwap = new ImpSwap( mpBuf->mpBuffer, mnBufSize );
+
+ if( !mpSwap->IsSwapped() )
+ {
+ delete mpSwap;
+ mpSwap = NULL;
+ }
+ else if( !( --mpBuf->mnRefCount ) )
+ delete mpBuf;
+
+ mpBuf = NULL;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void GfxLink::SwapIn()
+{
+ if( IsSwappedOut() )
+ {
+ mpBuf = new ImpBuffer( mpSwap->GetData() );
+
+ if( !( --mpSwap->mnRefCount ) )
+ delete mpSwap;
+
+ mpSwap = NULL;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const GfxLink& rGfxLink )
+{
+ VersionCompat* pCompat = new VersionCompat( rOStream, STREAM_WRITE, 1 );
+
+ rOStream << (UINT16) rGfxLink.GetType() << rGfxLink.GetDataSize() << rGfxLink.GetUserId();
+
+ delete pCompat;
+
+ if( rGfxLink.GetDataSize() )
+ {
+ if( rGfxLink.IsSwappedOut() )
+ rGfxLink.mpSwap->WriteTo( rOStream );
+ else
+ rOStream.Write( rGfxLink.GetData(), rGfxLink.GetDataSize() );
+ }
+
+ return rOStream;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, GfxLink& rGfxLink)
+{
+ ULONG nSize;
+ ULONG nUserId;
+ UINT16 nType;
+ BYTE* pBuf;
+ VersionCompat* pCompat = new VersionCompat( rIStream, STREAM_READ );
+
+ rIStream >> nType >> nSize >> nUserId;
+
+ delete pCompat;
+
+ pBuf = new BYTE[ nSize ];
+ rIStream.Read( pBuf, nSize );
+
+ rGfxLink = GfxLink( pBuf, nSize, (GfxLinkType) nType, TRUE );
+ rGfxLink.SetUserId( nUserId );
+
+ return rIStream;
+}
+
+// -----------
+// - ImpSwap -
+// -----------
+
+ImpSwap::ImpSwap( BYTE* pData, ULONG nDataSize ) :
+ mnDataSize( nDataSize ),
+ mnRefCount( 1UL )
+{
+ if( pData && mnDataSize )
+ {
+ maFileName = TempFile::CreateTempName();
+
+ if( maFileName.Len() )
+ {
+ SvFileStream aOStm( maFileName, STREAM_WRITE | STREAM_SHARE_DENYWRITE );
+
+ aOStm.Write( pData, mnDataSize );
+
+ if( aOStm.GetError() )
+ {
+ aOStm.Close();
+
+ try
+ {
+ ::ucb::Content aCnt( INetURLObject( maFileName, INET_PROT_FILE ).GetMainURL(),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
+ ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ... )
+ {
+ DBG_ERRORFILE( "Any other exception" );
+ }
+
+ maFileName.Erase();
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ImpSwap::~ImpSwap()
+{
+ if( IsSwapped() )
+ {
+ try
+ {
+ ::ucb::Content aCnt( INetURLObject( maFileName, INET_PROT_FILE ).GetMainURL(),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
+ ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ... )
+ {
+ DBG_ERRORFILE( "Any other exception" );
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+BYTE* ImpSwap::GetData() const
+{
+ BYTE* pData;
+
+ if( IsSwapped() )
+ {
+ SvFileStream aIStm( maFileName, STREAM_READ );
+
+ pData = new BYTE[ mnDataSize ];
+ aIStm.Read( pData, mnDataSize );
+
+ if( aIStm.GetError() )
+ {
+ aIStm.Close();
+ delete[] pData;
+ pData = NULL;
+ }
+ }
+ else
+ pData = NULL;
+
+ return pData;
+}
+
+// ------------------------------------------------------------------------
+
+void ImpSwap::WriteTo( SvStream& rOStm ) const
+{
+ BYTE* pData = GetData();
+
+ if( pData )
+ {
+ rOStm.Write( pData, mnDataSize );
+ delete[] pData;
+ }
+}
diff --git a/vcl/source/gdi/gradient.cxx b/vcl/source/gdi/gradient.cxx
new file mode 100644
index 000000000000..7a6489f9c8e6
--- /dev/null
+++ b/vcl/source/gdi/gradient.cxx
@@ -0,0 +1,386 @@
+/*************************************************************************
+ *
+ * $RCSfile: gradient.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_GRADIENT_CXX
+
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_GRADIENT_HXX
+#include <gradient.hxx>
+#endif
+
+// =======================================================================
+
+DBG_NAME( Gradient );
+
+// -----------------------------------------------------------------------
+
+Impl_Gradient::Impl_Gradient() :
+ maStartColor( COL_BLACK ),
+ maEndColor( COL_WHITE )
+{
+ mnRefCount = 1;
+ meStyle = GRADIENT_LINEAR;
+ mnAngle = 0;
+ mnBorder = 0;
+ mnOfsX = 50;
+ mnOfsY = 50;
+ mnIntensityStart = 100;
+ mnIntensityEnd = 100;
+ mnStepCount = 0;
+}
+
+// -----------------------------------------------------------------------
+
+Impl_Gradient::Impl_Gradient( const Impl_Gradient& rImplGradient ) :
+ maStartColor( rImplGradient.maStartColor ),
+ maEndColor( rImplGradient.maEndColor )
+{
+ mnRefCount = 1;
+ meStyle = rImplGradient.meStyle;
+ mnAngle = rImplGradient.mnAngle;
+ mnBorder = rImplGradient.mnBorder;
+ mnOfsX = rImplGradient.mnOfsX;
+ mnOfsY = rImplGradient.mnOfsY;
+ mnIntensityStart = rImplGradient.mnIntensityStart;
+ mnIntensityEnd = rImplGradient.mnIntensityEnd;
+ mnStepCount = rImplGradient.mnStepCount;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::MakeUnique()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpImplGradient->mnRefCount != 1 )
+ {
+ if( mpImplGradient->mnRefCount )
+ mpImplGradient->mnRefCount--;
+
+ mpImplGradient = new Impl_Gradient( *mpImplGradient );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Gradient::Gradient()
+{
+ DBG_CTOR( Gradient, NULL );
+
+ mpImplGradient = new Impl_Gradient;
+}
+
+// -----------------------------------------------------------------------
+
+Gradient::Gradient( const Gradient& rGradient )
+{
+ DBG_CTOR( Gradient, NULL );
+ DBG_CHKOBJ( &rGradient, Gradient, NULL );
+
+ // Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpImplGradient = rGradient.mpImplGradient;
+ mpImplGradient->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+Gradient::Gradient( GradientStyle eStyle )
+{
+ DBG_CTOR( Gradient, NULL );
+
+ mpImplGradient = new Impl_Gradient;
+ mpImplGradient->meStyle = eStyle;
+}
+
+// -----------------------------------------------------------------------
+
+Gradient::Gradient( GradientStyle eStyle,
+ const Color& rStartColor, const Color& rEndColor )
+{
+ DBG_CTOR( Gradient, NULL );
+
+ mpImplGradient = new Impl_Gradient;
+ mpImplGradient->meStyle = eStyle;
+ mpImplGradient->maStartColor = rStartColor;
+ mpImplGradient->maEndColor = rEndColor;
+}
+
+// -----------------------------------------------------------------------
+
+Gradient::~Gradient()
+{
+ DBG_DTOR( Gradient, NULL );
+
+ // Wenn es die letzte Referenz ist, loeschen,
+ // sonst Referenzcounter decrementieren
+ if ( mpImplGradient->mnRefCount == 1 )
+ delete mpImplGradient;
+ else
+ mpImplGradient->mnRefCount--;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetStyle( GradientStyle eStyle )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->meStyle = eStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetStartColor( const Color& rColor )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->maStartColor = rColor;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetEndColor( const Color& rColor )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->maEndColor = rColor;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetAngle( USHORT nAngle )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->mnAngle = nAngle;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetBorder( USHORT nBorder )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->mnBorder = nBorder;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetOfsX( USHORT nOfsX )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->mnOfsX = nOfsX;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetOfsY( USHORT nOfsY )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->mnOfsY = nOfsY;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetStartIntensity( USHORT nIntens )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->mnIntensityStart = nIntens;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetEndIntensity( USHORT nIntens )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->mnIntensityEnd = nIntens;
+}
+
+// -----------------------------------------------------------------------
+
+void Gradient::SetSteps( USHORT nSteps )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+
+ MakeUnique();
+ mpImplGradient->mnStepCount = nSteps;
+}
+
+// -----------------------------------------------------------------------
+
+Gradient& Gradient::operator=( const Gradient& rGradient )
+{
+ DBG_CHKTHIS( Gradient, NULL );
+ DBG_CHKOBJ( &rGradient, Gradient, NULL );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rGradient.mpImplGradient->mnRefCount++;
+
+ // Wenn es die letzte Referenz ist, loeschen,
+ // sonst Referenzcounter decrementieren
+ if ( mpImplGradient->mnRefCount == 1 )
+ delete mpImplGradient;
+ else
+ mpImplGradient->mnRefCount--;
+ mpImplGradient = rGradient.mpImplGradient;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Gradient::operator==( const Gradient& rGradient ) const
+{
+ DBG_CHKTHIS( Gradient, NULL );
+ DBG_CHKOBJ( &rGradient, Gradient, NULL );
+
+ if ( mpImplGradient == rGradient.mpImplGradient )
+ return TRUE;
+
+ if ( (mpImplGradient->meStyle == rGradient.mpImplGradient->meStyle) ||
+ (mpImplGradient->mnAngle == rGradient.mpImplGradient->mnAngle) ||
+ (mpImplGradient->mnBorder == rGradient.mpImplGradient->mnBorder) ||
+ (mpImplGradient->mnOfsX == rGradient.mpImplGradient->mnOfsX) ||
+ (mpImplGradient->mnOfsY == rGradient.mpImplGradient->mnOfsY) ||
+ (mpImplGradient->mnStepCount == rGradient.mpImplGradient->mnStepCount) ||
+ (mpImplGradient->mnIntensityStart == rGradient.mpImplGradient->mnIntensityStart) ||
+ (mpImplGradient->mnIntensityEnd == rGradient.mpImplGradient->mnIntensityEnd) ||
+ (mpImplGradient->maStartColor == rGradient.mpImplGradient->maStartColor) ||
+ (mpImplGradient->maEndColor == rGradient.mpImplGradient->maEndColor) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+SvStream& operator>>( SvStream& rIStm, Impl_Gradient& rImpl_Gradient )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ UINT16 nTmp16;
+
+ rIStm >> nTmp16; rImpl_Gradient.meStyle = (GradientStyle) nTmp16;
+
+ rIStm >> rImpl_Gradient.maStartColor >>
+ rImpl_Gradient.maEndColor >>
+ rImpl_Gradient.mnAngle >>
+ rImpl_Gradient.mnBorder >>
+ rImpl_Gradient.mnOfsX >>
+ rImpl_Gradient.mnOfsY >>
+ rImpl_Gradient.mnIntensityStart >>
+ rImpl_Gradient.mnIntensityEnd >>
+ rImpl_Gradient.mnStepCount;
+
+ return rIStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const Impl_Gradient& rImpl_Gradient )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 1 );
+
+ rOStm << (UINT16) rImpl_Gradient.meStyle <<
+ rImpl_Gradient.maStartColor <<
+ rImpl_Gradient.maEndColor <<
+ rImpl_Gradient.mnAngle <<
+ rImpl_Gradient.mnBorder <<
+ rImpl_Gradient.mnOfsX <<
+ rImpl_Gradient.mnOfsY <<
+ rImpl_Gradient.mnIntensityStart <<
+ rImpl_Gradient.mnIntensityEnd <<
+ rImpl_Gradient.mnStepCount;
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, Gradient& rGradient )
+{
+ rGradient.MakeUnique();
+ return( rIStm >> *rGradient.mpImplGradient );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const Gradient& rGradient )
+{
+ return( rOStm << *rGradient.mpImplGradient );
+}
diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx
new file mode 100644
index 000000000000..3c847d7dd916
--- /dev/null
+++ b/vcl/source/gdi/graph.cxx
@@ -0,0 +1,832 @@
+/*************************************************************************
+ *
+ * $RCSfile: graph.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_GRAPH_CXX
+
+#ifndef _SV_CLIP_HXX
+#include <clip.hxx>
+#endif
+#ifndef _SV_IMPGRAPH_HXX
+#include <impgraph.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_CLIP_HXX
+#include <clip.hxx>
+#endif
+#ifndef _SV_DRAG_HXX
+#include <drag.hxx>
+#endif
+#include <graph.hxx>
+
+// -----------------------
+// - Compression defines -
+// -----------------------
+
+#define COMPRESS_OWN ('S'|('D'<<8UL))
+#define COMPRESS_NONE ( 0UL )
+#define RLE_8 ( 1UL )
+#define RLE_4 ( 2UL )
+#define BITFIELDS ( 3UL )
+#define ZCOMPRESS ( COMPRESS_OWN | 0x01000000UL ) /* == 'SD01' (binary) */
+
+// -----------------------
+// - Default-Drawmethode -
+// -----------------------
+
+static void ImplDrawDefault( OutputDevice* pOutDev, const UniString* pText,
+ Font* pFont, const Bitmap* pBitmap,
+ const Point& rDestPt, const Size& rDestSize )
+{
+ USHORT nPixel = (USHORT) pOutDev->PixelToLogic( Size( 1, 1 ) ).Width();
+ USHORT nWidth = nPixel;
+ Point aPoint( rDestPt.X() + nWidth, rDestPt.Y() + nWidth );
+ Size aSize( rDestSize.Width() - ( nWidth << 1 ), rDestSize.Height() - ( nWidth << 1 ) );
+ BOOL bFilled = ( pBitmap != NULL || pFont != NULL );
+ Rectangle aBorderRect( aPoint, aSize );
+
+ pOutDev->Push();
+
+ pOutDev->SetFillColor();
+
+ // Auf dem Drucker ein schwarzes Rechteck und auf dem Bildschirm eins mit 3D-Effekt
+ if ( pOutDev->GetOutDevType() == OUTDEV_PRINTER )
+ pOutDev->SetLineColor( COL_BLACK );
+ else
+ {
+ aBorderRect.Left() += nPixel;
+ aBorderRect.Top() += nPixel;
+
+ pOutDev->SetLineColor( COL_LIGHTGRAY );
+ pOutDev->DrawRect( aBorderRect );
+
+ aBorderRect.Left() -= nPixel;
+ aBorderRect.Top() -= nPixel;
+ aBorderRect.Right() -= nPixel;
+ aBorderRect.Bottom() -= nPixel;
+ pOutDev->SetLineColor( COL_GRAY );
+ }
+
+ pOutDev->DrawRect( aBorderRect );
+
+ aPoint.X() += nWidth + 2*nPixel;
+ aPoint.Y() += nWidth + 2*nPixel;
+ aSize.Width() -= 2*nWidth + 4*nPixel;
+ aSize.Height() -= 2*nWidth + 4*nPixel;
+
+ if( aSize.Width() > 0 && aSize.Height() > 0 && pBitmap && !!*pBitmap )
+ {
+ Size aBitmapSize( pOutDev->PixelToLogic(pBitmap->GetSizePixel() ) );
+
+ if( aSize.Height() > aBitmapSize.Height() && aSize.Width() > aBitmapSize.Width() )
+ {
+ pOutDev->DrawBitmap( aPoint, *pBitmap );
+ aPoint.X() += aBitmapSize.Width() + 2*nPixel;
+ aSize.Width() -= aBitmapSize.Width() + 2*nPixel;
+ }
+ }
+
+ if ( aSize.Width() > 0 && aSize.Height() > 0 && pFont && pText && pText->Len()
+ && !(!pOutDev->IsOutputEnabled() /*&& pOutDev->GetConnectMetaFile() */) )
+ {
+ MapMode aMapMode( MAP_POINT );
+ Size aSz = pOutDev->LogicToLogic( Size( 0, 12 ), &aMapMode, NULL );
+ long nThreshold = aSz.Height() / 2;
+ long nStep = nThreshold / 3;
+
+ if ( !nStep )
+ nStep = aSz.Height() - nThreshold;
+
+ for(;; aSz.Height() -= nStep )
+ {
+ pFont->SetSize( aSz );
+ pOutDev->SetFont( *pFont );
+
+ long nTextHeight = pOutDev->GetTextHeight();
+ long nTextWidth = pOutDev->GetTextWidth( *pText );
+ if ( nTextHeight )
+ {
+ // Die N"aherung ber"ucksichtigt keine Ungenauigkeiten durch
+ // Wortumbr"uche
+ long nLines = aSize.Height() / nTextHeight;
+ long nWidth = aSize.Width() * nLines; // N"aherung!!!
+
+ if ( nTextWidth <= nWidth || aSz.Height() <= nThreshold )
+ {
+ USHORT nStart = 0;
+ USHORT nLen = 0;
+
+ while( nStart < pText->Len() && pText->GetChar( nStart ) == ' ' )
+ nStart++;
+ while( nStart+nLen < pText->Len() && pText->GetChar( nStart+nLen ) != ' ' )
+ nLen++;
+ while( nStart < pText->Len() && nLines-- )
+ {
+ USHORT nNext = nLen;
+ do
+ {
+ while ( nStart+nNext < pText->Len() && pText->GetChar( nStart+nNext ) == ' ' )
+ nNext++;
+ while ( nStart+nNext < pText->Len() && pText->GetChar( nStart+nNext ) != ' ' )
+ nNext++;
+ nTextWidth = pOutDev->GetTextWidth( *pText, nStart, nNext );
+ if ( nTextWidth > aSize.Width() )
+ break;
+ nLen = nNext;
+ }
+ while ( nStart+nNext < pText->Len() );
+
+ USHORT n = nLen;
+ nTextWidth = pOutDev->GetTextWidth( *pText, nStart, n );
+ while( nTextWidth > aSize.Width() )
+ nTextWidth = pOutDev->GetTextWidth( *pText, nStart, --n );
+ pOutDev->DrawText( aPoint, *pText, nStart, n );
+
+ aPoint.Y() += nTextHeight;
+ nStart += nLen;
+ nLen = nNext-nLen;
+ while( nStart < pText->Len() && pText->GetChar( nStart ) == ' ' )
+ {
+ nStart++;
+ nLen--;
+ }
+ }
+ break;
+ }
+ }
+ else
+ break;
+ }
+ }
+
+ // Falls die Default-Graphik keinen Inhalt hat,
+ // malen wir ein rotes Kreuz
+ if( !bFilled )
+ {
+ aBorderRect.Left()++;
+ aBorderRect.Top()++;
+ aBorderRect.Right()--;
+ aBorderRect.Bottom()--;
+
+ pOutDev->SetLineColor( COL_LIGHTRED );
+ pOutDev->DrawLine( aBorderRect.TopLeft(), aBorderRect.BottomRight() );
+ pOutDev->DrawLine( aBorderRect.TopRight(), aBorderRect.BottomLeft() );
+ }
+
+ pOutDev->Pop();
+}
+
+// -----------
+// - Graphic -
+// -----------
+
+TYPEINIT1_AUTOFACTORY( Graphic, SvDataCopyStream );
+
+// ------------------------------------------------------------------------
+
+Graphic::Graphic()
+{
+ mpImpGraphic = new ImpGraphic;
+}
+
+// ------------------------------------------------------------------------
+
+Graphic::Graphic( const Graphic& rGraphic )
+{
+ if( rGraphic.IsAnimated() )
+ mpImpGraphic = new ImpGraphic( *rGraphic.mpImpGraphic );
+ else
+ {
+ mpImpGraphic = rGraphic.mpImpGraphic;
+ mpImpGraphic->mnRefCount++;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+Graphic::Graphic( const Bitmap& rBmp )
+{
+ mpImpGraphic = new ImpGraphic( rBmp );
+}
+
+// ------------------------------------------------------------------------
+
+Graphic::Graphic( const BitmapEx& rBmpEx )
+{
+ mpImpGraphic = new ImpGraphic( rBmpEx );
+}
+
+// ------------------------------------------------------------------------
+
+Graphic::Graphic( const Animation& rAnimation )
+{
+ mpImpGraphic = new ImpGraphic( rAnimation );
+}
+
+// ------------------------------------------------------------------------
+
+Graphic::Graphic( const GDIMetaFile& rMtf )
+{
+ mpImpGraphic = new ImpGraphic( rMtf );
+}
+
+// ------------------------------------------------------------------------
+
+Graphic::~Graphic()
+{
+ if( mpImpGraphic->mnRefCount == 1UL )
+ delete mpImpGraphic;
+ else
+ mpImpGraphic->mnRefCount--;
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::ImplTestRefCount()
+{
+ if( mpImpGraphic->mnRefCount > 1UL )
+ {
+ mpImpGraphic->mnRefCount--;
+ mpImpGraphic = new ImpGraphic( *mpImpGraphic );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+Graphic& Graphic::operator=( const Graphic& rGraphic )
+{
+ if( &rGraphic != this )
+ {
+ if( rGraphic.IsAnimated() )
+ {
+ if( mpImpGraphic->mnRefCount == 1UL )
+ delete mpImpGraphic;
+ else
+ mpImpGraphic->mnRefCount--;
+
+ mpImpGraphic = new ImpGraphic( *rGraphic.mpImpGraphic );
+ }
+ else
+ {
+ rGraphic.mpImpGraphic->mnRefCount++;
+
+ if( mpImpGraphic->mnRefCount == 1UL )
+ delete mpImpGraphic;
+ else
+ mpImpGraphic->mnRefCount--;
+
+ mpImpGraphic = rGraphic.mpImpGraphic;
+ }
+ }
+
+ return *this;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::operator==( const Graphic& rGraphic ) const
+{
+ return( *mpImpGraphic == *rGraphic.mpImpGraphic );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::operator!=( const Graphic& rGraphic ) const
+{
+ return( *mpImpGraphic != *rGraphic.mpImpGraphic );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::operator!() const
+{
+ return( GRAPHIC_NONE == mpImpGraphic->ImplGetType() );
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::Load( SvStream& rIStm )
+{
+ rIStm >> *this;
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::Save( SvStream& rOStm )
+{
+ rOStm << *this;
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::Assign( const SvDataCopyStream& rCopyStream )
+{
+ *this = (const Graphic& ) rCopyStream;
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::Clear()
+{
+ ImplTestRefCount();
+ mpImpGraphic->ImplClear();
+}
+
+// ------------------------------------------------------------------------
+
+GraphicType Graphic::GetType() const
+{
+ return mpImpGraphic->ImplGetType();
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::SetDefaultType()
+{
+ ImplTestRefCount();
+ mpImpGraphic->ImplSetDefaultType();
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::IsSupportedGraphic() const
+{
+ return mpImpGraphic->ImplIsSupportedGraphic();
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::IsTransparent() const
+{
+ return mpImpGraphic->ImplIsTransparent();
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::IsAlpha() const
+{
+ return mpImpGraphic->ImplIsAlpha();
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::IsAnimated() const
+{
+ return mpImpGraphic->ImplIsAnimated();
+}
+
+// ------------------------------------------------------------------------
+
+Bitmap Graphic::GetBitmap() const
+{
+ return mpImpGraphic->ImplGetBitmap();
+}
+
+// ------------------------------------------------------------------------
+
+BitmapEx Graphic::GetBitmapEx() const
+{
+ return mpImpGraphic->ImplGetBitmapEx();
+}
+
+// ------------------------------------------------------------------------
+
+Animation Graphic::GetAnimation() const
+{
+ return mpImpGraphic->ImplGetAnimation();
+}
+
+// ------------------------------------------------------------------------
+
+const GDIMetaFile& Graphic::GetGDIMetaFile() const
+{
+ return mpImpGraphic->ImplGetGDIMetaFile();
+}
+
+// ------------------------------------------------------------------------
+
+Size Graphic::GetPrefSize() const
+{
+ return mpImpGraphic->ImplGetPrefSize();
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::SetPrefSize( const Size& rPrefSize )
+{
+ ImplTestRefCount();
+ mpImpGraphic->ImplSetPrefSize( rPrefSize );
+}
+
+// ------------------------------------------------------------------------
+
+MapMode Graphic::GetPrefMapMode() const
+{
+ return mpImpGraphic->ImplGetPrefMapMode();
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::SetPrefMapMode( const MapMode& rPrefMapMode )
+{
+ ImplTestRefCount();
+ mpImpGraphic->ImplSetPrefMapMode( rPrefMapMode );
+}
+
+// ------------------------------------------------------------------
+
+ULONG Graphic::GetSizeBytes() const
+{
+ return mpImpGraphic->ImplGetSizeBytes();
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const
+{
+ mpImpGraphic->ImplDraw( pOutDev, rDestPt );
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::Draw( OutputDevice* pOutDev,
+ const Point& rDestPt, const Size& rDestSz ) const
+{
+ if( GRAPHIC_DEFAULT == mpImpGraphic->ImplGetType() )
+ ImplDrawDefault( pOutDev, NULL, NULL, NULL, rDestPt, rDestSz );
+ else
+ mpImpGraphic->ImplDraw( pOutDev, rDestPt, rDestSz );
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::Draw( OutputDevice* pOutDev, const String& rText,
+ Font& rFont, const Bitmap& rBitmap,
+ const Point& rDestPt, const Size& rDestSz )
+{
+ ImplDrawDefault( pOutDev, &rText, &rFont, &rBitmap, rDestPt, rDestSz );
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::StartAnimation( OutputDevice* pOutDev, const Point& rDestPt, long nExtraData,
+ OutputDevice* pFirstFrameOutDev )
+{
+ ImplTestRefCount();
+ mpImpGraphic->ImplStartAnimation( pOutDev, rDestPt, nExtraData, pFirstFrameOutDev );
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::StartAnimation( OutputDevice* pOutDev, const Point& rDestPt,
+ const Size& rDestSz, long nExtraData,
+ OutputDevice* pFirstFrameOutDev )
+{
+ ImplTestRefCount();
+ mpImpGraphic->ImplStartAnimation( pOutDev, rDestPt, rDestSz, nExtraData, pFirstFrameOutDev );
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::StopAnimation( OutputDevice* pOutDev, long nExtraData )
+{
+ ImplTestRefCount();
+ mpImpGraphic->ImplStopAnimation( pOutDev, nExtraData );
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::SetAnimationNotifyHdl( const Link& rLink )
+{
+ mpImpGraphic->ImplSetAnimationNotifyHdl( rLink );
+}
+
+// ------------------------------------------------------------------------
+
+Link Graphic::GetAnimationNotifyHdl() const
+{
+ return mpImpGraphic->ImplGetAnimationNotifyHdl();
+}
+
+// ------------------------------------------------------------------------
+
+ULONG Graphic::GetAnimationLoopCount() const
+{
+ return mpImpGraphic->ImplGetAnimationLoopCount();
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::ResetAnimationLoopCount()
+{
+ mpImpGraphic->ImplResetAnimationLoopCount();
+}
+
+// ------------------------------------------------------------------------
+
+List* Graphic::GetAnimationInfoList() const
+{
+ return mpImpGraphic->ImplGetAnimationInfoList();
+}
+
+// ------------------------------------------------------------------------
+
+GraphicReader* Graphic::GetContext()
+{
+ return mpImpGraphic->ImplGetContext();
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::SetContext( GraphicReader* pReader )
+{
+ mpImpGraphic->ImplSetContext( pReader );
+}
+
+// ------------------------------------------------------------------------
+
+USHORT Graphic::GetGraphicsCompressMode( SvStream& rIStm )
+{
+ const ULONG nPos = rIStm.Tell();
+ const USHORT nOldFormat = rIStm.GetNumberFormatInt();
+ UINT32 nTmp32;
+ UINT16 nTmp16;
+ USHORT nCompressMode = COMPRESSMODE_NONE;
+
+ rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ rIStm >> nTmp32;
+
+ // is it a swapped graphic with a bitmap?
+ rIStm.SeekRel( (nTmp32 == (UINT32) GRAPHIC_BITMAP ) ? 40 : -4 );
+
+ // try to read bitmap id
+ rIStm >> nTmp16;
+
+ // check id of BitmapFileHeader
+ if( 0x4D42 == nTmp16 )
+ {
+ // seek to compress field of BitmapInfoHeader
+ rIStm.SeekRel( 28 );
+ rIStm >> nTmp32;
+
+ // Compare with our own compressmode
+ if( ZCOMPRESS == nTmp32 )
+ nCompressMode = COMPRESSMODE_ZBITMAP;
+ }
+
+ rIStm.SetNumberFormatInt( nOldFormat );
+ rIStm.Seek( nPos );
+
+ return nCompressMode;
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::SetDocFileName( const String& rName, ULONG nFilePos )
+{
+ mpImpGraphic->ImplSetDocFileName( rName, nFilePos );
+}
+
+// ------------------------------------------------------------------------
+
+const String& Graphic::GetDocFileName() const
+{
+ return mpImpGraphic->ImplGetDocFileName();
+}
+
+// ------------------------------------------------------------------------
+
+ULONG Graphic::GetDocFilePos() const
+{
+ return mpImpGraphic->ImplGetDocFilePos();
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::ReadEmbedded( SvStream& rIStream, BOOL bSwap )
+{
+ ImplTestRefCount();
+ return mpImpGraphic->ImplReadEmbedded( rIStream, bSwap );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::WriteEmbedded( SvStream& rOStream )
+{
+ ImplTestRefCount();
+ return mpImpGraphic->ImplWriteEmbedded( rOStream );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::SwapOut()
+{
+ ImplTestRefCount();
+ return mpImpGraphic->ImplSwapOut();
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::SwapOut( SvStream* pOStream )
+{
+ ImplTestRefCount();
+ return mpImpGraphic->ImplSwapOut( pOStream );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::SwapIn()
+{
+ ImplTestRefCount();
+ return mpImpGraphic->ImplSwapIn();
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::SwapIn( SvStream* pStrm )
+{
+ ImplTestRefCount();
+ return mpImpGraphic->ImplSwapIn( pStrm );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::IsSwapOut() const
+{
+ return mpImpGraphic->ImplIsSwapOut();
+}
+
+// ------------------------------------------------------------------------
+
+void Graphic::SetLink( const GfxLink& rGfxLink )
+{
+ ImplTestRefCount();
+ mpImpGraphic->ImplSetLink( rGfxLink );
+}
+
+// ------------------------------------------------------------------------
+
+GfxLink Graphic::GetLink()
+{
+ return mpImpGraphic->ImplGetLink();
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::IsLink() const
+{
+ return mpImpGraphic->ImplIsLink();
+}
+
+// ------------------------------------------------------------------------
+
+ULONG Graphic::GetChecksum() const
+{
+ return mpImpGraphic->ImplGetChecksum();
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, Graphic& rGraphic )
+{
+ rGraphic.ImplTestRefCount();
+ return rIStream >> *rGraphic.mpImpGraphic;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const Graphic& rGraphic )
+{
+ return rOStream << *rGraphic.mpImpGraphic;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG Graphic::RegisterClipboardFormatName()
+{
+ static ULONG nFormat = 0;
+
+ if ( !nFormat )
+ nFormat = Clipboard::RegisterFormatName( XubString( RTL_CONSTASCII_USTRINGPARAM( "SVXB (StarView Bitmap/Animation)" ) ) );
+
+ return nFormat;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::ClipboardHasFormat()
+{
+ return Clipboard::HasFormat( RegisterClipboardFormatName() )
+ || Clipboard::HasFormat( FORMAT_GDIMETAFILE )
+ || Clipboard::HasFormat( FORMAT_BITMAP );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::DragServerHasFormat( USHORT nItem )
+{
+ return DragServer::HasFormat( nItem, RegisterClipboardFormatName() )
+ || DragServer::HasFormat( nItem, FORMAT_GDIMETAFILE )
+ || DragServer::HasFormat( nItem, FORMAT_BITMAP );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::Copy() const
+{
+ SotDataMemberObjectRef aDataObject = new SotDataMemberObject;
+ SvData* pData = new SvData( RegisterClipboardFormatName() );
+
+ pData->SetData( (SvDataCopyStream*) this, TRANSFER_COPY );
+ aDataObject->Append( pData );
+ VclClipboard::Copy( aDataObject );
+
+ return TRUE;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL Graphic::Paste()
+{
+ const ULONG nFormat = RegisterClipboardFormatName();
+ BOOL bRet = FALSE;
+
+ if( VclClipboard::HasFormat( nFormat ) )
+ {
+ SotDataObjectRef aDataObject = VclClipboard::Paste();
+ SvData aData( nFormat );
+
+ if( aDataObject.Is() && aDataObject->GetData( &aData ) )
+ {
+ Graphic* pGraphic = NULL;
+
+ if( aData.GetData( (SvDataCopyStream**) &pGraphic, StaticType(), TRANSFER_MOVE ) )
+ *this = *pGraphic;
+
+ delete pGraphic;
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
diff --git a/vcl/source/gdi/hatch.cxx b/vcl/source/gdi/hatch.cxx
new file mode 100644
index 000000000000..ac66e89fd0cf
--- /dev/null
+++ b/vcl/source/gdi/hatch.cxx
@@ -0,0 +1,262 @@
+/*************************************************************************
+ *
+ * $RCSfile: hatch.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_HATCH_CXX
+
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_HATCX_HXX
+#include <hatch.hxx>
+#endif
+
+DBG_NAME( Hatch );
+
+// --------------
+// - ImplHatch -
+// --------------
+
+ImplHatch::ImplHatch() :
+ mnRefCount ( 1 ),
+ maColor ( COL_BLACK ),
+ meStyle ( HATCH_SINGLE ),
+ mnDistance ( 1 ),
+ mnAngle ( 0 )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ImplHatch::ImplHatch( const ImplHatch& rImplHatch ) :
+ mnRefCount ( 1 ),
+ maColor ( rImplHatch.maColor ),
+ meStyle ( rImplHatch.meStyle ),
+ mnDistance ( rImplHatch.mnDistance ),
+ mnAngle ( rImplHatch.mnAngle )
+{
+}
+
+// ---------
+// - Hatch -
+// ---------
+
+Hatch::Hatch()
+{
+ DBG_CTOR( Hatch, NULL );
+ mpImplHatch = new ImplHatch;
+}
+
+// -----------------------------------------------------------------------
+
+Hatch::Hatch( const Hatch& rHatch )
+{
+ DBG_CTOR( Hatch, NULL );
+ DBG_CHKOBJ( &rHatch, Hatch, NULL );
+ mpImplHatch = rHatch.mpImplHatch;
+ mpImplHatch->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+Hatch::Hatch( HatchStyle eStyle, const Color& rColor,
+ long nDistance, USHORT nAngle10 )
+{
+ DBG_CTOR( Hatch, NULL );
+ mpImplHatch = new ImplHatch;
+ mpImplHatch->maColor = rColor;
+ mpImplHatch->meStyle = eStyle;
+ mpImplHatch->mnDistance = nDistance;
+ mpImplHatch->mnAngle = nAngle10;
+}
+
+// -----------------------------------------------------------------------
+
+Hatch::~Hatch()
+{
+ DBG_DTOR( Hatch, NULL );
+ if( !( --mpImplHatch->mnRefCount ) )
+ delete mpImplHatch;
+}
+
+// -----------------------------------------------------------------------
+
+Hatch& Hatch::operator=( const Hatch& rHatch )
+{
+ DBG_CHKTHIS( Hatch, NULL );
+ DBG_CHKOBJ( &rHatch, Hatch, NULL );
+
+ rHatch.mpImplHatch->mnRefCount++;
+
+ if( !( --mpImplHatch->mnRefCount ) )
+ delete mpImplHatch;
+
+ mpImplHatch = rHatch.mpImplHatch;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Hatch::operator==( const Hatch& rHatch ) const
+{
+ DBG_CHKTHIS( Hatch, NULL );
+ DBG_CHKOBJ( &rHatch, Hatch, NULL );
+
+ return( mpImplHatch == rHatch.mpImplHatch ||
+ ( mpImplHatch->maColor == rHatch.mpImplHatch->maColor &&
+ mpImplHatch->meStyle == rHatch.mpImplHatch->meStyle &&
+ mpImplHatch->mnDistance == rHatch.mpImplHatch->mnDistance &&
+ mpImplHatch->mnAngle == rHatch.mpImplHatch->mnAngle ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Hatch::ImplMakeUnique()
+{
+ if( mpImplHatch->mnRefCount != 1 )
+ {
+ if( mpImplHatch->mnRefCount )
+ mpImplHatch->mnRefCount--;
+
+ mpImplHatch = new ImplHatch( *mpImplHatch );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Hatch::SetStyle( HatchStyle eStyle )
+{
+ DBG_CHKTHIS( Hatch, NULL );
+ ImplMakeUnique();
+ mpImplHatch->meStyle = eStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void Hatch::SetColor( const Color& rColor )
+{
+ DBG_CHKTHIS( Hatch, NULL );
+ ImplMakeUnique();
+ mpImplHatch->maColor = rColor;
+}
+
+// -----------------------------------------------------------------------
+
+void Hatch::SetDistance( long nDistance )
+{
+ DBG_CHKTHIS( Hatch, NULL );
+ ImplMakeUnique();
+ mpImplHatch->mnDistance = nDistance;
+}
+
+// -----------------------------------------------------------------------
+
+void Hatch::SetAngle( USHORT nAngle10 )
+{
+ DBG_CHKTHIS( Hatch, NULL );
+ ImplMakeUnique();
+ mpImplHatch->mnAngle = nAngle10;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, ImplHatch& rImplHatch )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ UINT16 nTmp16;
+
+ rIStm >> nTmp16; rImplHatch.meStyle = (HatchStyle) nTmp16;
+ rIStm >> rImplHatch.maColor >> rImplHatch.mnDistance >> rImplHatch.mnAngle;
+
+ return rIStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const ImplHatch& rImplHatch )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 1 );
+
+ rOStm << (UINT16) rImplHatch.meStyle << rImplHatch.maColor;
+ rOStm << rImplHatch.mnDistance << rImplHatch.mnAngle;
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, Hatch& rHatch )
+{
+ rHatch.ImplMakeUnique();
+ return( rIStm >> *rHatch.mpImplHatch );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const Hatch& rHatch )
+{
+ return( rOStm << *rHatch.mpImplHatch );
+}
diff --git a/vcl/source/gdi/image.cxx b/vcl/source/gdi/image.cxx
new file mode 100644
index 000000000000..16188cdc5143
--- /dev/null
+++ b/vcl/source/gdi/image.cxx
@@ -0,0 +1,1521 @@
+/*************************************************************************
+ *
+ * $RCSfile: image.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#define _SV_IMAGE_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_RC_HXX
+#include <rc.hxx>
+#endif
+#ifndef _SV_RESMGR_HXX
+#include <resmgr.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_IMAGE_H
+#include <image.h>
+#endif
+#define private public
+#ifndef _SV_IMAGE_HXX
+#include <image.hxx>
+#endif
+#undef private
+
+// =======================================================================
+
+DBG_NAME( Image );
+DBG_NAME( ImageList );
+
+#define IMAGE_FILE_VERSION 100
+
+// =======================================================================
+
+ImplImageList::~ImplImageList()
+{
+ if ( mpImageBitmap )
+ delete mpImageBitmap;
+ delete mpAry;
+}
+
+// =======================================================================
+
+ImplImageRefData::~ImplImageRefData()
+{
+ mpImplData->mnIRefCount--;
+ if ( mpImplData->mnRefCount || mpImplData->mnIRefCount )
+ {
+ mpImplData->mpAry[mnIndex].mnRefCount--;
+ if ( !mpImplData->mpAry[mnIndex].mnRefCount )
+ mpImplData->mnRealCount--;
+ }
+ else
+ delete mpImplData;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplImageRefData::IsEqual( const ImplImageRefData& rData )
+{
+ if ( (mpImplData == rData.mpImplData) && (mnIndex == rData.mnIndex) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// =======================================================================
+
+ImplImageData::ImplImageData( const Bitmap& rBmp, const Bitmap& rMaskBmp ) :
+ maBmp( rBmp ),
+ maMaskBmp( rMaskBmp )
+{
+ mbColor = FALSE;
+ mpImageBitmap = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplImageData::ImplImageData( const Bitmap& rBmp, const Color& rColor ) :
+ maBmp( rBmp ),
+ maColor( rColor )
+{
+ mbColor = TRUE;
+ mpImageBitmap = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplImageData::~ImplImageData()
+{
+ if ( mpImageBitmap )
+ delete mpImageBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplImageData::IsEqual( const ImplImageData& rData )
+{
+ if ( (maBmp == rData.maBmp) && (maMaskBmp == rData.maMaskBmp) &&
+ (maColor == rData.maColor) && (mbColor == rData.mbColor) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// =======================================================================
+
+ImplImage::~ImplImage()
+{
+ switch ( meType )
+ {
+ case IMAGETYPE_BITMAP:
+ delete (Bitmap*)mpData;
+ break;
+
+ case IMAGETYPE_IMAGE:
+ delete (ImplImageData*)mpData;
+ break;
+
+ case IMAGETYPE_IMAGEREF:
+ delete (ImplImageRefData*)mpData;
+ break;
+ }
+}
+
+// =======================================================================
+
+Image::Image()
+{
+ DBG_CTOR( Image, NULL );
+
+ mpImplData = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+Image::Image( const ResId& rResId )
+{
+ DBG_CTOR( Image, NULL );
+
+ rResId.SetRT( RSC_IMAGE );
+ ResMgr* pResMgr = rResId.GetResMgr();
+ if ( !pResMgr )
+ pResMgr = Resource::GetResManager();
+
+ if ( pResMgr->GetResource( rResId ) )
+ {
+ // Header ueberspringen
+ pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
+
+ USHORT nObjMask = pResMgr->ReadShort();
+
+ Bitmap aImageBitmap;
+ Bitmap aMaskBitmap;
+ Color aMaskColor;
+ if( nObjMask & RSC_IMAGE_IMAGEBITMAP )
+ {
+ aImageBitmap = Bitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ }
+ if( nObjMask & RSC_IMAGE_MASKBITMAP )
+ {
+ aMaskBitmap = Bitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ }
+ if( nObjMask & RSC_IMAGE_MASKCOLOR )
+ {
+ aMaskColor = Color( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ }
+
+ if ( !aImageBitmap )
+ mpImplData = NULL;
+ else
+ {
+ mpImplData = new ImplImage;
+ mpImplData->mnRefCount = 1;
+ if ( !aMaskBitmap )
+ {
+ if( nObjMask & RSC_IMAGE_MASKCOLOR )
+ {
+ mpImplData->meType = IMAGETYPE_IMAGE;
+ mpImplData->mpData = new ImplImageData( aImageBitmap, aMaskColor );
+ }
+ else
+ {
+ mpImplData->meType = IMAGETYPE_BITMAP;
+ mpImplData->mpData = new Bitmap( aImageBitmap );
+ }
+ }
+ else
+ {
+ mpImplData->meType = IMAGETYPE_IMAGE;
+ mpImplData->mpData = new ImplImageData( aImageBitmap, aMaskBitmap );
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR( "Image::Image( const ResId& rResId ): No resource!" );
+ mpImplData = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image::Image( const Image& rImage )
+{
+ DBG_CTOR( Image, NULL );
+
+ mpImplData = rImage.mpImplData;
+ if ( mpImplData )
+ mpImplData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+Image::Image( const Bitmap& rBitmap )
+{
+ DBG_CTOR( Image, NULL );
+
+ if ( !rBitmap )
+ mpImplData = NULL;
+ else
+ {
+ mpImplData = new ImplImage;
+ mpImplData->mnRefCount = 1;
+ mpImplData->meType = IMAGETYPE_BITMAP;
+ mpImplData->mpData = new Bitmap( rBitmap );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image::Image( const Bitmap& rBitmap, const Bitmap& rMaskBitmap )
+{
+ DBG_CTOR( Image, NULL );
+
+ if ( !rBitmap )
+ mpImplData = NULL;
+ else
+ {
+ mpImplData = new ImplImage;
+ mpImplData->mnRefCount = 1;
+ if ( !rMaskBitmap )
+ {
+ mpImplData->meType = IMAGETYPE_BITMAP;
+ mpImplData->mpData = new Bitmap( rBitmap );
+ }
+ else
+ {
+ mpImplData->meType = IMAGETYPE_IMAGE;
+ mpImplData->mpData = new ImplImageData( rBitmap, rMaskBitmap );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image::Image( const Bitmap& rBitmap, const Color& rColor )
+{
+ DBG_CTOR( Image, NULL );
+
+ if ( !rBitmap )
+ mpImplData = NULL;
+ else
+ {
+ mpImplData = new ImplImage;
+ mpImplData->mnRefCount = 1;
+ mpImplData->meType = IMAGETYPE_IMAGE;
+ mpImplData->mpData = new ImplImageData( rBitmap, rColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image::Image( const BitmapEx& rBitmapEx )
+{
+ DBG_CTOR( Image, NULL );
+
+ const Bitmap aBmp( rBitmapEx.GetBitmap() );
+
+ if( !aBmp )
+ mpImplData = NULL;
+ else
+ {
+ const Bitmap aMask( rBitmapEx.GetMask() );
+
+ mpImplData = new ImplImage;
+ mpImplData->mnRefCount = 1;
+
+ if( !aMask )
+ {
+ mpImplData->meType = IMAGETYPE_BITMAP;
+ mpImplData->mpData = new Bitmap( aBmp );
+ }
+ else
+ {
+ mpImplData->meType = IMAGETYPE_IMAGE;
+ mpImplData->mpData = new ImplImageData( aBmp, aMask );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image::~Image()
+{
+ DBG_DTOR( Image, NULL );
+
+ if ( mpImplData )
+ {
+ if ( mpImplData->mnRefCount > 1 )
+ mpImplData->mnRefCount--;
+ else
+ delete mpImplData;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size Image::GetSizePixel() const
+{
+ DBG_CHKTHIS( Image, NULL );
+
+ if ( mpImplData )
+ {
+ switch ( mpImplData->meType )
+ {
+ case IMAGETYPE_BITMAP:
+ return ((Bitmap*)mpImplData->mpData)->GetSizePixel();
+
+ case IMAGETYPE_IMAGE:
+ return ((ImplImageData*)mpImplData->mpData)->maBmp.GetSizePixel();
+
+ case IMAGETYPE_IMAGEREF:
+ return ((ImplImageRefData*)mpImplData->mpData)->mpImplData->maImageSize;
+ }
+ }
+
+ return Size();
+}
+
+// -----------------------------------------------------------------------
+
+Image& Image::operator=( const Image& rImage )
+{
+ DBG_CHKTHIS( Image, NULL );
+ DBG_CHKOBJ( &rImage, Image, NULL );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ if ( rImage.mpImplData )
+ rImage.mpImplData->mnRefCount++;
+
+ // Abkoppeln
+ if ( mpImplData )
+ {
+ if ( mpImplData->mnRefCount > 1 )
+ mpImplData->mnRefCount--;
+ else
+ delete mpImplData;
+ }
+
+ // Neue Daten zuweisen
+ mpImplData = rImage.mpImplData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Image::operator==( const Image& rImage ) const
+{
+ DBG_CHKTHIS( Image, NULL );
+ DBG_CHKOBJ( &rImage, Image, NULL );
+
+ if ( rImage.mpImplData == mpImplData )
+ return TRUE;
+ if ( !rImage.mpImplData || !mpImplData )
+ return FALSE;
+
+ if ( rImage.mpImplData->mpData == mpImplData->mpData )
+ return TRUE;
+
+ if ( rImage.mpImplData->meType == mpImplData->meType )
+ {
+ switch ( mpImplData->meType )
+ {
+ case IMAGETYPE_BITMAP:
+ if ( *((Bitmap*)rImage.mpImplData->mpData) == *((Bitmap*)mpImplData->mpData) )
+ return TRUE;
+ break;
+
+ case IMAGETYPE_IMAGE:
+ if ( ((ImplImageData*)rImage.mpImplData->mpData)->IsEqual( *((ImplImageData*)mpImplData->mpData) ) )
+ return TRUE;
+ break;
+
+ case IMAGETYPE_IMAGEREF:
+ if ( ((ImplImageRefData*)rImage.mpImplData->mpData)->IsEqual( *((ImplImageRefData*)mpImplData->mpData) ) )
+ return TRUE;
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+// =======================================================================
+
+static void ImplCopyImageListData( ImageList* pThis )
+{
+ if ( pThis->mpImplData->mnRefCount > 1 )
+ {
+ pThis->mpImplData->mnRefCount--;
+
+ ImplImageList* pNewData = new ImplImageList;
+ pNewData->mnRefCount = 1;
+ pNewData->mnIRefCount = 0;
+ pNewData->mnCount = pThis->mpImplData->mnCount;
+ pNewData->mnRealCount = pThis->mpImplData->mnRealCount;
+ pNewData->mnArySize = pThis->mpImplData->mnArySize;
+ pNewData->mpAry = new ImageAryData[pNewData->mnArySize];
+ pNewData->maImageSize = pThis->mpImplData->maImageSize;
+ pNewData->mpImageBitmap = new ImplImageBmp;
+ pNewData->mpImageBitmap->Create( pNewData->maImageSize.Width(),
+ pNewData->maImageSize.Height(),
+ pNewData->mnArySize );
+ memset( pNewData->mpAry, 0, pNewData->mnArySize*sizeof(ImageAryData) );
+
+ USHORT i = 0;
+ USHORT n = 0;
+ while ( i < pThis->mpImplData->mnArySize )
+ {
+ // Nur die Images kopieren, die gebraucht werden
+ if ( pThis->mpImplData->mpAry[i].mnId )
+ {
+ pNewData->mpAry[n].mnId = pThis->mpImplData->mpAry[i].mnId;
+ pNewData->mpAry[n].mnRefCount = 1;
+ pNewData->mpImageBitmap->Replace( n,
+ *(pThis->mpImplData->mpImageBitmap),
+ i );
+ n++;
+ }
+
+ i++;
+ }
+
+ pThis->mpImplData = pNewData;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplBmpImageCreate( ImageList* pThis,
+ const Bitmap& rBitmap, const Bitmap& rMaskBmp,
+ const Color& rColor, BOOL bColor,
+ USHORT nInit, USHORT* mpIdAry = NULL,
+ USHORT nGrow = 4 )
+{
+ // Falls es sich um eine leere ImageListe handelt, dann Defaul-Werte
+ // setzen und nichts machen
+ if ( !nInit )
+ {
+ pThis->mpImplData = NULL;
+ pThis->mnInitSize = 1;
+ pThis->mnGrowSize = nGrow;
+ return;
+ }
+
+ DBG_ASSERT( !nInit || rBitmap.GetSizePixel().Width(),
+ "ImageList::ImageList(): nInitSize != 0 and BmpSize.Width() == 0" );
+ DBG_ASSERT( (rBitmap.GetSizePixel().Width() % nInit) == 0,
+ "ImageList::ImageList(): BmpSize % nInitSize != 0" );
+ DBG_ASSERT( !rMaskBmp || (rMaskBmp.GetSizePixel() == rBitmap.GetSizePixel()),
+ "ImageList::ImageList(): BmpSize != MaskBmpSize" );
+#ifdef DBG_UTIL
+ if ( mpIdAry )
+ {
+ for ( USHORT n1 = 0; n1 < nInit; n1++ )
+ {
+ USHORT nId = mpIdAry[n1];
+ if ( !nId )
+ {
+ DBG_ERROR( "ImageList::ImageList(): Id == 0" );
+ }
+ for ( USHORT n2 = 0; n2 < n1; n2++ )
+ {
+ if ( nId == mpIdAry[n2] )
+ {
+ DBG_ERROR1( "ImageList::ImageList(): Double Id (%u)", nId );
+ }
+ }
+ }
+ }
+#endif
+
+ Size aBmpSize = rBitmap.GetSizePixel();
+ pThis->mnInitSize = nInit;
+ pThis->mnGrowSize = nGrow;
+ pThis->mpImplData = new ImplImageList;
+ pThis->mpImplData->mnRefCount = 1;
+ pThis->mpImplData->mnIRefCount = 0;
+ pThis->mpImplData->mnCount = nInit;
+ pThis->mpImplData->mnRealCount = nInit;
+ pThis->mpImplData->mnArySize = nInit;
+ pThis->mpImplData->mpAry = new ImageAryData[nInit];
+ pThis->mpImplData->maImageSize = Size( aBmpSize.Width() / nInit, aBmpSize.Height() );
+
+ for ( USHORT i = 0; i < nInit; i++ )
+ {
+ if ( mpIdAry )
+ pThis->mpImplData->mpAry[i].mnId = mpIdAry[i];
+ else
+ pThis->mpImplData->mpAry[i].mnId = i+1;
+ pThis->mpImplData->mpAry[i].mnRefCount = 1;
+ }
+
+ pThis->mpImplData->mpImageBitmap = new ImplImageBmp;
+ pThis->mpImplData->mpImageBitmap->Create( rBitmap, rMaskBmp,
+ rColor, bColor,
+ pThis->mpImplData->maImageSize.Width(),
+ pThis->mpImplData->maImageSize.Height(),
+ nInit );
+}
+
+// =======================================================================
+
+ImageList::ImageList( USHORT nInit, USHORT nGrow )
+{
+ DBG_CTOR( ImageList, NULL );
+
+ mpImplData = NULL;
+ mnInitSize = nInit;
+ mnGrowSize = nGrow;
+}
+
+// -----------------------------------------------------------------------
+
+ImageList::ImageList( const ResId& rResId )
+{
+ DBG_CTOR( ImageList, NULL );
+
+ rResId.SetRT( RSC_IMAGELIST );
+ ResMgr* pResMgr = rResId.GetResMgr();
+ if ( !pResMgr )
+ pResMgr = Resource::GetResManager();
+
+ if ( pResMgr->GetResource( rResId ) )
+ {
+ // Header ueberspringen
+ pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
+
+ USHORT nObjMask = pResMgr->ReadShort();
+
+ Bitmap aImageBitmap;
+ Bitmap aMaskBitmap;
+ Color aMaskColor;
+ BOOL bCol = FALSE;
+ BOOL bIsIdList = FALSE;
+
+ if ( nObjMask & RSC_IMAGELIST_IMAGEBITMAP )
+ {
+ aImageBitmap = Bitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ }
+ if ( nObjMask & RSC_IMAGELIST_MASKBITMAP )
+ {
+ aMaskBitmap = Bitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ }
+ if ( nObjMask & RSC_IMAGELIST_MASKCOLOR )
+ {
+ aMaskColor = Color( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
+ bCol = TRUE;
+ }
+ if ( nObjMask & RSC_IMAGELIST_IDLIST )
+ {
+ bIsIdList = TRUE;
+ USHORT nCount = pResMgr->ReadShort();
+ USHORT* pAry = new USHORT[ nCount ];
+ for( int i = 0; i < nCount; i++ )
+ pAry[ i ] = pResMgr->ReadShort();
+ ImplBmpImageCreate( this, aImageBitmap, aMaskBitmap, aMaskColor,
+ bCol, nCount, pAry, 4 );
+ delete pAry;
+ }
+ if ( nObjMask & RSC_IMAGELIST_IDCOUNT )
+ {
+ USHORT nCount = pResMgr->ReadShort();
+ if ( !bIsIdList )
+ {
+ ImplBmpImageCreate( this, aImageBitmap, aMaskBitmap, aMaskColor,
+ bCol, nCount, NULL, 4 );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ImageList::ImageList( const ImageList& rImageList )
+{
+ DBG_CTOR( ImageList, NULL );
+
+ mpImplData = rImageList.mpImplData;
+ if ( mpImplData )
+ mpImplData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+ImageList::ImageList( const Bitmap& rBitmap,
+ USHORT nInit, USHORT* mpIdAry, USHORT nGrow )
+{
+ DBG_CTOR( ImageList, NULL );
+
+ ImplBmpImageCreate( this, rBitmap, Bitmap(), Color(), FALSE,
+ nInit, mpIdAry, nGrow );
+}
+
+// -----------------------------------------------------------------------
+
+ImageList::ImageList( const Bitmap& rBitmap, const Bitmap& rMaskBmp,
+ USHORT nInit, USHORT* mpIdAry, USHORT nGrow )
+{
+ DBG_CTOR( ImageList, NULL );
+
+ ImplBmpImageCreate( this, rBitmap, rMaskBmp, Color(), FALSE,
+ nInit, mpIdAry, nGrow );
+}
+
+// -----------------------------------------------------------------------
+
+ImageList::ImageList( const Bitmap& rBitmap, const Color& rColor,
+ USHORT nInit, USHORT* mpIdAry, USHORT nGrow )
+{
+ DBG_CTOR( ImageList, NULL );
+
+ ImplBmpImageCreate( this, rBitmap, Bitmap(), rColor, TRUE,
+ nInit, mpIdAry, nGrow );
+}
+
+// -----------------------------------------------------------------------
+
+ImageList::~ImageList()
+{
+ DBG_DTOR( ImageList, NULL );
+
+ if ( mpImplData )
+ {
+ mpImplData->mnRefCount--;
+ if ( !mpImplData->mnRefCount && !mpImplData->mnIRefCount )
+ delete mpImplData;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImageList::AddImage( USHORT nId, const Image& rImage )
+{
+ DBG_CHKTHIS( ImageList, NULL );
+ DBG_CHKOBJ( &rImage, Image, NULL );
+ DBG_ASSERT( nId, "ImageList::AddImage(): ImageId == 0" );
+ DBG_ASSERT( GetImagePos( nId ) == IMAGELIST_IMAGE_NOTFOUND,
+ "ImageList::AddImage() - ImageId already exists" );
+ DBG_ASSERT( rImage.mpImplData, "ImageList::AddImage(): Wrong Size" );
+ DBG_ASSERT( !mpImplData || (rImage.GetSizePixel() == mpImplData->maImageSize),
+ "ImageList::AddImage(): Wrong Size" );
+
+ ImageType eImageType = rImage.mpImplData->meType;
+ Size aImageSize = rImage.GetSizePixel();
+ USHORT nIndex;
+
+ if ( !mpImplData )
+ {
+ mpImplData = new ImplImageList;
+ mpImplData->mnRefCount = 1;
+ mpImplData->mnIRefCount = 0;
+ mpImplData->mnCount = 0;
+ mpImplData->mnRealCount = 0;
+ mpImplData->mnArySize = mnInitSize;
+ mpImplData->mpAry = new ImageAryData[mnInitSize];
+ mpImplData->maImageSize = aImageSize;
+ mpImplData->mpImageBitmap = new ImplImageBmp;
+ mpImplData->mpImageBitmap->Create( aImageSize.Width(), aImageSize.Height(),
+ mnInitSize );
+ memset( mpImplData->mpAry, 0, mpImplData->mnArySize*sizeof(ImageAryData) );
+ }
+ else
+ ImplCopyImageListData( this );
+
+ // Gegebenenfalls unser Array erweitern und freien Index ermitteln
+ if ( mpImplData->mnRealCount == mpImplData->mnArySize )
+ {
+ ImageAryData* pOldAry = mpImplData->mpAry;
+ USHORT nOldSize = mpImplData->mnArySize;
+
+ mpImplData->mnArySize += mnGrowSize;
+ mpImplData->mpAry = new ImageAryData[mpImplData->mnArySize];
+ memset( mpImplData->mpAry, 0, mpImplData->mnArySize*sizeof(ImageAryData) );
+ memcpy( mpImplData->mpAry, pOldAry, nOldSize*sizeof(ImageAryData) );
+ mpImplData->mpImageBitmap->Expand( mnGrowSize );
+ delete pOldAry;
+
+ nIndex = mpImplData->mnRealCount;
+ }
+ else
+ {
+ nIndex = 0;
+ while ( mpImplData->mpAry[nIndex].mnRefCount )
+ nIndex++;
+ }
+
+ // Image in Bitmap einfuegen
+ switch ( eImageType )
+ {
+ case IMAGETYPE_BITMAP:
+ mpImplData->mpImageBitmap->Replace( nIndex, *((Bitmap*)rImage.mpImplData->mpData) );
+ break;
+
+ case IMAGETYPE_IMAGE:
+ {
+ ImplImageData* pData = (ImplImageData*)rImage.mpImplData->mpData;
+ if ( pData->mpImageBitmap )
+ mpImplData->mpImageBitmap->Replace( nIndex, *(pData->mpImageBitmap), 0 );
+ else
+ {
+ if ( pData->mbColor )
+ mpImplData->mpImageBitmap->Replace( nIndex, pData->maBmp, pData->maColor );
+ else
+ mpImplData->mpImageBitmap->Replace( nIndex, pData->maBmp, pData->maMaskBmp );
+ }
+ }
+ break;
+
+ case IMAGETYPE_IMAGEREF:
+ {
+ ImplImageRefData* pData = (ImplImageRefData*)rImage.mpImplData->mpData;
+ mpImplData->mpImageBitmap->Replace( nIndex, *(pData->mpImplData->mpImageBitmap),
+ pData->mnIndex );
+ }
+ break;
+ }
+
+ // Array-Daten updaten
+ mpImplData->mnCount++;
+ mpImplData->mnRealCount++;
+ mpImplData->mpAry[nIndex].mnId = nId;
+ mpImplData->mpAry[nIndex].mnRefCount = 1;
+}
+
+// -----------------------------------------------------------------------
+
+void ImageList::CopyImage( USHORT nId, USHORT nCopyId )
+{
+ DBG_CHKTHIS( ImageList, NULL );
+ DBG_ASSERT( nId, "ImageList::CopyImage(): ImageId == 0" );
+ DBG_ASSERT( GetImagePos( nId ) == IMAGELIST_IMAGE_NOTFOUND,
+ "ImageList::CopyImage(): ImageId already exists" );
+ DBG_ASSERT( GetImagePos( nCopyId ) != IMAGELIST_IMAGE_NOTFOUND,
+ "ImageList::CopyImage(): Unknown nCopyId" );
+
+ USHORT nIndex;
+ USHORT nCopyIndex = 0;
+
+ // Index von CopyId holen
+ while ( nCopyIndex < mpImplData->mnArySize )
+ {
+ if ( mpImplData->mpAry[nCopyIndex].mnId == nCopyId )
+ break;
+
+ nCopyIndex++;
+ }
+ if ( nCopyIndex >= mpImplData->mnArySize )
+ return;
+
+ // Referenz-Counter ueberpruefen
+ ImplCopyImageListData( this );
+
+ // Gegebenenfalls unser Array erweitern
+ if ( mpImplData->mnRealCount == mpImplData->mnArySize )
+ {
+ ImageAryData* pOldAry = mpImplData->mpAry;
+ USHORT nOldSize = mpImplData->mnArySize;
+
+ mpImplData->mnArySize += mnGrowSize;
+ mpImplData->mpAry = new ImageAryData[mpImplData->mnArySize];
+ memset( mpImplData->mpAry, 0, mpImplData->mnArySize*sizeof(ImageAryData) );
+ memcpy( mpImplData->mpAry, pOldAry, nOldSize*sizeof(ImageAryData) );
+ mpImplData->mpImageBitmap->Expand( mnGrowSize );
+ delete pOldAry;
+
+ nIndex = mpImplData->mnRealCount;
+ }
+ else
+ {
+ nIndex = 0;
+ while ( mpImplData->mpAry[nIndex].mnRefCount )
+ nIndex++;
+ }
+
+ // Kopieren
+ mpImplData->mpImageBitmap->Replace( nIndex, *(mpImplData->mpImageBitmap), nCopyIndex );
+
+ // Array-Daten updaten
+ mpImplData->mnCount++;
+ mpImplData->mnRealCount++;
+ mpImplData->mpAry[nIndex].mnId = nId;
+ mpImplData->mpAry[nIndex].mnRefCount = 1;
+}
+
+// -----------------------------------------------------------------------
+
+void ImageList::ReplaceImage( USHORT nId, const Image& rImage )
+{
+ DBG_CHKTHIS( ImageList, NULL );
+ DBG_CHKOBJ( &rImage, Image, NULL );
+ DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND,
+ "ImageList::ReplaceImage(): Unknown nId" );
+
+ RemoveImage( nId );
+ AddImage( nId, rImage );
+}
+
+// -----------------------------------------------------------------------
+
+void ImageList::ReplaceImage( USHORT nId, USHORT nReplaceId )
+{
+ DBG_CHKTHIS( ImageList, NULL );
+ DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND,
+ "ImageList::ReplaceImage(): Unknown nId" );
+ DBG_ASSERT( GetImagePos( nReplaceId ) != IMAGELIST_IMAGE_NOTFOUND,
+ "ImageList::ReplaceImage(): Unknown nReplaceId" );
+
+ USHORT nPos1 = 0;
+ USHORT nPos2 = 0;
+
+ // Index von Id holen
+ while ( nPos1 < mpImplData->mnArySize )
+ {
+ if ( mpImplData->mpAry[nPos1].mnId == nId )
+ break;
+
+ nPos1++;
+ }
+ if ( nPos1 >= mpImplData->mnArySize )
+ return;
+
+ // Index von ReplaceId holen
+ while ( nPos2 < mpImplData->mnArySize )
+ {
+ if ( mpImplData->mpAry[nPos2].mnId == nReplaceId )
+ break;
+
+ nPos2++;
+ }
+ if ( nPos2 >= mpImplData->mnArySize )
+ return;
+
+ // Referenz-Counter ueberpruefen
+ ImplCopyImageListData( this );
+
+ // Ersetzen
+ mpImplData->mpImageBitmap->Replace( nPos1, nPos2 );
+}
+
+// -----------------------------------------------------------------------
+
+void ImageList::MergeImage( USHORT nId, USHORT nMergeId )
+{
+ DBG_CHKTHIS( ImageList, NULL );
+ DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND,
+ "ImageList::MergeImage(): Unknown nId" );
+ DBG_ASSERT( GetImagePos( nMergeId ) != IMAGELIST_IMAGE_NOTFOUND,
+ "ImageList::MergeImage(): Unknown nMergeId" );
+
+ USHORT nPos1 = 0;
+ USHORT nPos2 = 0;
+
+ // Index von Id holen
+ while ( nPos1 < mpImplData->mnArySize )
+ {
+ if ( mpImplData->mpAry[nPos1].mnId == nId )
+ break;
+
+ nPos1++;
+ }
+ if ( nPos1 >= mpImplData->mnArySize )
+ return;
+
+ // Index von MergeId holen
+ while ( nPos2 < mpImplData->mnArySize )
+ {
+ if ( mpImplData->mpAry[nPos2].mnId == nMergeId )
+ break;
+
+ nPos2++;
+ }
+ if ( nPos2 >= mpImplData->mnArySize )
+ return;
+
+ // Referenz-Counter ueberpruefen
+ ImplCopyImageListData( this );
+
+ // Ersetzen
+ mpImplData->mpImageBitmap->Merge( nPos1, nPos2 );
+}
+
+// -----------------------------------------------------------------------
+
+void ImageList::RemoveImage( USHORT nId )
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ if ( mpImplData )
+ {
+ ImplCopyImageListData( this );
+
+ USHORT i = 0;
+ while ( i < mpImplData->mnArySize )
+ {
+ if ( mpImplData->mpAry[i].mnId == nId )
+ break;
+
+ i++;
+ }
+
+ if ( i < mpImplData->mnArySize )
+ {
+ mpImplData->mpAry[i].mnRefCount--;
+ mpImplData->mpAry[i].mnId = 0;
+ if ( !mpImplData->mpAry[i].mnRefCount )
+ mpImplData->mnRealCount--;
+
+ mpImplData->mnCount--;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image ImageList::GetImage( USHORT nId ) const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ Image aImage;
+
+ if ( mpImplData )
+ {
+ USHORT i = 0;
+ while ( i < mpImplData->mnArySize )
+ {
+ if ( mpImplData->mpAry[i].mnId == nId )
+ break;
+
+ i++;
+ }
+
+ if ( i < mpImplData->mnArySize )
+ {
+ ImplImageRefData* mpData = new ImplImageRefData;
+
+ mpImplData->mnIRefCount++;
+ mpImplData->mpAry[i].mnRefCount++;
+ mpData->mpImplData = mpImplData;
+ mpData->mnIndex = i;
+
+ aImage.mpImplData = new ImplImage;
+ aImage.mpImplData->mnRefCount = 1;
+ aImage.mpImplData->meType = IMAGETYPE_IMAGEREF;
+ aImage.mpImplData->mpData = mpData;
+ }
+ }
+
+ return aImage;
+}
+
+// -----------------------------------------------------------------------
+
+void ImageList::Clear()
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ if ( mpImplData )
+ {
+ if ( mpImplData->mnRefCount > 1 )
+ mpImplData->mnRefCount--;
+ else
+ delete mpImplData;
+ }
+
+ mpImplData = 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImageList::GetImageCount() const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ if ( mpImplData )
+ return mpImplData->mnCount;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImageList::GetImagePos( USHORT nId ) const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ if ( mpImplData && nId )
+ {
+ USHORT nPos = 0;
+ USHORT i = 0;
+ while ( i < mpImplData->mnArySize )
+ {
+ if ( mpImplData->mpAry[i].mnId == nId )
+ return nPos;
+
+ if ( mpImplData->mpAry[i].mnId )
+ nPos++;
+ i++;
+ }
+ }
+
+ return IMAGELIST_IMAGE_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImageList::GetImageId( USHORT nPos ) const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ if ( mpImplData )
+ {
+ USHORT nRealPos = 0;
+ USHORT i = 0;
+ while ( i < mpImplData->mnArySize )
+ {
+ if ( (nPos == nRealPos) && (mpImplData->mpAry[i].mnId) )
+ return mpImplData->mpAry[i].mnId;
+
+ if ( mpImplData->mpAry[i].mnId )
+ nRealPos++;
+ i++;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Size ImageList::GetImageSize() const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ if ( mpImplData )
+ return mpImplData->maImageSize;
+ else
+ return Size();
+}
+
+// -----------------------------------------------------------------------
+
+Bitmap ImageList::GetBitmap() const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ Bitmap aBmp;
+
+ if ( mpImplData )
+ {
+ // Positionen ermitteln, die in der Bitmap enthalten sein sollen
+ USHORT* mpPosAry = new USHORT[mpImplData->mnCount];
+ USHORT nPosCount = 0;
+ for ( USHORT i = 0; i < mpImplData->mnArySize; i++ )
+ {
+ if ( mpImplData->mpAry[i].mnId )
+ {
+ mpPosAry[nPosCount] = i;
+ nPosCount++;
+ }
+ }
+
+ // Bitmap besorgen
+ aBmp = mpImplData->mpImageBitmap->GetBitmap( nPosCount, mpPosAry );
+
+ // Temporaeres Array loeschen
+ delete mpPosAry;
+ }
+
+ return aBmp;
+}
+
+// -----------------------------------------------------------------------
+
+Bitmap ImageList::GetMaskBitmap() const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ Bitmap aBmp;
+
+ if ( HasMaskBitmap() )
+ {
+ // Positionen ermitteln, die in der Bitmap enthalten sein sollen
+ USHORT* mpPosAry = new USHORT[mpImplData->mnCount];
+ USHORT nPosCount = 0;
+ for ( USHORT i = 0; i < mpImplData->mnArySize; i++ )
+ {
+ if ( mpImplData->mpAry[i].mnId )
+ {
+ mpPosAry[nPosCount] = i;
+ nPosCount++;
+ }
+ }
+
+ // Bitmap besorgen
+ aBmp = mpImplData->mpImageBitmap->GetMaskBitmap( nPosCount, mpPosAry );
+
+ // Temporaeres Array loeschen
+ delete mpPosAry;
+ }
+
+ return aBmp;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImageList::HasMaskBitmap() const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ if ( mpImplData )
+ return mpImplData->mpImageBitmap->HasMaskBitmap();
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Color ImageList::GetMaskColor() const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ Color aColor;
+
+ if ( HasMaskColor() )
+ aColor = mpImplData->mpImageBitmap->GetMaskColor();
+
+ return aColor;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImageList::HasMaskColor() const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+
+ if ( mpImplData )
+ return mpImplData->mpImageBitmap->HasMaskColor();
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ImageList& ImageList::operator=( const ImageList& rImageList )
+{
+ DBG_CHKTHIS( ImageList, NULL );
+ DBG_CHKOBJ( &rImageList, ImageList, NULL );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ if ( rImageList.mpImplData )
+ rImageList.mpImplData->mnRefCount++;
+
+ // Abkoppeln
+ if ( mpImplData )
+ {
+ mpImplData->mnRefCount--;
+ if ( !mpImplData->mnRefCount && !mpImplData->mnIRefCount )
+ delete mpImplData;
+ }
+
+ // Neue Daten zuweisen
+ mpImplData = rImageList.mpImplData;
+ mnInitSize = rImageList.mnInitSize;
+ mnGrowSize = rImageList.mnGrowSize;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImageList::operator==( const ImageList& rImageList ) const
+{
+ DBG_CHKTHIS( ImageList, NULL );
+ DBG_CHKOBJ( &rImageList, ImageList, NULL );
+
+ if ( rImageList.mpImplData == mpImplData )
+ return TRUE;
+ if ( !rImageList.mpImplData || !mpImplData )
+ return FALSE;
+
+ if ( (rImageList.mpImplData->mnCount == mpImplData->mnCount) &&
+ (rImageList.mpImplData->maImageSize == mpImplData->maImageSize) )
+ return TRUE;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, ImageList& rImageList )
+{
+ DBG_CHKOBJ( &rImageList, ImageList, NULL );
+
+ // Falls es eine bestehende ImageListe ist, dann erst abkoppeln
+ if ( rImageList.mpImplData )
+ {
+ rImageList.mpImplData->mnRefCount--;
+ if ( !rImageList.mpImplData->mnRefCount && !rImageList.mpImplData->mnIRefCount )
+ delete rImageList.mpImplData;
+ }
+ rImageList.mpImplData = NULL;
+
+ // Daten lesen
+ USHORT nVersion;
+ Size aImageSize;
+ BOOL bImageList;
+ rIStream >> nVersion;
+ rIStream >> rImageList.mnInitSize;
+ rIStream >> rImageList.mnGrowSize;
+ rIStream >> bImageList;
+
+ // Wenn es eine leere ImageListe ist, dann brauchen wir nicht weiter lesen
+ if ( !bImageList )
+ return rIStream;
+
+ // Image-Groesse lesen
+ rIStream >> aImageSize.Width();
+ rIStream >> aImageSize.Height();
+
+ // Image-Daten anlegen und initialisieren
+ rImageList.mpImplData = new ImplImageList;
+ rImageList.mpImplData->mnRefCount = 1;
+ rImageList.mpImplData->mnIRefCount = 0;
+ rImageList.mpImplData->mnCount = rImageList.mnInitSize;
+ rImageList.mpImplData->mnRealCount = rImageList.mnInitSize;
+ rImageList.mpImplData->mnArySize = rImageList.mnInitSize;
+ rImageList.mpImplData->mpAry = new ImageAryData[rImageList.mnInitSize];
+ rImageList.mpImplData->maImageSize = aImageSize;
+
+ // Array mit ID's lesen und initialisieren
+ for ( USHORT i = 0; i < rImageList.mnInitSize; i++ )
+ {
+ rIStream >> rImageList.mpImplData->mpAry[i].mnId;
+ rImageList.mpImplData->mpAry[i].mnRefCount = 1;
+ }
+
+ // Bitmaps lesen
+ Bitmap aBitmap;
+ Bitmap aMaskBitmap;
+ Color aMaskColor;
+ BYTE bMaskBitmap;
+ BYTE bMaskColor;
+ rIStream >> aBitmap;
+ rIStream >> bMaskBitmap;
+ if ( bMaskBitmap )
+ rIStream >> aMaskBitmap;
+ rIStream >> bMaskColor;
+ if ( bMaskColor )
+ rIStream >> aMaskColor;
+
+ // Systemdaten anlegen
+ rImageList.mpImplData->mpImageBitmap = new ImplImageBmp;
+ rImageList.mpImplData->mpImageBitmap->Create( aBitmap, aMaskBitmap,
+ aMaskColor, bMaskColor,
+ aImageSize.Width(),
+ aImageSize.Height(),
+ rImageList.mnInitSize );
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const ImageList& rImageList )
+{
+ DBG_CHKOBJ( &rImageList, ImageList, NULL );
+
+ BOOL bImageList = (rImageList.mpImplData) ? TRUE : FALSE;
+
+ USHORT nVersion = IMAGE_FILE_VERSION;
+ rOStream << nVersion;
+
+ // Wenn es eine leere ImageListe ist, dann nur InitSize und
+ // GrowSize schreiben
+ if ( !bImageList || !rImageList.mpImplData->mnCount )
+ {
+ BOOL bSaveImageList = FALSE;
+ rOStream << rImageList.mnInitSize;
+ rOStream << rImageList.mnGrowSize;
+ rOStream << bSaveImageList;
+ return rOStream;
+ }
+
+ // Normale Daten schreiben
+ rOStream << rImageList.mpImplData->mnCount;
+ rOStream << rImageList.mnGrowSize;
+ rOStream << bImageList;
+ rOStream << rImageList.mpImplData->maImageSize.Width();
+ rOStream << rImageList.mpImplData->maImageSize.Height();
+
+ // Array schreiben und feststellen, welche Eintraege gespeichert werden
+ // muessen
+ USHORT* mpPosAry = new USHORT[rImageList.mpImplData->mnCount];
+ USHORT nPosCount = 0;
+ for ( USHORT i = 0; i < rImageList.mpImplData->mnArySize; i++ )
+ {
+ if ( rImageList.mpImplData->mpAry[i].mnId )
+ {
+ rOStream << rImageList.mpImplData->mpAry[i].mnId;
+ mpPosAry[nPosCount] = i;
+ nPosCount++;
+ }
+ }
+
+ // Bitmaps rausschreiben
+ Bitmap aBmp;
+ BYTE bMaskBitmap = (BYTE)rImageList.mpImplData->mpImageBitmap->HasMaskBitmap();
+ BYTE bMaskColor = (BYTE)rImageList.mpImplData->mpImageBitmap->HasMaskColor();
+ aBmp = rImageList.mpImplData->mpImageBitmap->GetBitmap( nPosCount, mpPosAry );
+ rOStream << aBmp;
+ rOStream << bMaskBitmap;
+ if ( bMaskBitmap )
+ {
+ aBmp = rImageList.mpImplData->mpImageBitmap->GetMaskBitmap( nPosCount, mpPosAry );
+ rOStream << aBmp;
+ }
+ rOStream << bMaskColor;
+ if ( bMaskColor )
+ {
+ Color aColor = rImageList.mpImplData->mpImageBitmap->GetMaskColor();
+ rOStream << aColor;
+ }
+
+ // Temporaeres Array loeschen
+ delete mpPosAry;
+
+ return rOStream;
+}
+
+// =======================================================================
+
+void OutputDevice::DrawImage( const Point& rPos, const Image& rImage,
+ USHORT nStyle )
+{
+ DBG_CHKOBJ( &rImage, Image, NULL );
+ DBG_ASSERT( GetOutDevType() != OUTDEV_PRINTER,
+ "DrawImage(): Images can't be drawn on any mprinter" );
+
+ if( !rImage.mpImplData )
+ return;
+
+ switch( rImage.mpImplData->meType )
+ {
+ case IMAGETYPE_BITMAP:
+ {
+ DrawBitmap( rPos, *((Bitmap*)rImage.mpImplData->mpData) );
+ }
+ break;
+
+ case IMAGETYPE_IMAGE:
+ {
+ ImplImageData* pData = (ImplImageData*)rImage.mpImplData->mpData;
+
+ if ( !pData->mpImageBitmap )
+ {
+ Size aSize = pData->maBmp.GetSizePixel();
+ pData->mpImageBitmap = new ImplImageBmp;
+ pData->mpImageBitmap->Create( pData->maBmp, pData->maMaskBmp,
+ pData->maColor, pData->mbColor,
+ aSize.Width(), aSize.Height(),
+ 1 );
+ }
+
+ pData->mpImageBitmap->Draw( 0, this, rPos, nStyle );
+ }
+ break;
+
+ case IMAGETYPE_IMAGEREF:
+ {
+ ImplImageRefData* pData = (ImplImageRefData*)rImage.mpImplData->mpData;
+ pData->mpImplData->mpImageBitmap->Draw( pData->mnIndex, this, rPos, nStyle );
+ }
+ break;
+ }
+}
+
+// =======================================================================
+
+void OutputDevice::DrawImage( const Point& rPos, const Size& rSize,
+ const Image& rImage, USHORT nStyle )
+{
+ DBG_CHKOBJ( &rImage, Image, NULL );
+ DBG_ASSERT( GetOutDevType() != OUTDEV_PRINTER,
+ "DrawImage(): Images can't be drawn on any mprinter" );
+
+ if( !rImage.mpImplData )
+ return;
+
+ switch( rImage.mpImplData->meType )
+ {
+ case IMAGETYPE_BITMAP:
+ {
+ DrawBitmap( rPos, rSize, *((Bitmap*)rImage.mpImplData->mpData) );
+ }
+ break;
+
+ case IMAGETYPE_IMAGE:
+ {
+ ImplImageData* pData = (ImplImageData*)rImage.mpImplData->mpData;
+
+ if ( !pData->mpImageBitmap )
+ {
+ Size aSize = pData->maBmp.GetSizePixel();
+ pData->mpImageBitmap = new ImplImageBmp;
+ pData->mpImageBitmap->Create( pData->maBmp, pData->maMaskBmp,
+ pData->maColor, pData->mbColor,
+ aSize.Width(), aSize.Height(),
+ 1 );
+ }
+
+ pData->mpImageBitmap->Draw( 0, this, rPos, nStyle, &rSize );
+ }
+ break;
+
+ case IMAGETYPE_IMAGEREF:
+ {
+ ImplImageRefData* pData = (ImplImageRefData*)rImage.mpImplData->mpData;
+ pData->mpImplData->mpImageBitmap->Draw( pData->mnIndex, this, rPos, nStyle, &rSize );
+ }
+ break;
+ }
+}
diff --git a/vcl/source/gdi/imgcons.cxx b/vcl/source/gdi/imgcons.cxx
new file mode 100644
index 000000000000..d20f9c26f1c9
--- /dev/null
+++ b/vcl/source/gdi/imgcons.cxx
@@ -0,0 +1,593 @@
+/*************************************************************************
+ *
+ * $RCSfile: imgcons.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <bmpacc.hxx>
+#include <bitmapex.hxx>
+#include <image.hxx>
+#include <imgcons.hxx>
+
+// -------------------
+// - ImplColorMapper -
+// -------------------
+
+class ImplColorMapper
+{
+ Color maCol;
+ ULONG mnR;
+ ULONG mnG;
+ ULONG mnB;
+ ULONG mnT;
+ ULONG mnRShift;
+ ULONG mnGShift;
+ ULONG mnBShift;
+ ULONG mnTShift;
+
+ ULONG ImplCalcMaskShift( ULONG nVal );
+
+public:
+
+ ImplColorMapper( ULONG nRMask, ULONG nGMask, ULONG nBMask, ULONG nTMask );
+ ~ImplColorMapper();
+
+ const Color& ImplGetColor( ULONG nColor )
+ {
+ maCol.SetRed( (UINT8) ( ( nColor & mnR ) >> mnRShift ) );
+ maCol.SetGreen( (UINT8) ( ( nColor & mnG ) >> mnGShift ) );
+ maCol.SetBlue( (UINT8) ( ( nColor & mnB ) >> mnBShift ) );
+ maCol.SetTransparency( (UINT8) ( ( nColor & mnT ) >> mnTShift ) );
+ return maCol;
+ }
+};
+
+// -----------------------------------------------------------------------------
+
+ImplColorMapper::ImplColorMapper( ULONG nRMask, ULONG nGMask, ULONG nBMask, ULONG nTMask ) :
+ mnR( nRMask ),
+ mnG( nGMask ),
+ mnB( nBMask ),
+ mnT( nTMask )
+{
+ mnRShift = ImplCalcMaskShift( mnR );
+ mnGShift = ImplCalcMaskShift( mnG );
+ mnBShift = ImplCalcMaskShift( mnB );
+ mnTShift = ImplCalcMaskShift( mnT );
+}
+
+// -----------------------------------------------------------------------------
+
+ImplColorMapper::~ImplColorMapper()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG ImplColorMapper::ImplCalcMaskShift( ULONG nVal )
+{
+ DBG_ASSERT( nVal > 0, "Mask has no value!" );
+
+ ULONG nRet = 0UL;
+
+ for( ULONG i = 0UL; i < 32; i++ )
+ {
+ if( nVal & ( 1UL << i ) )
+ {
+ nRet = i;
+ break;
+ }
+ }
+
+ return nRet;
+}
+
+// -----------------
+// - ImageConsumer -
+// -----------------
+
+ImageConsumer::ImageConsumer() :
+ mnStatus( 0UL ),
+ mpPal ( NULL ),
+ mpMapper( NULL ),
+ mbTrans ( FALSE )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ImageConsumer::~ImageConsumer()
+{
+ delete[] mpPal;
+ delete mpMapper;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImageConsumer::Init( ULONG nWidth, ULONG nHeight )
+{
+ maSize = Size( nWidth, nHeight );
+ maBitmap = maMask = Bitmap();
+ mnStatus = 0UL;
+ mbTrans = FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImageConsumer::SetColorModel( USHORT nBitCount,
+ ULONG nPalEntries, const ULONG* pRGBAPal,
+ ULONG nRMask, ULONG nGMask, ULONG nBMask, ULONG nAMask )
+{
+ DBG_ASSERT( maSize.Width() && maSize.Height(), "Missing call to ImageConsumer::Init(...)!" );
+
+ BitmapPalette aPal( Min( (USHORT) nPalEntries, (USHORT) 256 ) );
+
+ if( nPalEntries )
+ {
+ BitmapColor aCol;
+ const ULONG* pTmp = pRGBAPal;
+
+ delete mpMapper;
+ mpMapper = NULL;
+
+ delete[] mpPal;
+ mpPal = new Color[ nPalEntries ];
+
+ for( ULONG i = 0; i < nPalEntries; i++, pTmp++ )
+ {
+ Color& rCol = mpPal[ i ];
+ BYTE cVal;
+
+ cVal = (BYTE) ( ( *pTmp & 0xff000000UL ) >> 24UL );
+ rCol.SetRed( cVal );
+ if( i < 256UL )
+ aPal[ (USHORT) i ].SetRed( cVal );
+
+ cVal = (BYTE) ( ( *pTmp & 0x00ff0000UL ) >> 16UL );
+ rCol.SetGreen( cVal );
+ if( i < 256UL )
+ aPal[ (USHORT) i ].SetGreen( cVal );
+
+ cVal = (BYTE) ( ( *pTmp & 0x0000ff00UL ) >> 8UL );
+ rCol.SetBlue( cVal );
+ if( i < 256UL )
+ aPal[ (USHORT) i ].SetBlue( cVal );
+
+ rCol.SetTransparency( (BYTE) ( ( *pTmp & 0x000000ffUL ) ) );
+ }
+
+ if( nBitCount <= 1 )
+ nBitCount = 1;
+ else if( nBitCount <= 4 )
+ nBitCount = 4;
+ else if( nBitCount <= 8 )
+ nBitCount = 8;
+ else
+ nBitCount = 24;
+ }
+ else
+ {
+ delete mpMapper;
+ mpMapper = new ImplColorMapper( nRMask, nGMask, nBMask, nAMask );
+
+ delete[] mpPal;
+ mpPal = NULL;
+
+ nBitCount = 24;
+ }
+
+ if( !maBitmap )
+ {
+
+ maBitmap = Bitmap( maSize, nBitCount, &aPal );
+ maMask = Bitmap( maSize, 1 );
+ maMask.Erase( COL_BLACK );
+ mbTrans = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void ImageConsumer::SetPixelsByBytes( ULONG nConsX, ULONG nConsY,
+ ULONG nConsWidth, ULONG nConsHeight,
+ const BYTE* pData, ULONG nOffset, ULONG nScanSize )
+{
+ DBG_ASSERT( !!maBitmap && !!maMask, "Missing call to ImageConsumer::SetColorModel(...)!" );
+
+ BitmapWriteAccess* pBmpAcc = maBitmap.AcquireWriteAccess();
+ BitmapWriteAccess* pMskAcc = maMask.AcquireWriteAccess();
+
+ if( pBmpAcc && pMskAcc )
+ {
+ const long nWidth = pBmpAcc->Width();
+ const long nHeight = pBmpAcc->Height();
+
+ maChangedRect = Rectangle( Point(), Size( nWidth, nHeight ) );
+ maChangedRect.Intersection( Rectangle( Point( nConsX, nConsY ), Size( nConsWidth, nConsHeight ) ) );
+
+ if( !maChangedRect.IsEmpty() )
+ {
+ const long nStartX = maChangedRect.Left();
+ const long nEndX = maChangedRect.Right();
+ const long nStartY = maChangedRect.Top();
+ const long nEndY = maChangedRect.Bottom();
+
+ if( mpMapper && ( pBmpAcc->GetBitCount() > 8 ) )
+ {
+ BitmapColor aCol;
+ BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ {
+ const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset;
+
+ for( long nX = nStartX; nX <= nEndX; nX++ )
+ {
+ const Color& rCol = mpMapper->ImplGetColor( *pTmp++ );
+
+ // 0: Transparent; >0: Non-Transparent
+ if( !rCol.GetTransparency() )
+ {
+ pMskAcc->SetPixel( nY, nX, aMskWhite );
+ mbTrans = TRUE;
+ }
+ else
+ {
+ aCol.SetRed( rCol.GetRed() );
+ aCol.SetGreen( rCol.GetGreen() );
+ aCol.SetBlue( rCol.GetBlue() );
+ pBmpAcc->SetPixel( nY, nX, aCol );
+ }
+ }
+ }
+
+ DataChanged();
+ }
+ else if( mpPal && ( pBmpAcc->GetBitCount() <= 8 ) )
+ {
+ BitmapColor aIndex( (BYTE) 0 );
+ BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ {
+ const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset;
+
+ for( long nX = nStartX; nX <= nEndX; nX++ )
+ {
+ const BYTE cIndex = *pTmp++;
+ const Color& rCol = mpPal[ cIndex ];
+
+ // 0: Transparent; >0: Non-Transparent
+ if( !rCol.GetTransparency() )
+ {
+ pMskAcc->SetPixel( nY, nX, aMskWhite );
+ mbTrans = TRUE;
+ }
+ else
+ {
+ aIndex.SetIndex( cIndex );
+ pBmpAcc->SetPixel( nY, nX, aIndex );
+ }
+ }
+ }
+
+ DataChanged();
+ }
+ else if( mpPal && ( pBmpAcc->GetBitCount() > 8 ) )
+ {
+ BitmapColor aCol;
+ BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ {
+ const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset;
+
+ for( long nX = nStartX; nX <= nEndX; nX++ )
+ {
+ const BYTE cIndex = *pTmp++;
+ const Color& rCol = mpPal[ cIndex ];
+
+ // 0: Transparent; >0: Non-Transparent
+ if( !rCol.GetTransparency() )
+ {
+ pMskAcc->SetPixel( nY, nX, aMskWhite );
+ mbTrans = TRUE;
+ }
+ else
+ {
+ aCol.SetRed( rCol.GetRed() );
+ aCol.SetGreen( rCol.GetGreen() );
+ aCol.SetBlue( rCol.GetBlue() );
+ pBmpAcc->SetPixel( nY, nX, aCol );
+ }
+ }
+ }
+
+ DataChanged();
+ }
+ else
+ {
+ DBG_ERROR( "Producer format error!" );
+ maChangedRect.SetEmpty();
+ }
+ }
+ }
+ else
+ maChangedRect.SetEmpty();
+
+ maBitmap.ReleaseAccess( pBmpAcc );
+ maMask.ReleaseAccess( pMskAcc );
+}
+
+// -----------------------------------------------------------------------------
+
+void ImageConsumer::SetPixelsByLongs( ULONG nConsX, ULONG nConsY,
+ ULONG nConsWidth, ULONG nConsHeight,
+ const ULONG* pData, ULONG nOffset, ULONG nScanSize )
+{
+ DBG_ASSERT( !!maBitmap && !!maMask, "Missing call to ImageConsumer::SetColorModel(...)!" );
+
+ BitmapWriteAccess* pBmpAcc = maBitmap.AcquireWriteAccess();
+ BitmapWriteAccess* pMskAcc = maMask.AcquireWriteAccess();
+
+ if( pBmpAcc && pMskAcc )
+ {
+ const long nWidth = pBmpAcc->Width();
+ const long nHeight = pBmpAcc->Height();
+
+ maChangedRect = Rectangle( Point(), Size( nWidth, nHeight ) );
+ maChangedRect.Intersection( Rectangle( Point( nConsX, nConsY ), Size( nConsWidth, nConsHeight ) ) );
+
+ if( !maChangedRect.IsEmpty() )
+ {
+ const long nStartX = maChangedRect.Left();
+ const long nEndX = maChangedRect.Right();
+ const long nStartY = maChangedRect.Top();
+ const long nEndY = maChangedRect.Bottom();
+
+ if( mpMapper && ( pBmpAcc->GetBitCount() > 8 ) )
+ {
+ BitmapColor aCol;
+ BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ {
+ const ULONG* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset;
+
+ for( long nX = nStartX; nX <= nEndX; nX++ )
+ {
+ const Color& rCol = mpMapper->ImplGetColor( *pTmp++ );
+
+ // 0: Transparent; >0: Non-Transparent
+ if( !rCol.GetTransparency() )
+ {
+ pMskAcc->SetPixel( nY, nX, aMskWhite );
+ mbTrans = TRUE;
+ }
+ else
+ {
+ aCol.SetRed( rCol.GetRed() );
+ aCol.SetGreen( rCol.GetGreen() );
+ aCol.SetBlue( rCol.GetBlue() );
+ pBmpAcc->SetPixel( nY, nX, aCol );
+ }
+ }
+ }
+
+ DataChanged();
+ }
+ else if( mpPal && ( pBmpAcc->GetBitCount() <= 8 ) )
+ {
+ BitmapColor aIndex( (BYTE) 0 );
+ BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ {
+ const ULONG* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset;
+
+ for( long nX = nStartX; nX <= nEndX; nX++ )
+ {
+ const ULONG nIndex = *pTmp++;
+ const Color& rCol = mpPal[ nIndex ];
+
+ // 0: Transparent; >0: Non-Transparent
+ if( !rCol.GetTransparency() )
+ {
+ pMskAcc->SetPixel( nY, nX, aMskWhite );
+ mbTrans = TRUE;
+ }
+ else
+ {
+ aIndex.SetIndex( (BYTE) nIndex );
+ pBmpAcc->SetPixel( nY, nX, aIndex );
+ }
+ }
+ }
+
+ DataChanged();
+ }
+ else if( mpPal && ( pBmpAcc->GetBitCount() > 8 ) )
+ {
+ BitmapColor aCol;
+ BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
+
+ for( long nY = nStartY; nY <= nEndY; nY++ )
+ {
+ const ULONG* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset;
+
+ for( long nX = nStartX; nX <= nEndX; nX++ )
+ {
+ const ULONG nIndex = *pTmp++;
+ const Color& rCol = mpPal[ nIndex ];
+
+ // 0: Transparent; >0: Non-Transparent
+ if( !rCol.GetTransparency() )
+ {
+ pMskAcc->SetPixel( nY, nX, aMskWhite );
+ mbTrans = TRUE;
+ }
+ else
+ {
+ aCol.SetRed( rCol.GetRed() );
+ aCol.SetGreen( rCol.GetGreen() );
+ aCol.SetBlue( rCol.GetBlue() );
+ pBmpAcc->SetPixel( nY, nX, aCol );
+ }
+ }
+ }
+
+ DataChanged();
+ }
+ else
+ {
+ DBG_ERROR( "Producer format error!" );
+ maChangedRect.SetEmpty();
+ }
+ }
+ }
+ else
+ maChangedRect.SetEmpty();
+
+ maBitmap.ReleaseAccess( pBmpAcc );
+ maMask.ReleaseAccess( pMskAcc );
+}
+
+// -----------------------------------------------------------------------------
+
+void ImageConsumer::Completed( ULONG nStatus /*, ImageProducer& rProducer */ )
+{
+ delete mpMapper;
+ mpMapper = NULL;
+ delete[] mpPal;
+ mpPal = NULL;
+ maSize = Size();
+ mnStatus = nStatus;
+
+ switch( nStatus )
+ {
+ case( SINGLEFRAMEDONE ):
+ case( STATICIMAGEDONE ):
+ {
+ if( !mbTrans )
+ maMask = Bitmap();
+ }
+ break;
+
+ case( IMAGEERROR ):
+ case( IMAGEABORTED ):
+ maBitmap = maMask = Bitmap();
+ break;
+
+ default:
+ break;
+ }
+
+// rProducer.RemoveConsumer( *this );
+
+ if( maDoneLink.IsSet() )
+ maDoneLink.Call( this );
+}
+
+// -----------------------------------------------------------------------------
+
+void ImageConsumer::DataChanged()
+{
+ if( maChgLink.IsSet() )
+ maChgLink.Call( this );
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG ImageConsumer::GetStatus() const
+{
+ return mnStatus;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ImageConsumer::GetData( BitmapEx& rBmpEx ) const
+{
+ const BOOL bRet = ( SINGLEFRAMEDONE == mnStatus || STATICIMAGEDONE == mnStatus );
+
+ if( bRet )
+ {
+ if( !!maMask )
+ rBmpEx = BitmapEx( maBitmap, maMask );
+ else
+ rBmpEx = BitmapEx( maBitmap );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ImageConsumer::GetData( Image& rImage ) const
+{
+ const BOOL bRet = ( SINGLEFRAMEDONE == mnStatus || STATICIMAGEDONE == mnStatus );
+
+ if( bRet )
+ {
+ if( !!maMask )
+ rImage = Image( maBitmap, maMask );
+ else
+ rImage = Image( maBitmap );
+ }
+
+ return bRet;
+}
diff --git a/vcl/source/gdi/impanmvw.cxx b/vcl/source/gdi/impanmvw.cxx
new file mode 100644
index 000000000000..fc3a943c0471
--- /dev/null
+++ b/vcl/source/gdi/impanmvw.cxx
@@ -0,0 +1,392 @@
+/*************************************************************************
+ *
+ * $RCSfile: impanmvw.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_IMPANMVW_CXX
+
+#define private public
+
+#include "impanmvw.hxx"
+#include "virdev.hxx"
+#include "window.hxx"
+#include "salbtype.hxx"
+
+// ----------------
+// - ImplAnimView -
+// ----------------
+
+ImplAnimView::ImplAnimView( Animation* pParent, OutputDevice* pOut,
+ const Point& rPt, const Size& rSz,
+ ULONG nExtraData,
+ OutputDevice* pFirstFrameOutDev ) :
+ mpParent ( pParent ),
+ mpOut ( pFirstFrameOutDev ? pFirstFrameOutDev : pOut ),
+ maPt ( rPt ),
+ maSz ( rSz ),
+ maClip ( mpOut->GetClipRegion() ),
+ maSzPix ( mpOut->LogicToPixel( maSz ) ),
+ mnExtraData ( nExtraData ),
+ mpBackground ( new VirtualDevice ),
+ mpRestore ( new VirtualDevice ),
+ meLastDisposal ( DISPOSE_BACK ),
+ mbPause ( FALSE ),
+ mbMarked ( FALSE ),
+ mbHMirr ( maSz.Width() < 0L ),
+ mbVMirr ( maSz.Height() < 0L )
+{
+ mpParent->ImplIncAnimCount();
+
+ // mirrored horizontically?
+ if( mbHMirr )
+ {
+ maDispPt.X() = maPt.X() + maSz.Width() + 1L;
+ maDispSz.Width() = -maSz.Width();
+ maSzPix.Width() = -maSzPix.Width();
+ }
+ else
+ {
+ maDispPt.X() = maPt.X();
+ maDispSz.Width() = maSz.Width();
+ }
+
+ // mirrored vertically?
+ if( mbVMirr )
+ {
+ maDispPt.Y() = maPt.Y() + maSz.Height() + 1L;
+ maDispSz.Height() = -maSz.Height();
+ maSzPix.Height() = -maSzPix.Height();
+ }
+ else
+ {
+ maDispPt.Y() = maPt.Y();
+ maDispSz.Height() = maSz.Height();
+ }
+
+ // save background
+ mpBackground->SetOutputSizePixel( maSzPix );
+
+ if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
+ {
+ MapMode aTempMap( mpOut->GetMapMode() );
+ aTempMap.SetOrigin( Point() );
+ mpBackground->SetMapMode( aTempMap );
+ ( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
+ mpBackground->SetMapMode( MapMode() );
+ }
+ else
+ mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
+
+ // initial drawing to actual position
+ ImplDrawToPos( mpParent->ImplGetCurPos() );
+
+ // if first frame OutputDevice is set, update variables now for real OutputDevice
+ if( pFirstFrameOutDev )
+ maClip = ( mpOut = pOut )->GetClipRegion();
+}
+
+// ------------------------------------------------------------------------
+
+ImplAnimView::~ImplAnimView()
+{
+ delete mpBackground;
+ delete mpRestore;
+
+ mpParent->ImplDecAnimCount();
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImplAnimView::ImplMatches( OutputDevice* pOut, long nExtraData ) const
+{
+ BOOL bRet = FALSE;
+
+ if( nExtraData )
+ {
+ if( ( mnExtraData == nExtraData ) && ( !pOut || ( pOut == mpOut ) ) )
+ bRet = TRUE;
+ }
+ else if( !pOut || ( pOut == mpOut ) )
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplAnimView::ImplGetPosSize( const AnimationBitmap& rAnm, Point& rPosPix, Size& rSizePix )
+{
+ const Size& rAnmSize = mpParent->GetDisplaySizePixel();
+ Point aPt2( rAnm.aPosPix.X() + rAnm.aSizePix.Width() - 1L,
+ rAnm.aPosPix.Y() + rAnm.aSizePix.Height() - 1L );
+ double fFactX, fFactY;
+
+ // calculate x scaling
+ if( rAnmSize.Width() > 1L )
+ fFactX = (double) ( maSzPix.Width() - 1L ) / ( rAnmSize.Width() - 1L );
+ else
+ fFactX = 1.0;
+
+ // calculate y scaling
+ if( rAnmSize.Height() > 1L )
+ fFactY = (double) ( maSzPix.Height() - 1L ) / ( rAnmSize.Height() - 1L );
+ else
+ fFactY = 1.0;
+
+ rPosPix.X() = FRound( rAnm.aPosPix.X() * fFactX );
+ rPosPix.Y() = FRound( rAnm.aPosPix.Y() * fFactY );
+
+ aPt2.X() = FRound( aPt2.X() * fFactX );
+ aPt2.Y() = FRound( aPt2.Y() * fFactY );
+
+ rSizePix.Width() = aPt2.X() - rPosPix.X() + 1L;
+ rSizePix.Height() = aPt2.Y() - rPosPix.Y() + 1L;
+
+ // mirrored horizontically?
+ if( mbHMirr )
+ rPosPix.X() = maSzPix.Width() - 1L - aPt2.X();
+
+ // mirrored vertically?
+ if( mbVMirr )
+ rPosPix.Y() = maSzPix.Height() - 1L - aPt2.Y();
+}
+
+// ------------------------------------------------------------------------
+
+void ImplAnimView::ImplDrawToPos( ULONG nPos )
+{
+ VirtualDevice aVDev;
+ Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
+
+ aVDev.SetOutputSizePixel( maSzPix, FALSE );
+ nPos = Min( nPos, (ULONG) mpParent->Count() - 1UL );
+
+ for( ULONG i = 0UL; i <= nPos; i++ )
+ ImplDraw( i, &aVDev );
+
+ if( pOldClip )
+ mpOut->SetClipRegion( maClip );
+
+ mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, aVDev );
+
+ if( pOldClip )
+ {
+ mpOut->SetClipRegion( *pOldClip );
+ delete pOldClip;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ImplAnimView::ImplDraw( ULONG nPos )
+{
+ ImplDraw( nPos, NULL );
+}
+
+// ------------------------------------------------------------------------
+
+void ImplAnimView::ImplDraw( ULONG nPos, VirtualDevice* pVDev )
+{
+ Rectangle aOutRect( mpOut->PixelToLogic( Point() ), mpOut->GetOutputSize() );
+
+ // check, if output lies out of display
+ if( aOutRect.Intersection( Rectangle( maDispPt, maDispSz ) ).IsEmpty() )
+ ImplSetMarked( TRUE );
+ else if( !mbPause )
+ {
+ VirtualDevice* pDev;
+ Point aPosPix;
+ Point aBmpPosPix;
+ Size aSizePix;
+ Size aBmpSizePix;
+ const ULONG nLastPos = mpParent->Count() - 1;
+ const AnimationBitmap& rAnm = mpParent->Get( (USHORT) ( mnActPos = Min( nPos, nLastPos ) ) );
+
+ ImplGetPosSize( rAnm, aPosPix, aSizePix );
+
+ // mirrored horizontically?
+ if( mbHMirr )
+ {
+ aBmpPosPix.X() = aPosPix.X() + aSizePix.Width() - 1L;
+ aBmpSizePix.Width() = -aSizePix.Width();
+ }
+ else
+ {
+ aBmpPosPix.X() = aPosPix.X();
+ aBmpSizePix.Width() = aSizePix.Width();
+ }
+
+ // mirrored vertically?
+ if( mbVMirr )
+ {
+ aBmpPosPix.Y() = aPosPix.Y() + aSizePix.Height() - 1L;
+ aBmpSizePix.Height() = -aSizePix.Height();
+ }
+ else
+ {
+ aBmpPosPix.Y() = aPosPix.Y();
+ aBmpSizePix.Height() = aSizePix.Height();
+ }
+
+ // get output device
+ if( !pVDev )
+ {
+ pDev = new VirtualDevice;
+ pDev->SetOutputSizePixel( maSzPix, FALSE );
+ pDev->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
+ }
+ else
+ pDev = pVDev;
+
+ // restore background after each run
+ if( !nPos )
+ {
+ meLastDisposal = DISPOSE_BACK;
+ maRestPt = Point();
+ maRestSz = maSzPix;
+ }
+
+ // restore
+ if( ( DISPOSE_NOT != meLastDisposal ) && maRestSz.Width() && maRestSz.Height() )
+ {
+ if( DISPOSE_BACK == meLastDisposal )
+ pDev->DrawOutDev( maRestPt, maRestSz, maRestPt, maRestSz, *mpBackground );
+ else
+ pDev->DrawOutDev( maRestPt, maRestSz, Point(), maRestSz, *mpRestore );
+ }
+
+ meLastDisposal = rAnm.eDisposal;
+ maRestPt = aPosPix;
+ maRestSz = aSizePix;
+
+ // Was muessen wir beim naechsten Mal restaurieren ?
+ // ==> ggf. in eine Bitmap stecken, ansonsten SaveBitmap
+ // aus Speichergruenden loeschen
+ if( ( meLastDisposal == DISPOSE_BACK ) || ( meLastDisposal == DISPOSE_NOT ) )
+ mpRestore->SetOutputSizePixel( Size( 1, 1 ), FALSE );
+ else
+ {
+ mpRestore->SetOutputSizePixel( maRestSz, FALSE );
+ mpRestore->DrawOutDev( Point(), maRestSz, aPosPix, aSizePix, *pDev );
+ }
+
+ pDev->DrawBitmapEx( aBmpPosPix, aBmpSizePix, rAnm.aBmpEx );
+
+ if( !pVDev )
+ {
+ Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
+
+ if( pOldClip )
+ mpOut->SetClipRegion( maClip );
+
+ mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, *pDev );
+
+ if( pOldClip )
+ {
+ mpOut->SetClipRegion( *pOldClip );
+ delete pOldClip;
+ }
+
+ delete pDev;
+
+#ifndef REMOTE_APPSERVER
+ if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
+ ( (Window*) mpOut )->Sync();
+#endif
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ImplAnimView::ImplRepaint()
+{
+ const BOOL bOldPause = mbPause;
+
+ if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
+ {
+ MapMode aTempMap( mpOut->GetMapMode() );
+ aTempMap.SetOrigin( Point() );
+ mpBackground->SetMapMode( aTempMap );
+ ( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
+ mpBackground->SetMapMode( MapMode() );
+ }
+ else
+ mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
+
+ mbPause = FALSE;
+ ImplDrawToPos( mnActPos );
+ mbPause = bOldPause;
+}
+
+// ------------------------------------------------------------------------
+
+AInfo* ImplAnimView::ImplCreateAInfo() const
+{
+ AInfo* pAInfo = new AInfo;
+
+ pAInfo->aStartOrg = maPt;
+ pAInfo->aStartSize = maSz;
+ pAInfo->pOutDev = mpOut;
+ pAInfo->pViewData = (void*) this;
+ pAInfo->nExtraData = mnExtraData;
+ pAInfo->bPause = mbPause;
+
+ return pAInfo;
+}
diff --git a/vcl/source/gdi/impanmvw.hxx b/vcl/source/gdi/impanmvw.hxx
new file mode 100644
index 000000000000..fdefa420cc62
--- /dev/null
+++ b/vcl/source/gdi/impanmvw.hxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * $RCSfile: impanmvw.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_IMPANMVW_HXX
+#define _SV_IMPANMVW_HXX
+
+#include "animate.hxx"
+
+// ----------------
+// - ImplAnimView -
+// ----------------
+
+class Animation;
+class OutputDevice;
+class VirtualDevice;
+struct AnimationBitmap;
+
+class ImplAnimView
+{
+private:
+
+ Animation* mpParent;
+ OutputDevice* mpOut;
+ long mnExtraData;
+ Point maPt;
+ Point maDispPt;
+ Point maRestPt;
+ Size maSz;
+ Size maSzPix;
+ Size maDispSz;
+ Size maRestSz;
+ MapMode maMap;
+ Region maClip;
+ VirtualDevice* mpBackground;
+ VirtualDevice* mpRestore;
+ ULONG mnActPos;
+ Disposal meLastDisposal;
+ BOOL mbPause;
+ BOOL mbFirst;
+ BOOL mbMarked;
+ BOOL mbHMirr;
+ BOOL mbVMirr;
+
+ void ImplGetPosSize( const AnimationBitmap& rAnm, Point& rPosPix, Size& rSizePix );
+ void ImplDraw( ULONG nPos, VirtualDevice* pVDev );
+
+public:
+
+ ImplAnimView( Animation* pParent, OutputDevice* pOut,
+ const Point& rPt, const Size& rSz, ULONG nExtraData,
+ OutputDevice* pFirstFrameOutDev = NULL );
+ ~ImplAnimView();
+
+ BOOL ImplMatches( OutputDevice* pOut, long nExtraData ) const;
+ void ImplDrawToPos( ULONG nPos );
+ void ImplDraw( ULONG nPos );
+ void ImplRepaint();
+ AInfo* ImplCreateAInfo() const;
+
+ const Point& ImplGetOutPos() const { return maPt; }
+
+ const Size& ImplGetOutSize() const { return maSz; }
+ const Size& ImplGetOutSizePix() const { return maSzPix; }
+
+ void ImplPause( BOOL bPause ) { mbPause = bPause; }
+ BOOL ImplIsPause() const { return mbPause; }
+
+ void ImplSetMarked( BOOL bMarked ) { mbMarked = bMarked; }
+ BOOL ImplIsMarked() const { return mbMarked; }
+};
+
+#endif
diff --git a/vcl/source/gdi/impbmp.cxx b/vcl/source/gdi/impbmp.cxx
new file mode 100644
index 000000000000..3cb648163026
--- /dev/null
+++ b/vcl/source/gdi/impbmp.cxx
@@ -0,0 +1,309 @@
+/*************************************************************************
+ *
+ * $RCSfile: impbmp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_IMPBMP_CXX
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#else
+#include <indbmp.hxx>
+#ifndef _SV_RMBITMAP_HXX
+#include <rmbitmap.hxx>
+#endif
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#include <impbmp.hxx>
+#include <bitmap.hxx>
+
+// --------------
+// - ImpBitmap -
+// --------------
+
+ImpBitmap::ImpBitmap() :
+ mnRefCount ( 1UL ),
+ mnChecksum ( 0UL ),
+ mpRMBitmap ( NULL ),
+#ifndef REMOTE_APPSERVER
+ mpSalBitmap ( new SalBitmap )
+#else
+ mpSalBitmap ( new ImplServerBitmap )
+#endif
+{
+}
+
+// -----------------------------------------------------------------------
+
+ImpBitmap::~ImpBitmap()
+{
+#ifdef REMOTE_APPSERVER
+ ImplReleaseRemoteBmp();
+#endif
+ delete mpSalBitmap;
+}
+
+// -----------------------------------------------------------------------
+#ifndef REMOTE_APPSERVER
+void ImpBitmap::ImplSetSalBitmap( SalBitmap* pBitmap )
+#else
+void ImpBitmap::ImplSetSalBitmap( ImplServerBitmap* pBitmap )
+#endif
+{
+ delete mpSalBitmap, mpSalBitmap = pBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImpBitmap::ImplCreate( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal )
+{
+ return mpSalBitmap->Create( rSize, nBitCount, rPal );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImpBitmap::ImplCreate( const ImpBitmap& rImpBitmap )
+{
+ mnChecksum = rImpBitmap.mnChecksum;
+ return mpSalBitmap->Create( *rImpBitmap.mpSalBitmap );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImpBitmap::ImplCreate( const ImpBitmap& rImpBitmap, SalGraphics* pGraphics )
+{
+ return mpSalBitmap->Create( *rImpBitmap.mpSalBitmap, pGraphics );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImpBitmap::ImplCreate( const ImpBitmap& rImpBitmap, USHORT nNewBitCount )
+{
+ return mpSalBitmap->Create( *rImpBitmap.mpSalBitmap, nNewBitCount );
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplDestroy()
+{
+ mpSalBitmap->Destroy();
+}
+
+// -----------------------------------------------------------------------
+
+Size ImpBitmap::ImplGetSize() const
+{
+#ifdef REMOTE_APPSERVER
+ if( ImplIsGetPrepared() )
+ return mpRMBitmap->GetSize();
+ else
+#endif
+ return mpSalBitmap->GetSize();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImpBitmap::ImplGetBitCount() const
+{
+ USHORT nBitCount;
+
+#ifdef REMOTE_APPSERVER
+ if( ImplIsGetPrepared() )
+ nBitCount = mpRMBitmap->GetBitCount();
+ else
+#endif
+ nBitCount = mpSalBitmap->GetBitCount();
+
+ return( ( nBitCount <= 1 ) ? 1 : ( nBitCount <= 4 ) ? 4 : ( nBitCount <= 8 ) ? 8 : 24 );
+}
+
+// -----------------------------------------------------------------------
+
+BitmapBuffer* ImpBitmap::ImplAcquireBuffer( BOOL bReadOnly )
+{
+ return mpSalBitmap->AcquireBuffer( bReadOnly );
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplReleaseBuffer( BitmapBuffer* pBuffer, BOOL bReadOnly )
+{
+ mpSalBitmap->ReleaseBuffer( pBuffer, bReadOnly );
+
+ if( !bReadOnly )
+ mnChecksum = 0;
+}
+
+#ifdef REMOTE_APPSERVER
+
+RMBitmap* ImpBitmap::ImplGetRemoteBmp()
+{
+ return mpRMBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplCreateRemoteBmp( const Bitmap& rBitmap )
+{
+ DBG_ASSERT( !mpRMBitmap, "ImplCreateRemoteBmp( Bitmap& rBitmap )???" );
+
+ mpRMBitmap = new RMBitmap( &(Bitmap&) rBitmap );
+ mpRMBitmap->Create();
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplCreateRemoteBmp( const Bitmap& rBitmap,
+ OutputDevice* pOut,
+ const Point& rPt, const Size& rSz )
+{
+ DBG_ASSERT( !mpRMBitmap, "ImplCreateRemoteBmp( Bitmap& rBitmap )???" );
+
+ mpRMBitmap = new RMBitmap( &(Bitmap&) rBitmap );
+ mpRMBitmap->CreateGet( pOut, rPt, rSz );
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplReleaseRemoteBmp()
+{
+ delete mpRMBitmap;
+ mpRMBitmap = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplDrawRemoteBmp( OutputDevice* pOut,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Point& rDestPt, const Size& rDestSz )
+{
+ if( mpRMBitmap )
+ mpRMBitmap->Draw( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz );
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplDrawRemoteBmpEx( OutputDevice* pOut,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Point& rDestPt, const Size& rDestSz,
+ const Bitmap& rMask )
+{
+ if( mpRMBitmap )
+ mpRMBitmap->DrawEx( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz, rMask );
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplDrawRemoteBmpAlpha( OutputDevice* pOut,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Point& rDestPt, const Size& rDestSz,
+ const AlphaMask& rAlpha )
+{
+ if( mpRMBitmap )
+ mpRMBitmap->DrawAlpha( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz, rAlpha );
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplDrawRemoteBmpMask( OutputDevice* pOut,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Point& rDestPt, const Size& rDestSz,
+ const Color& rColor )
+{
+ if( mpRMBitmap )
+ mpRMBitmap->DrawMask( pOut, rSrcPt, rSrcSz, rDestPt, rDestSz, rColor );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImpBitmap::ImplIsGetPrepared() const
+{
+ return( mpRMBitmap ? mpRMBitmap->IsGetPrepared() : FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void ImpBitmap::ImplResolveGet()
+{
+ if( mpRMBitmap )
+ {
+ Bitmap aBmp;
+ mpRMBitmap->Get( aBmp );
+ ImpBitmap* pGetImpBmp = aBmp.ImplGetImpBitmap();
+
+ if( pGetImpBmp )
+ {
+ // wir nehmen der gegetteten Bitmap einfach
+ // die SalBitmap weg; Null-Setzen nicht vergessen,
+ // da die Bitmap die SalBitmap sonst abraeumt
+ delete mpSalBitmap;
+ mpSalBitmap = pGetImpBmp->mpSalBitmap;
+ pGetImpBmp->mpSalBitmap = NULL;
+ }
+ }
+}
+
+#endif
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
new file mode 100644
index 000000000000..a53739ec6041
--- /dev/null
+++ b/vcl/source/gdi/impgraph.cxx
@@ -0,0 +1,1571 @@
+/*************************************************************************
+ *
+ * $RCSfile: impgraph.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_IMPGRAPH_CXX
+
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _URLOBJ_HXX
+#include <tools/urlobj.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _TOOLS_TEMPFILE_HXX
+#include <tools/tempfile.hxx>
+#endif
+#ifndef _UCBHELPER_CONTENT_HXX
+#include <ucbhelper/content.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _NEW_HXX
+#include <tools/new.hxx>
+#endif
+#include <impgraph.hxx>
+#ifndef _GFXLINK_HXX
+#include <gfxlink.hxx>
+#endif
+#ifndef _SV_CVTGRF_HXX
+#include <cvtgrf.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_GRAPH_HXX
+#include <graph.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define GRAPHIC_MAXPARTLEN 256000L
+#define GRAPHIC_MTFTOBMP_MAXEXT 2048
+#define GRAPHIC_STREAMBUFSIZE 8192UL
+
+#define SYS_WINMETAFILE 0x00000003UL
+#define SYS_WNTMETAFILE 0x00000004UL
+#define SYS_OS2METAFILE 0x00000005UL
+#define SYS_MACMETAFILE 0x00000006UL
+
+#define GRAPHIC_FORMAT_50 COMPAT_FORMAT( 'G', 'R', 'F', '5' )
+#define NATIVE_FORMAT_50 COMPAT_FORMAT( 'N', 'A', 'T', '5' )
+
+// ---------------
+// - ImpSwapFile -
+// ---------------
+
+struct ImpSwapFile
+{
+ String aSwapFileName;
+ USHORT nRefCount;
+};
+
+// -----------------
+// - Graphicreader -
+// -----------------
+
+GraphicReader::~GraphicReader()
+{
+}
+
+// --------------
+// - ImpGraphic -
+// --------------
+
+ImpGraphic::ImpGraphic() :
+ mpAnimation ( NULL ),
+ mpContext ( NULL ),
+ mpSwapFile ( NULL ),
+ mpGfxLink ( NULL ),
+ meType ( GRAPHIC_NONE ),
+ mnDocFilePos ( 0UL ),
+ mnRefCount ( 1UL ),
+ mbSwapOut ( FALSE ),
+ mbSwapUnderway ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------------
+
+ImpGraphic::ImpGraphic( const ImpGraphic& rImpGraphic ) :
+ maEx ( rImpGraphic.maEx ),
+ maMetaFile ( rImpGraphic.maMetaFile ),
+ mpContext ( NULL ),
+ mpSwapFile ( rImpGraphic.mpSwapFile ),
+ meType ( rImpGraphic.meType ),
+ maDocFileName ( rImpGraphic.maDocFileName ),
+ mnDocFilePos ( rImpGraphic.mnDocFilePos ),
+ mnRefCount ( 1UL ),
+ mbSwapOut ( rImpGraphic.mbSwapOut ),
+ mbSwapUnderway ( FALSE )
+{
+ if( mpSwapFile )
+ mpSwapFile->nRefCount++;
+
+ if( rImpGraphic.mpGfxLink )
+ mpGfxLink = new GfxLink( *rImpGraphic.mpGfxLink );
+ else
+ mpGfxLink = NULL;
+
+ if( rImpGraphic.mpAnimation )
+ {
+ mpAnimation = new Animation( *rImpGraphic.mpAnimation );
+ maEx = mpAnimation->GetBitmapEx();
+ }
+ else
+ mpAnimation = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) :
+ maEx ( rBitmap ),
+ mpAnimation ( NULL ),
+ mpContext ( NULL ),
+ mpSwapFile ( NULL ),
+ mpGfxLink ( NULL ),
+ meType ( !rBitmap ? GRAPHIC_NONE : GRAPHIC_BITMAP ),
+ mnDocFilePos ( 0UL ),
+ mnRefCount ( 1UL ),
+ mbSwapOut ( FALSE ),
+ mbSwapUnderway ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------------
+
+ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
+ maEx ( rBitmapEx ),
+ mpAnimation ( NULL ),
+ mpContext ( NULL ),
+ mpSwapFile ( NULL ),
+ mpGfxLink ( NULL ),
+ meType ( !rBitmapEx ? GRAPHIC_NONE : GRAPHIC_BITMAP ),
+ mnDocFilePos ( 0UL ),
+ mnRefCount ( 1UL ),
+ mbSwapOut ( FALSE ),
+ mbSwapUnderway ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------------
+
+ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
+ maEx ( rAnimation.GetBitmapEx() ),
+ mpAnimation ( new Animation( rAnimation ) ),
+ mpContext ( NULL ),
+ mpSwapFile ( NULL ),
+ mpGfxLink ( NULL ),
+ meType ( GRAPHIC_BITMAP ),
+ mnDocFilePos ( 0UL ),
+ mnRefCount ( 1UL ),
+ mbSwapOut ( FALSE ),
+ mbSwapUnderway ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------------
+
+ImpGraphic::ImpGraphic( const GDIMetaFile& rMtf ) :
+ maMetaFile ( rMtf ),
+ mpAnimation ( NULL ),
+ mpContext ( NULL ),
+ mpSwapFile ( NULL ),
+ mpGfxLink ( NULL ),
+ meType ( GRAPHIC_GDIMETAFILE ),
+ mnDocFilePos ( 0UL ),
+ mnRefCount ( 1UL ),
+ mbSwapOut ( FALSE ),
+ mbSwapUnderway ( FALSE )
+{
+}
+
+// ------------------------------------------------------------------------
+
+ImpGraphic::~ImpGraphic()
+{
+ ImplClear();
+
+ if( (ULONG) mpContext > 1UL )
+ delete mpContext;
+}
+
+// ------------------------------------------------------------------------
+
+ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic )
+{
+ if( &rImpGraphic != this )
+ {
+ if( !mbSwapUnderway )
+ ImplClear();
+
+ maMetaFile = rImpGraphic.maMetaFile;
+ meType = rImpGraphic.meType;
+
+ delete mpAnimation;
+
+ if ( rImpGraphic.mpAnimation )
+ {
+ mpAnimation = new Animation( *rImpGraphic.mpAnimation );
+ maEx = mpAnimation->GetBitmapEx();
+ }
+ else
+ {
+ mpAnimation = NULL;
+ maEx = rImpGraphic.maEx;
+ }
+
+ if( !mbSwapUnderway )
+ {
+ maDocFileName = rImpGraphic.maDocFileName;
+ mnDocFilePos = rImpGraphic.mnDocFilePos;
+ mbSwapOut = rImpGraphic.mbSwapOut;
+ mpSwapFile = rImpGraphic.mpSwapFile;
+
+ if( mpSwapFile )
+ mpSwapFile->nRefCount++;
+ }
+
+ delete mpGfxLink;
+
+ if( rImpGraphic.mpGfxLink )
+ mpGfxLink = new GfxLink( *rImpGraphic.mpGfxLink );
+ else
+ mpGfxLink = NULL;
+ }
+
+ return *this;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
+{
+ BOOL bRet = FALSE;
+
+ if( this == &rImpGraphic )
+ bRet = TRUE;
+ else if( !ImplIsSwapOut() && ( rImpGraphic.meType == meType ) )
+ {
+ switch( meType )
+ {
+ case( GRAPHIC_NONE ):
+ bRet = TRUE;
+ break;
+
+ case( GRAPHIC_GDIMETAFILE ):
+ {
+ if( rImpGraphic.maMetaFile == maMetaFile )
+ bRet = TRUE;
+ }
+ break;
+
+ case( GRAPHIC_BITMAP ):
+ {
+ if( mpAnimation )
+ {
+ if( rImpGraphic.mpAnimation && ( *rImpGraphic.mpAnimation == *mpAnimation ) )
+ bRet = TRUE;
+ }
+ else if( !rImpGraphic.mpAnimation && ( rImpGraphic.maEx == maEx ) )
+ bRet = TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplClearGraphics( BOOL bCreateSwapInfo )
+{
+ if( bCreateSwapInfo && !ImplIsSwapOut() )
+ {
+ maSwapInfo.maPrefMapMode = ImplGetPrefMapMode();
+ maSwapInfo.maPrefSize = ImplGetPrefSize();
+ }
+
+ maEx.Clear();
+ maMetaFile.Clear();
+
+ if( mpAnimation )
+ {
+ mpAnimation->Clear();
+ delete mpAnimation;
+ mpAnimation = NULL;
+ }
+
+ if( mpGfxLink )
+ {
+ delete mpGfxLink;
+ mpGfxLink = NULL;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplClear()
+{
+ if( mpSwapFile )
+ {
+ if( mpSwapFile->nRefCount > 1 )
+ mpSwapFile->nRefCount--;
+ else
+ {
+ try
+ {
+ ::ucb::Content aCnt( INetURLObject( mpSwapFile->aSwapFileName, INET_PROT_FILE ).GetMainURL(),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
+ ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ... )
+ {
+ DBG_ERRORFILE( "Any other exception" );
+ }
+
+ delete mpSwapFile;
+ }
+
+ mpSwapFile = NULL;
+ }
+
+ mbSwapOut = FALSE;
+ mnDocFilePos = 0UL;
+ maDocFileName.Erase();
+
+ // cleanup
+ ImplClearGraphics( FALSE );
+ meType = GRAPHIC_NONE;
+}
+
+// ------------------------------------------------------------------------
+
+GraphicType ImpGraphic::ImplGetType() const
+{
+ return meType;
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplSetDefaultType()
+{
+ ImplClear();
+ meType = GRAPHIC_DEFAULT;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplIsSupportedGraphic() const
+{
+ return( meType != GRAPHIC_NONE );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplIsTransparent() const
+{
+ BOOL bRet;
+
+ if( meType == GRAPHIC_BITMAP )
+ bRet = ( mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent() );
+ else
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplIsAlpha() const
+{
+ BOOL bRet;
+
+ if( meType == GRAPHIC_BITMAP )
+ bRet = ( NULL == mpAnimation ) && maEx.IsAlpha();
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplIsAnimated() const
+{
+ return( mpAnimation != NULL );
+}
+
+// ------------------------------------------------------------------------
+
+Bitmap ImpGraphic::ImplGetBitmap() const
+{
+ Bitmap aRetBmp;
+
+ if( meType == GRAPHIC_BITMAP )
+ {
+ const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
+ const Color aReplaceColor( COL_WHITE );
+
+ aRetBmp = rRetBmpEx.GetBitmap( &aReplaceColor );
+ }
+ else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() )
+ {
+ VirtualDevice aVDev;
+ Size aSizePix( aVDev.LogicToPixel( maMetaFile.GetPrefSize(),
+ maMetaFile.GetPrefMapMode() ) );
+
+ if( aSizePix.Width() && aSizePix.Height() &&
+ ( aSizePix.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aSizePix.Height() > GRAPHIC_MTFTOBMP_MAXEXT ) )
+ {
+ double fWH = (double) aSizePix.Width() / aSizePix.Height();
+
+ if( fWH <= 1.0 )
+ {
+ aSizePix.Width() = FRound( fWH * GRAPHIC_MTFTOBMP_MAXEXT );
+ aSizePix.Height() = GRAPHIC_MTFTOBMP_MAXEXT;
+ }
+ else
+ {
+ aSizePix.Width() = GRAPHIC_MTFTOBMP_MAXEXT;
+ aSizePix.Height() = FRound( GRAPHIC_MTFTOBMP_MAXEXT / fWH );
+ }
+ }
+
+ if( aVDev.SetOutputSizePixel( aSizePix ) )
+ {
+ const Point aPt;
+ ImplDraw( &aVDev, aPt, aSizePix );
+ aRetBmp = aVDev.GetBitmap( aPt, aSizePix );
+ }
+ }
+
+ if( !!aRetBmp )
+ {
+ aRetBmp.SetPrefMapMode( ImplGetPrefMapMode() );
+ aRetBmp.SetPrefSize( ImplGetPrefSize() );
+ }
+
+ return aRetBmp;
+}
+
+// ------------------------------------------------------------------------
+
+BitmapEx ImpGraphic::ImplGetBitmapEx() const
+{
+ BitmapEx aRetBmpEx;
+
+ if( meType == GRAPHIC_BITMAP )
+ aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
+ else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() )
+ {
+ const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) );
+ aRetBmpEx = BitmapEx( ImplGetBitmap(), aMonoMask.ImplGetBitmap() );
+ }
+
+ return aRetBmpEx;
+}
+
+// ------------------------------------------------------------------------
+
+Animation ImpGraphic::ImplGetAnimation() const
+{
+ Animation aAnimation;
+
+ if( mpAnimation )
+ aAnimation = *mpAnimation;
+
+ return aAnimation;
+}
+
+// ------------------------------------------------------------------------
+
+const GDIMetaFile& ImpGraphic::ImplGetGDIMetaFile() const
+{
+ return maMetaFile;
+}
+
+// ------------------------------------------------------------------------
+
+Size ImpGraphic::ImplGetPrefSize() const
+{
+ Size aSize;
+
+ if( ImplIsSwapOut() )
+ aSize = maSwapInfo.maPrefSize;
+ else
+ {
+ switch( meType )
+ {
+ case( GRAPHIC_NONE ):
+ case( GRAPHIC_DEFAULT ):
+ break;
+
+ case( GRAPHIC_BITMAP ):
+ {
+ aSize = maEx.GetPrefSize();
+
+ if( !aSize.Width() || !aSize.Height() )
+ aSize = maEx.GetSizePixel();
+ }
+ break;
+
+ default:
+ {
+ if( ImplIsSupportedGraphic() )
+ aSize = maMetaFile.GetPrefSize();
+ }
+ break;
+ }
+ }
+
+ return aSize;
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
+{
+ switch( meType )
+ {
+ case( GRAPHIC_NONE ):
+ case( GRAPHIC_DEFAULT ):
+ break;
+
+ case( GRAPHIC_BITMAP ):
+ maEx.SetPrefSize( rPrefSize );
+ break;
+
+ default:
+ {
+ if( ImplIsSupportedGraphic() )
+ maMetaFile.SetPrefSize( rPrefSize );
+ }
+ break;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+MapMode ImpGraphic::ImplGetPrefMapMode() const
+{
+ MapMode aMapMode;
+
+ if( ImplIsSwapOut() )
+ aMapMode = maSwapInfo.maPrefMapMode;
+ else
+ {
+ switch( meType )
+ {
+ case( GRAPHIC_NONE ):
+ case( GRAPHIC_DEFAULT ):
+ break;
+
+ case( GRAPHIC_BITMAP ):
+ {
+ const Size aSize( maEx.GetPrefSize() );
+
+ if ( aSize.Width() && aSize.Height() )
+ aMapMode = maEx.GetPrefMapMode();
+ }
+ break;
+
+ default:
+ {
+ if( ImplIsSupportedGraphic() )
+ return maMetaFile.GetPrefMapMode();
+ }
+ break;
+ }
+ }
+
+ return aMapMode;
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode )
+{
+ switch( meType )
+ {
+ case( GRAPHIC_NONE ):
+ case( GRAPHIC_DEFAULT ):
+ break;
+
+ case( GRAPHIC_BITMAP ):
+ maEx.SetPrefMapMode( rPrefMapMode );
+ break;
+
+ default:
+ {
+ if( ImplIsSupportedGraphic() )
+ maMetaFile.SetPrefMapMode( rPrefMapMode );
+ }
+ break;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ImpGraphic::ImplGetSizeBytes() const
+{
+ ULONG nSizeBytes;
+
+ if( meType == GRAPHIC_BITMAP )
+ {
+ if( mpAnimation )
+ nSizeBytes = mpAnimation->GetSizeBytes();
+ else
+ nSizeBytes = maEx.GetSizeBytes();
+ }
+ else
+ nSizeBytes = 0UL;
+
+ return nSizeBytes;
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplDraw( OutputDevice* pOutDev, const Point& rDestPt ) const
+{
+ if( ImplIsSupportedGraphic() && !ImplIsSwapOut() )
+ {
+ switch( meType )
+ {
+ case( GRAPHIC_DEFAULT ):
+ break;
+
+ case( GRAPHIC_BITMAP ):
+ {
+ if ( mpAnimation )
+ mpAnimation->Draw( pOutDev, rDestPt );
+ else
+ maEx.Draw( pOutDev, rDestPt );
+ }
+ break;
+
+ default:
+ ImplDraw( pOutDev, rDestPt, maMetaFile.GetPrefSize() );
+ break;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplDraw( OutputDevice* pOutDev,
+ const Point& rDestPt, const Size& rDestSize ) const
+{
+ if( ImplIsSupportedGraphic() && !ImplIsSwapOut() )
+ {
+ switch( meType )
+ {
+ case( GRAPHIC_DEFAULT ):
+ break;
+
+ case( GRAPHIC_BITMAP ):
+ {
+ if( mpAnimation )
+ mpAnimation->Draw( pOutDev, rDestPt, rDestSize );
+ else
+ maEx.Draw( pOutDev, rDestPt, rDestSize );
+ }
+ break;
+
+ default:
+ {
+ ( (ImpGraphic*) this )->maMetaFile.WindStart();
+ ( (ImpGraphic*) this )->maMetaFile.Play( pOutDev, rDestPt, rDestSize );
+ ( (ImpGraphic*) this )->maMetaFile.WindStart();
+ }
+ break;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev,
+ const Point& rDestPt,
+ long nExtraData,
+ OutputDevice* pFirstFrameOutDev )
+{
+ if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation )
+ mpAnimation->Start( pOutDev, rDestPt, nExtraData, pFirstFrameOutDev );
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev, const Point& rDestPt,
+ const Size& rDestSize, long nExtraData,
+ OutputDevice* pFirstFrameOutDev )
+{
+ if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation )
+ mpAnimation->Start( pOutDev, rDestPt, rDestSize, nExtraData, pFirstFrameOutDev );
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplStopAnimation( OutputDevice* pOutDev, long nExtraData )
+{
+ if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation )
+ mpAnimation->Stop( pOutDev, nExtraData );
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplSetAnimationNotifyHdl( const Link& rLink )
+{
+ if( mpAnimation )
+ mpAnimation->SetNotifyHdl( rLink );
+}
+
+// ------------------------------------------------------------------------
+
+Link ImpGraphic::ImplGetAnimationNotifyHdl() const
+{
+ Link aLink;
+
+ if( mpAnimation )
+ aLink = mpAnimation->GetNotifyHdl();
+
+ return aLink;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ImpGraphic::ImplGetAnimationLoopCount() const
+{
+ return( mpAnimation ? mpAnimation->GetLoopCount() : 0UL );
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplResetAnimationLoopCount()
+{
+ if( mpAnimation )
+ mpAnimation->ResetLoopCount();
+}
+
+// ------------------------------------------------------------------------
+
+List* ImpGraphic::ImplGetAnimationInfoList() const
+{
+ return( mpAnimation ? mpAnimation->GetAInfoList() : NULL );
+}
+
+// ------------------------------------------------------------------------
+
+GraphicReader* ImpGraphic::ImplGetContext()
+{
+ return mpContext;
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplSetContext( GraphicReader* pReader )
+{
+ mpContext = pReader;
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplSetDocFileName( const String& rName, ULONG nFilePos )
+{
+ maDocFileName = rName;
+ mnDocFilePos = nFilePos;
+}
+
+// ------------------------------------------------------------------------
+
+const String& ImpGraphic::ImplGetDocFileName() const
+{
+ return maDocFileName;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ImpGraphic::ImplGetDocFilePos() const
+{
+ return mnDocFilePos;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplReadEmbedded( SvStream& rIStm, BOOL bSwap )
+{
+ MapMode aMapMode;
+ Size aSize;
+ const ULONG nStartPos = rIStm.Tell();
+ ULONG nId;
+ ULONG nHeaderLen;
+ long nType;
+ long nLen;
+ const USHORT nOldFormat = rIStm.GetNumberFormatInt();
+ BOOL bRet = FALSE;
+
+ if( !mbSwapUnderway )
+ {
+ const String aTempName( maDocFileName );
+ const ULONG nTempPos = mnDocFilePos;
+
+ ImplClear();
+
+ maDocFileName = aTempName;
+ mnDocFilePos = nTempPos;
+ }
+
+ rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rIStm >> nId;
+
+ // check version
+ if( GRAPHIC_FORMAT_50 == nId )
+ {
+ // read new style header
+ VersionCompat* pCompat = new VersionCompat( rIStm, STREAM_READ );
+
+ rIStm >> nType;
+ rIStm >> nLen;
+ rIStm >> aSize;
+ rIStm >> aMapMode;
+
+ delete pCompat;
+ }
+ else
+ {
+ // read old style header
+ long nWidth, nHeight;
+ long nMapMode, nScaleNumX, nScaleDenomX;
+ long nScaleNumY, nScaleDenomY, nOffsX, nOffsY;
+
+ rIStm.SeekRel( -4L );
+
+ rIStm >> nType >> nLen >> nWidth >> nHeight;
+ rIStm >> nMapMode >> nScaleNumX >> nScaleDenomX >> nScaleNumY;
+ rIStm >> nScaleDenomY >> nOffsX >> nOffsY;
+
+ // swapped
+ if( nType > 100L )
+ {
+ nType = SWAPLONG( nType );
+ nLen = SWAPLONG( nLen );
+ nWidth = SWAPLONG( nWidth );
+ nHeight = SWAPLONG( nHeight );
+ nMapMode = SWAPLONG( nMapMode );
+ nScaleNumX = SWAPLONG( nScaleNumX );
+ nScaleDenomX = SWAPLONG( nScaleDenomX );
+ nScaleNumY = SWAPLONG( nScaleNumY );
+ nScaleDenomY = SWAPLONG( nScaleDenomY );
+ nOffsX = SWAPLONG( nOffsX );
+ nOffsY = SWAPLONG( nOffsY );
+ }
+
+ aSize = Size( nWidth, nHeight );
+ aMapMode = MapMode( (MapUnit) nMapMode, Point( nOffsX, nOffsY ),
+ Fraction( nScaleNumX, nScaleDenomX ),
+ Fraction( nScaleNumY, nScaleDenomY ) );
+ }
+
+ nHeaderLen = rIStm.Tell() - nStartPos;
+ meType = (GraphicType) nType;
+
+ if( meType )
+ {
+ if( meType == GRAPHIC_BITMAP )
+ {
+ maEx.aBitmapSize = aSize;
+
+ if( aMapMode != MapMode() )
+ {
+ maEx.SetPrefMapMode( aMapMode );
+ maEx.SetPrefSize( aSize );
+ }
+ }
+ else
+ {
+ maMetaFile.SetPrefMapMode( aMapMode );
+ maMetaFile.SetPrefSize( aSize );
+ }
+
+ if( bSwap )
+ {
+ if( maDocFileName.Len() )
+ {
+ rIStm.Seek( nStartPos + nHeaderLen + nLen );
+ bRet = mbSwapOut = TRUE;
+ }
+ else
+ {
+ const String aTmpName( TempFile::CreateTempName() );
+
+ if( aTmpName.Len() )
+ {
+ SvFileStream aOStm( aTmpName, STREAM_WRITE | STREAM_SHARE_DENYWRITE );
+
+ aOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ if( !aOStm.GetError() )
+ {
+ ULONG nFullLen = nHeaderLen + nLen;
+ ULONG nPartLen = Min( nFullLen, (ULONG) GRAPHIC_MAXPARTLEN );
+ BYTE* pBuffer = (BYTE*) SvMemAlloc( nPartLen );
+
+ if( pBuffer )
+ {
+ rIStm.Seek( nStartPos );
+
+ while( nFullLen )
+ {
+ rIStm.Read( (char*) pBuffer, nPartLen );
+ aOStm.Write( (char*) pBuffer, nPartLen );
+
+ nFullLen -= nPartLen;
+
+ if( nFullLen < GRAPHIC_MAXPARTLEN )
+ nPartLen = nFullLen;
+ }
+
+ SvMemFree( pBuffer );
+
+ ULONG nReadErr = rIStm.GetError();
+ ULONG nWriteErr = aOStm.GetError();
+
+ aOStm.Close();
+
+ if( !nReadErr && !nWriteErr )
+ {
+ bRet = mbSwapOut = TRUE;
+ mpSwapFile = new ImpSwapFile;
+ mpSwapFile->nRefCount = 1;
+ mpSwapFile->aSwapFileName = aTmpName;
+ }
+ else
+ {
+ try
+ {
+ ::ucb::Content aCnt( INetURLObject( aTmpName, INET_PROT_FILE ).GetMainURL(),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
+ ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ... )
+ {
+ DBG_ERRORFILE( "Any other exception" );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if( meType == GRAPHIC_BITMAP || meType == GRAPHIC_GDIMETAFILE )
+ {
+ rIStm >> *this;
+ bRet = ( rIStm.GetError() == 0UL );
+ }
+ else if( meType >= SYS_WINMETAFILE && meType <= SYS_MACMETAFILE )
+ {
+ Graphic aSysGraphic;
+ ULONG nCvtType;
+
+ switch( (ULONG) meType )
+ {
+ case( SYS_WINMETAFILE ):
+ case( SYS_WNTMETAFILE ): nCvtType = CVT_WMF; break;
+ case( SYS_OS2METAFILE ): nCvtType = CVT_MET; break;
+ case( SYS_MACMETAFILE ): nCvtType = CVT_PCT; break;
+
+ default:
+ nCvtType = CVT_UNKNOWN;
+ break;
+ }
+
+ if( nType && GraphicConverter::Import( rIStm, aSysGraphic, nCvtType ) == ERRCODE_NONE )
+ {
+ *this = ImpGraphic( aSysGraphic.GetGDIMetaFile() );
+ bRet = ( rIStm.GetError() == 0UL );
+ }
+ else
+ meType = GRAPHIC_DEFAULT;
+ }
+
+ if( bRet )
+ {
+ ImplSetPrefMapMode( aMapMode );
+ ImplSetPrefSize( aSize );
+ }
+ }
+ else
+ bRet = TRUE;
+
+ rIStm.SetNumberFormatInt( nOldFormat );
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplWriteEmbedded( SvStream& rOStm )
+{
+ BOOL bRet = FALSE;
+
+ if( ( meType != GRAPHIC_NONE ) && ( meType != GRAPHIC_DEFAULT ) && !ImplIsSwapOut() )
+ {
+ const MapMode aMapMode( ImplGetPrefMapMode() );
+ const Size aSize( ImplGetPrefSize() );
+ const USHORT nOldFormat = rOStm.GetNumberFormatInt();
+ const ULONG nStmPos1 = rOStm.Tell();
+ ULONG nDataFieldPos;
+
+ rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ // write correct version ( old style/new style header )
+ if( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 )
+ {
+ // write ID for new format (5.0)
+ rOStm << GRAPHIC_FORMAT_50;
+
+ // write new style header
+ VersionCompat* pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 );
+
+ rOStm << (long) meType;
+
+ // data size is updated later
+ nDataFieldPos = rOStm.Tell();
+ rOStm << (long) 0;
+
+ rOStm << aSize;
+ rOStm << aMapMode;
+
+ delete pCompat;
+ }
+ else
+ {
+ // write old style (<=4.0) header
+ rOStm << (long) meType;
+
+ // data size is updated later
+ nDataFieldPos = rOStm.Tell();
+ rOStm << (long) 0;
+
+ rOStm << (long) aSize.Width();
+ rOStm << (long) aSize.Height();
+ rOStm << (long) aMapMode.GetMapUnit();
+ rOStm << (long) aMapMode.GetScaleX().GetNumerator();
+ rOStm << (long) aMapMode.GetScaleX().GetDenominator();
+ rOStm << (long) aMapMode.GetScaleY().GetNumerator();
+ rOStm << (long) aMapMode.GetScaleY().GetDenominator();
+ rOStm << (long) aMapMode.GetOrigin().X();
+ rOStm << (long) aMapMode.GetOrigin().Y();
+ }
+
+ // write data block
+ if( !rOStm.GetError() )
+ {
+ const ULONG nDataStart = rOStm.Tell();
+
+ if( ImplIsSupportedGraphic() )
+ rOStm << *this;
+
+ if( !rOStm.GetError() )
+ {
+ const ULONG nStmPos2 = rOStm.Tell();
+ rOStm.Seek( nDataFieldPos );
+ rOStm << (long) ( nStmPos2 - nDataStart );
+ rOStm.Seek( nStmPos2 );
+ bRet = TRUE;
+ }
+ }
+
+ rOStm.SetNumberFormatInt( nOldFormat );
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplSwapOut()
+{
+ BOOL bRet = FALSE;
+
+ if( !ImplIsSwapOut() )
+ {
+ if( !maDocFileName.Len() )
+ {
+ const String aTmpName( TempFile::CreateTempName() );
+
+ if( aTmpName.Len() )
+ {
+ SvFileStream aOStm( aTmpName, STREAM_WRITE | STREAM_SHARE_DENYWRITE );
+
+ aOStm.SetVersion( SOFFICE_FILEFORMAT_NOW );
+ aOStm.SetCompressMode( COMPRESSMODE_NATIVE );
+
+ if( ( bRet = ImplSwapOut( &aOStm ) ) == TRUE )
+ {
+ mpSwapFile = new ImpSwapFile;
+ mpSwapFile->nRefCount = 1;
+ mpSwapFile->aSwapFileName = aTmpName;
+ }
+ else
+ {
+ try
+ {
+ ::ucb::Content aCnt( INetURLObject( aTmpName, INET_PROT_FILE ).GetMainURL(),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
+ ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ... )
+ {
+ DBG_ERRORFILE( "Any other exception" );
+ }
+ }
+ }
+ }
+ else
+ {
+ ImplClearGraphics( TRUE );
+ bRet = mbSwapOut = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplSwapOut( SvStream* pOStm )
+{
+ BOOL bRet = FALSE;
+
+ if( pOStm )
+ {
+ pOStm->SetBufferSize( GRAPHIC_STREAMBUFSIZE );
+
+ if( !pOStm->GetError() && ImplWriteEmbedded( *pOStm ) )
+ {
+ pOStm->Flush();
+
+ if( !pOStm->GetError() )
+ {
+ ImplClearGraphics( TRUE );
+ bRet = mbSwapOut = TRUE;
+ }
+ }
+ }
+ else
+ {
+ ImplClearGraphics( TRUE );
+ bRet = mbSwapOut = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplSwapIn()
+{
+ BOOL bRet = FALSE;
+
+ if( ImplIsSwapOut() )
+ {
+ const String aFileName = ( mpSwapFile ? mpSwapFile->aSwapFileName : maDocFileName );
+ SvFileStream aIStm( aFileName, STREAM_READ | STREAM_SHARE_DENYWRITE );
+
+ aIStm.SetVersion( SOFFICE_FILEFORMAT_NOW );
+ aIStm.SetCompressMode( COMPRESSMODE_NATIVE );
+
+ if( !mpSwapFile )
+ aIStm.Seek( mnDocFilePos );
+
+ bRet = ImplSwapIn( &aIStm );
+ aIStm.Close();
+
+ if( mpSwapFile )
+ {
+ if( mpSwapFile->nRefCount > 1 )
+ mpSwapFile->nRefCount--;
+ else
+ {
+ try
+ {
+ ::ucb::Content aCnt( INetURLObject( mpSwapFile->aSwapFileName, INET_PROT_FILE ).GetMainURL(),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
+ ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ... )
+ {
+ DBG_ERRORFILE( "Any other exception" );
+ }
+
+ delete mpSwapFile;
+ }
+
+ mpSwapFile = NULL;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplSwapIn( SvStream* pIStm )
+{
+ BOOL bRet = FALSE;
+
+ if( pIStm )
+ {
+ pIStm->SetBufferSize( GRAPHIC_STREAMBUFSIZE );
+
+ if( !pIStm->GetError() )
+ {
+ mbSwapUnderway = TRUE;
+ bRet = ImplReadEmbedded( *pIStm );
+ mbSwapUnderway = FALSE;
+
+ if( !bRet )
+ ImplClear();
+ else
+ mbSwapOut = FALSE;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplIsSwapOut() const
+{
+ return mbSwapOut;
+}
+
+// ------------------------------------------------------------------------
+
+void ImpGraphic::ImplSetLink( const GfxLink& rGfxLink )
+{
+ delete mpGfxLink;
+ mpGfxLink = new GfxLink( rGfxLink );
+
+ if( mpGfxLink->IsNative() )
+ mpGfxLink->SwapOut();
+}
+
+// ------------------------------------------------------------------------
+
+GfxLink ImpGraphic::ImplGetLink()
+{
+ return( mpGfxLink ? *mpGfxLink : GfxLink() );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplIsLink() const
+{
+ return ( mpGfxLink != NULL ) ? TRUE : FALSE;
+}
+
+// ------------------------------------------------------------------------
+
+ULONG ImpGraphic::ImplGetChecksum() const
+{
+ ULONG nRet = 0;
+
+ if( ImplIsSupportedGraphic() && !ImplIsSwapOut() )
+ {
+ switch( meType )
+ {
+ case( GRAPHIC_DEFAULT ):
+ break;
+
+ case( GRAPHIC_BITMAP ):
+ {
+ if( mpAnimation )
+ nRet = mpAnimation->GetChecksum();
+ else
+ nRet = maEx.GetChecksum();
+ }
+ break;
+
+ default:
+ nRet = maMetaFile.GetChecksum();
+ break;
+ }
+ }
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplCopy() const
+{
+ DBG_ERROR( "Missing implementation!" );
+ return FALSE;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL ImpGraphic::ImplPaste()
+{
+ DBG_ERROR( "Missing implementation!" );
+ return FALSE;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, ImpGraphic& rImpGraphic )
+{
+ if( !rIStm.GetError() )
+ {
+ const ULONG nStmPos1 = rIStm.Tell();
+ ULONG nTmp;
+
+ if ( !rImpGraphic.mbSwapUnderway )
+ rImpGraphic.ImplClear();
+
+ // read Id
+ rIStm >> nTmp;
+
+ if( NATIVE_FORMAT_50 == nTmp )
+ {
+ Graphic aGraphic;
+ GfxLink aLink;
+ VersionCompat* pCompat;
+
+ // read compat info
+ pCompat = new VersionCompat( rIStm, STREAM_READ );
+ delete pCompat;
+
+ rIStm >> aLink;
+
+ // set dummy link to avoid creation of additional link after filtering;
+ // we set a default link to avoid unnecessary swapping of native data
+ aGraphic.SetLink( GfxLink() );
+
+ if( !rIStm.GetError() && aLink.LoadNative( aGraphic ) )
+ {
+ // set link only, if no other link was set
+ const BOOL bSetLink = ( rImpGraphic.mpGfxLink == NULL );
+
+ // assign graphic
+ rImpGraphic = *aGraphic.ImplGetImpGraphic();
+
+ if( bSetLink )
+ rImpGraphic.ImplSetLink( aLink );
+ }
+ else
+ {
+ rIStm.Seek( nStmPos1 );
+ rIStm.SetError( ERRCODE_IO_WRONGFORMAT );
+ }
+ }
+ else
+ {
+ BitmapEx aBmpEx;
+ const USHORT nOldFormat = rIStm.GetNumberFormatInt();
+
+ rIStm.SeekRel( -4 );
+ rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rIStm >> aBmpEx;
+
+ if( !rIStm.GetError() )
+ {
+ UINT32 nMagic1, nMagic2;
+ ULONG nActPos = rIStm.Tell();
+
+ rIStm >> nMagic1 >> nMagic2;
+ rIStm.Seek( nActPos );
+
+ rImpGraphic = ImpGraphic( aBmpEx );
+
+ if( ( 0x5344414e == nMagic1 ) && ( 0x494d4931 == nMagic2 ) && !rIStm.GetError() )
+ {
+ delete rImpGraphic.mpAnimation;
+ rImpGraphic.mpAnimation = new Animation;
+ rIStm >> *rImpGraphic.mpAnimation;
+ }
+ }
+ else
+ {
+ GDIMetaFile aMtf;
+
+ rIStm.Seek( nStmPos1 );
+ rIStm.ResetError();
+ rIStm >> aMtf;
+
+ if( !rIStm.GetError() )
+ rImpGraphic = aMtf;
+ else
+ rIStm.Seek( nStmPos1 );
+ }
+
+ rIStm.SetNumberFormatInt( nOldFormat );
+ }
+ }
+
+ return rIStm;
+}
+
+// ------------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const ImpGraphic& rImpGraphic )
+{
+ if( !rOStm.GetError() )
+ {
+ if( !rImpGraphic.ImplIsSwapOut() )
+ {
+ if( ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) &&
+ ( rOStm.GetCompressMode() & COMPRESSMODE_NATIVE ) &&
+ rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative() )
+ {
+ VersionCompat* pCompat;
+
+ // native format
+ rOStm << NATIVE_FORMAT_50;
+
+ // write compat info
+ pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 );
+ delete pCompat;
+
+ rOStm << *rImpGraphic.mpGfxLink;
+ }
+ else
+ {
+ // own format
+ const USHORT nOldFormat = rOStm.GetNumberFormatInt();
+ rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ switch( rImpGraphic.ImplGetType() )
+ {
+ case( GRAPHIC_NONE ):
+ case( GRAPHIC_DEFAULT ):
+ break;
+
+ case GRAPHIC_BITMAP:
+ {
+ if ( rImpGraphic.ImplIsAnimated() )
+ rOStm << *rImpGraphic.mpAnimation;
+ else
+ rOStm << rImpGraphic.maEx;
+ }
+ break;
+
+ default:
+ {
+ if( rImpGraphic.ImplIsSupportedGraphic() )
+ rOStm << rImpGraphic.maMetaFile;
+ }
+ break;
+ }
+
+ rOStm.SetNumberFormatInt( nOldFormat );
+ }
+ }
+ else
+ rOStm.SetError( SVSTREAM_GENERALERROR );
+ }
+
+ return rOStm;
+}
diff --git a/vcl/source/gdi/impimage.cxx b/vcl/source/gdi/impimage.cxx
new file mode 100644
index 000000000000..1dcebb60009a
--- /dev/null
+++ b/vcl/source/gdi/impimage.cxx
@@ -0,0 +1,744 @@
+/*************************************************************************
+ *
+ * $RCSfile: impimage.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_IMPIMAGE_CXX
+
+#include <string.h>
+
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_BITMAPEX_HXX
+#include <bitmapex.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_IMAGE_H
+#include <image.h>
+#endif
+
+// -------------
+// - FASTIMAGE -
+// -------------
+
+#ifndef REMOTE_APPSERVER
+#if defined WIN || defined WNT || defined OS2
+#undef FASTTRANSPARENT
+extern BOOL bFastTransparent;
+#else
+#undef FASTTRANSPARENT
+#endif
+#else
+#undef FASTTRANSPARENT
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define IPOS( nPos ) ( Point( (nPos) * aSize.Width(), 0L ) )
+#define IMPSYSIMAGEITEM_NOTFREE ( 0x01 )
+#define IMPSYSIMAGEITEM_MASK ( 0x02 )
+#define DISA_ALL ( 0xffff )
+#define PAINT_ALL ( 0xffff )
+
+// ----------------
+// - ImplImageBmp -
+// ----------------
+
+ImplImageBmp::ImplImageBmp() :
+ pInfoAry ( NULL ),
+ nCount ( 0 ),
+ nSize ( 0 )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ImplImageBmp::~ImplImageBmp()
+{
+ delete[] pInfoAry;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Create( long nItemWidth, long nItemHeight, USHORT nInitSize )
+{
+ const Size aTotalSize( nInitSize * nItemWidth, nItemHeight );
+
+ nCount = 0;
+ aSize = Size( nItemWidth, nItemHeight );
+ nSize = nInitSize;
+
+ aBmp = Bitmap( aTotalSize, 4 );
+ aMask = Bitmap( aTotalSize, 1 );
+
+ delete[] pInfoAry;
+ pInfoAry = new BYTE[ nSize ];
+ memset( pInfoAry, 0, nSize );
+ ImplClearCaches();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Create( const Bitmap& rBmp, const Bitmap& rMaskBmp,
+ const Color& rColor, BOOL bColor,
+ long nItemWidth, long nItemHeight, USHORT nInitSize )
+{
+ BYTE nStyle = IMPSYSIMAGEITEM_NOTFREE;
+
+ ImplClearCaches();
+
+ if ( bColor || !!rMaskBmp )
+ nStyle |= IMPSYSIMAGEITEM_MASK;
+
+ aSize = Size( nItemWidth, nItemHeight );
+ nCount = 0;
+ nSize = nInitSize;
+
+ delete[] pInfoAry;
+ pInfoAry = new BYTE[ nSize ];
+ memset( pInfoAry, nStyle, nSize );
+
+ aBmp = rBmp;
+
+ if( !!rMaskBmp )
+ aMask = rMaskBmp;
+ else if( bColor )
+ aMask = aBmp.CreateMask( rColor );
+
+#ifdef FASTTRANSPARENT
+ if( nStyle & IMPSYSIMAGEITEM_MASK )
+ ImplUpdatePaintBmp( DISA_ALL );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Expand( USHORT nGrowSize )
+{
+ const ULONG nDX = nGrowSize * aSize.Width();
+ const USHORT nOldSize = nSize;
+ BYTE* pNewAry = new BYTE[ nSize += nGrowSize ];
+
+ ImplClearCaches();
+
+ aBmp.Expand( nDX, 0UL );
+ aMask.Expand( nDX, 0UL );
+
+ if( !!aDisa )
+ aDisa.Expand( nDX, 0UL );
+
+ memset( pNewAry, 0, nSize );
+ memcpy( pNewAry, pInfoAry, nOldSize );
+ delete[] pInfoAry;
+ pInfoAry = pNewAry;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Replace( USHORT nPos, USHORT nSrcPos )
+{
+ const Rectangle aSrcRect( IPOS( nSrcPos ), aSize );
+ const Rectangle aDstRect( IPOS( nPos ), aSize );
+
+ ImplClearCaches();
+
+ aBmp.CopyPixel( aDstRect, aSrcRect );
+
+ if ( pInfoAry[ nSrcPos ] & IMPSYSIMAGEITEM_MASK )
+ {
+ aMask.CopyPixel( aDstRect, aSrcRect );
+
+ if( !!aDisa )
+ aDisa.CopyPixel( aDstRect, aSrcRect );
+ }
+
+ pInfoAry[ nPos ] = pInfoAry[ nSrcPos ];
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Replace( USHORT nPos, const ImplImageBmp& rImageBmp, USHORT nSrcPos )
+{
+ const Rectangle aSrcRect( IPOS( nSrcPos ), aSize );
+ const Rectangle aDstRect( IPOS( nPos ), aSize );
+
+ ImplClearCaches();
+
+ aBmp.CopyPixel( aDstRect, aSrcRect, &rImageBmp.aBmp );
+
+ if ( rImageBmp.pInfoAry[ nSrcPos ] & IMPSYSIMAGEITEM_MASK )
+ {
+ aMask.CopyPixel( aDstRect, aSrcRect, &rImageBmp.aMask );
+
+ if( !!aDisa )
+ aDisa.CopyPixel( aDstRect, aSrcRect, &rImageBmp.aDisa );
+ }
+
+ pInfoAry[ nPos ] = rImageBmp.pInfoAry[ nSrcPos ];
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Replace( USHORT nPos, const Bitmap& rBmp )
+{
+ Point aPoint;
+ const Rectangle aSrcRect( aPoint, aSize );
+ const Rectangle aDstRect( IPOS( nPos ), aSize );
+
+ ImplClearCaches();
+
+ aBmp.CopyPixel( aDstRect, aSrcRect, &rBmp );
+ pInfoAry[ nPos ] &= ~IMPSYSIMAGEITEM_MASK;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Replace( USHORT nPos, const Bitmap& rBmp, const Bitmap& rMaskBmp )
+{
+ Point aPoint;
+ const Rectangle aSrcRect( aPoint, aSize );
+ const Rectangle aDstRect( IPOS( nPos ), aSize );
+
+ ImplClearCaches();
+
+ aBmp.CopyPixel( aDstRect, aSrcRect, &rBmp );
+ aMask.CopyPixel( aDstRect, aSrcRect, &rMaskBmp );
+
+ if( !!aDisa )
+ ImplUpdateDisaBmp( nPos );
+
+ pInfoAry[ nPos ] |= IMPSYSIMAGEITEM_MASK;
+
+#ifdef FASTTRANSPARENT
+ ImplUpdatePaintBmp( nPos );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Replace( USHORT nPos, const Bitmap& rBmp, const Color& rColor )
+{
+ Replace( nPos, rBmp, rBmp.CreateMask( rColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Merge( USHORT nPos, USHORT nSrcPos )
+{
+ if ( !( pInfoAry[ nSrcPos ] & IMPSYSIMAGEITEM_MASK ) )
+ Replace( nPos, nSrcPos );
+ else
+ {
+ ImplClearCaches();
+
+ const Rectangle aSrcRect( IPOS( nSrcPos ), aSize );
+ const Rectangle aDstRect( IPOS( nPos ), aSize );
+ BitmapWriteAccess* pBmp = aBmp.AcquireWriteAccess();
+ BitmapWriteAccess* pMsk = aMask.AcquireWriteAccess();
+
+ if ( pBmp && pMsk )
+ {
+ const BitmapColor aMskBlack( pMsk->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ BitmapColor aDstCol, aSrcCol;
+ long nDstLeft = aDstRect.Left();
+ long nDstRight = aDstRect.Right();
+ long nDstBottom = aDstRect.Bottom();
+ long nSrcLeft = aSrcRect.Left();
+ long nSrcRight = aSrcRect.Right();
+ long nSrcTop = aSrcRect.Bottom();
+
+ for( long nDstY = aDstRect.Top(), nSrcY = aSrcRect.Top(); nDstY <= nDstBottom; nDstY++, nSrcY++ )
+ {
+ for( long nDstX = nDstLeft, nSrcX = nSrcLeft; nDstX <= nDstRight; nDstX++, nSrcX++ )
+ {
+ aDstCol = pMsk->GetPixel( nDstY, nDstX );
+ aSrcCol = pMsk->GetPixel( nSrcY, nSrcX );
+
+ if( aMskBlack == aDstCol )
+ {
+ if( aMskBlack == aSrcCol )
+ pBmp->SetPixel( nDstY, nDstX, pBmp->GetPixel( nSrcY, nSrcX ) );
+ }
+ else if( aMskBlack == aSrcCol )
+ {
+ pBmp->SetPixel( nDstY, nDstX, pBmp->GetPixel( nSrcY, nSrcX ) );
+ pMsk->SetPixel( nDstY, nDstX, aMskBlack );
+ }
+ }
+ }
+ }
+
+ aBmp.ReleaseAccess( pBmp );
+ aMask.ReleaseAccess( pMsk );
+
+ if( !!aDisa )
+ ImplUpdateDisaBmp( nPos );
+
+ pInfoAry[ nPos ] |= IMPSYSIMAGEITEM_MASK;
+
+#ifdef FASTTRANSPARENT
+ ImplUpdatePaintBmp( nPos );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Bitmap ImplImageBmp::GetBitmap( USHORT nPosCount, USHORT* pPosAry ) const
+{
+ Bitmap aNewBmp( Size( nPosCount * aSize.Width(), aSize.Height() ), aBmp.GetBitCount() );
+
+ for( USHORT i = 0; i < nPosCount; i++ )
+ {
+ const Rectangle aSrcRect( IPOS( pPosAry[ i ] ), aSize );
+ const Rectangle aDstRect( IPOS( i ), aSize );
+
+ aNewBmp.CopyPixel( aDstRect, aSrcRect, &aBmp );
+ }
+
+ return aNewBmp;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplImageBmp::HasMaskBitmap() const
+{
+ return( !!aMask );
+}
+
+// -----------------------------------------------------------------------
+
+Bitmap ImplImageBmp::GetMaskBitmap( USHORT nPosCount, USHORT* pPosAry ) const
+{
+ Bitmap aNewMask( Size( nPosCount * aSize.Width(), aSize.Height() ), aMask.GetBitCount() );
+
+ for( USHORT i = 0; i < nPosCount; i++ )
+ {
+ const Rectangle aSrcRect( IPOS( pPosAry[ i ] ), aSize );
+ const Rectangle aDstRect( IPOS( i ), aSize );
+
+ aNewMask.CopyPixel( aDstRect, aSrcRect, &aMask );
+ }
+
+ return aNewMask;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplImageBmp::HasMaskColor() const
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Color ImplImageBmp::GetMaskColor() const
+{
+ return Color();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::Draw( USHORT nPos, OutputDevice* pOutDev,
+ const Point& rPos, USHORT nStyle,
+ const Size* pSize )
+{
+ if( pOutDev->IsDeviceOutputNecessary() )
+ {
+#ifndef REMOTE_APPSERVER
+
+ if( !aBmpDisp && !!aBmp )
+ aBmpDisp = aBmp.CreateDisplayBitmap( pOutDev );
+
+ if( !aMaskDisp && !!aMask )
+ aMaskDisp = aMask.CreateDisplayBitmap( pOutDev );
+
+#else // REMOTE_APPSERVER
+
+ if( !aBmpDisp && !!aBmp )
+ aBmpDisp = aBmp;
+
+ if( !aMaskDisp && !!aMask )
+ aMaskDisp = aMask;
+
+ if( !aDisaDisp && !!aDisa )
+ aDisaDisp = aDisa;
+
+#endif // REMOTE_APPSERVER
+
+ if( !aBmpEx )
+ aBmpEx = BitmapEx( aBmpDisp, aMaskDisp );
+
+ if( pInfoAry[ nPos ] & IMPSYSIMAGEITEM_MASK )
+ {
+#ifdef FASTTRANSPARENT
+ BOOL bTmp = bFastTransparent;
+ bFastTransparent = TRUE;
+#endif
+
+ Point aOutPos = pOutDev->LogicToPixel( rPos );
+ Size aOutSize;
+ BOOL bOldMap = pOutDev->mbMap;
+
+ if( pSize )
+ aOutSize = pOutDev->LogicToPixel( *pSize );
+ else
+ aOutSize = aSize;
+
+ pOutDev->mbMap = FALSE;
+
+ if ( nStyle & IMAGE_DRAW_DISABLE )
+ {
+ Point aOutPos1( aOutPos.X()+1, aOutPos.Y()+1 );
+ const Point aPos( IPOS( nPos) );
+ const StyleSettings& rSettings = pOutDev->GetSettings().GetStyleSettings();
+
+ if( !aDisa )
+ {
+ aDisa = Bitmap( aBmpEx.GetSizePixel(), 1 );
+ ImplUpdateDisaBmp( DISA_ALL );
+#ifndef REMOTE_APPSERVER
+ aDisaDisp = aDisa.CreateDisplayBitmap( pOutDev );
+#else // REMOTE_APPSERVER
+ aDisaDisp = aDisa;
+#endif // REMOTE_APPSERVER
+ }
+
+ if( !aDisaDisp && !!aDisa )
+ aDisaDisp = aDisa.CreateDisplayBitmap( pOutDev );
+
+ pOutDev->DrawMask( aOutPos1, aOutSize, aPos, aSize,
+ aDisaDisp, rSettings.GetLightColor() );
+ pOutDev->DrawMask( aOutPos, aOutSize, aPos, aSize,
+ aDisaDisp, rSettings.GetShadowColor() );
+ }
+ else
+ {
+ BOOL bDrawn = FALSE;
+
+ if( nStyle & ( IMAGE_DRAW_HIGHLIGHT | IMAGE_DRAW_DEACTIVE ) )
+ {
+ Bitmap aTmpBmp( aBmp );
+ BitmapWriteAccess* pAcc;
+
+ aTmpBmp.Crop( Rectangle( IPOS( nPos ), aSize ) );
+ pAcc = aTmpBmp.AcquireWriteAccess();
+
+ if( pAcc )
+ {
+ const StyleSettings& rSettings = pOutDev->GetSettings().GetStyleSettings();
+ Color aColor;
+ BitmapColor aCol;
+ const long nW = pAcc->Width();
+ const long nH = pAcc->Height();
+ BYTE* pMapR = new BYTE[ 256 ];
+ BYTE* pMapG = new BYTE[ 256 ];
+ BYTE* pMapB = new BYTE[ 256 ];
+ long nX, nY;
+
+ if( nStyle & IMAGE_DRAW_HIGHLIGHT )
+ aColor = rSettings.GetHighlightColor();
+ else
+ aColor = rSettings.GetDeactiveColor();
+
+ const BYTE cR = aColor.GetRed();
+ const BYTE cG = aColor.GetGreen();
+ const BYTE cB = aColor.GetBlue();
+
+ for( nX = 0L; nX < 256L; nX++ )
+ {
+ pMapR[ nX ] = (BYTE) ( ( ( nY = ( nX + cR ) >> 1 ) > 255 ) ? 255 : nY );
+ pMapG[ nX ] = (BYTE) ( ( ( nY = ( nX + cG ) >> 1 ) > 255 ) ? 255 : nY );
+ pMapB[ nX ] = (BYTE) ( ( ( nY = ( nX + cB ) >> 1 ) > 255 ) ? 255 : nY );
+ }
+
+ if( pAcc->HasPalette() )
+ {
+ for( USHORT i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ )
+ {
+ const BitmapColor& rCol = pAcc->GetPaletteColor( i );
+ aCol.SetRed( pMapR[ rCol.GetRed() ] );
+ aCol.SetGreen( pMapG[ rCol.GetGreen() ] );
+ aCol.SetBlue( pMapB[ rCol.GetBlue() ] );
+ pAcc->SetPaletteColor( i, aCol );
+ }
+ }
+ else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
+ {
+ for( nY = 0L; nY < nH; nY++ )
+ {
+ Scanline pScan = pAcc->GetScanline( nY );
+
+ for( nX = 0L; nX < nW; nX++ )
+ {
+ *pScan = pMapB[ *pScan ]; pScan++;
+ *pScan = pMapG[ *pScan ]; pScan++;
+ *pScan = pMapR[ *pScan ]; pScan++;
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0L; nY < nH; nY++ )
+ {
+ for( nX = 0L; nX < nW; nX++ )
+ {
+ aCol = pAcc->GetPixel( nY, nX );
+ aCol.SetRed( pMapR[ aCol.GetRed() ] );
+ aCol.SetGreen( pMapG[ aCol.GetGreen() ] );
+ aCol.SetBlue( pMapB[ aCol.GetBlue() ] );
+ pAcc->SetPixel( nY, nX, aCol );
+ }
+ }
+ }
+
+ delete[] pMapR;
+ delete[] pMapG;
+ delete[] pMapB;
+ aTmpBmp.ReleaseAccess( pAcc );
+
+ Bitmap aTmpMsk( aMask );
+ aTmpMsk.Crop( Rectangle( IPOS( nPos), aSize ) );
+ pOutDev->DrawBitmapEx( aOutPos, BitmapEx( aTmpBmp, aTmpMsk ) );
+ bDrawn = TRUE;
+ }
+ }
+
+ if( !bDrawn )
+ pOutDev->DrawBitmapEx( aOutPos, aOutSize, IPOS( nPos), aSize, aBmpEx );
+ }
+
+ pOutDev->mbMap = bOldMap;
+
+#ifdef FASTTRANSPARENT
+ bFastTransparent = bTmp;
+#endif
+ }
+ else if( pSize )
+ pOutDev->DrawBitmap( rPos, *pSize,
+ IPOS( nPos), aSize, aBmpEx.GetBitmap() );
+ else
+ pOutDev->DrawBitmap( rPos, pOutDev->PixelToLogic( aSize ),
+ IPOS( nPos), aSize, aBmpEx.GetBitmap() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::ImplUpdateDisaBmp( USHORT nPos )
+{
+ BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+ BitmapReadAccess* pMsk = aMask.AcquireReadAccess();
+ BitmapWriteAccess* pDis = aDisa.AcquireWriteAccess();
+
+ if( pAcc && pMsk && pDis )
+ {
+ const Color aWhite( COL_WHITE );
+ const Color aBlack( COL_BLACK );
+ const BitmapColor aAccWhite( pAcc->GetBestMatchingColor( aWhite ) );
+ const BitmapColor aMskWhite( pMsk->GetBestMatchingColor( aWhite ) );
+ const BitmapColor aDisWhite( pDis->GetBestMatchingColor( aWhite ) );
+ const BitmapColor aDisBlack( pDis->GetBestMatchingColor( aBlack ) );
+ long nLeft;
+ long nTop;
+ long nRight;
+ long nBottom;
+
+ if( DISA_ALL != nPos )
+ {
+ const Point aPos( IPOS( nPos ) );
+
+ nLeft = aPos.X();
+ nTop = aPos.Y();
+ nRight = nLeft + aSize.Width();
+ nBottom = nTop + aSize.Height();
+ }
+ else
+ {
+ nLeft = nTop = 0L;
+ nRight = pDis->Width();
+ nBottom = pDis->Height();
+ }
+
+ if( pAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_MSN_PAL &&
+ pMsk->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL )
+ {
+ // optimized version
+ const BYTE cAccTest = aAccWhite.GetIndex();
+ const BYTE cMskTest = aMskWhite.GetIndex();
+
+ for( long nY = nTop; nY < nBottom; nY++ )
+ {
+ Scanline pAccScan = pAcc->GetScanline( nY );
+ Scanline pMskScan = pMsk->GetScanline( nY );
+
+ for( long nX = nLeft; nX < nRight; nX++ )
+ {
+ if( ( cMskTest == ( pMskScan[ nX >> 3 ] & ( 1 << ( 7 - ( nX & 7 ) ) ) ? 1 : 0 ) ) ||
+ ( cAccTest == ( ( pAccScan[ nX >> 1 ] >> ( nX & 1 ? 0 : 4 ) ) & 0x0f ) ) )
+ {
+ pDis->SetPixel( nY, nX, aDisWhite );
+ }
+ else
+ pDis->SetPixel( nY, nX, aDisBlack );
+ }
+ }
+ }
+ else if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL &&
+ pMsk->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL )
+ {
+ // optimized version
+ const BYTE cAccTest = aAccWhite.GetIndex();
+ const BYTE cMskTest = aMskWhite.GetIndex();
+
+ for( long nY = nTop; nY < nBottom; nY++ )
+ {
+ Scanline pAccScan = pAcc->GetScanline( nY );
+ Scanline pMskScan = pMsk->GetScanline( nY );
+
+ for( long nX = nLeft; nX < nRight; nX++ )
+ {
+ if( ( cMskTest == ( pMskScan[ nX >> 3 ] & ( 1 << ( 7 - ( nX & 7 ) ) ) ? 1 : 0 ) ) ||
+ ( cAccTest == pAccScan[ nX ] ) )
+ {
+ pDis->SetPixel( nY, nX, aDisWhite );
+ }
+ else
+ pDis->SetPixel( nY, nX, aDisBlack );
+ }
+ }
+ }
+ else
+ {
+ for( long nY = nTop; nY < nBottom; nY++ )
+ {
+ for( long nX = nLeft; nX < nRight; nX++ )
+ {
+ if( ( aMskWhite == pMsk->GetPixel( nY, nX ) ) || ( aAccWhite == pAcc->GetPixel( nY, nX ) ) )
+ pDis->SetPixel( nY, nX, aDisWhite );
+ else
+ pDis->SetPixel( nY, nX, aDisBlack );
+ }
+ }
+ }
+ }
+
+ aBmp.ReleaseAccess( pAcc );
+ aMask.ReleaseAccess( pMsk );
+ aDisa.ReleaseAccess( pDis );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::ImplUpdatePaintBmp( USHORT nPos )
+{
+ BitmapWriteAccess* pBmp = aBmp.AcquireWriteAccess();
+ BitmapReadAccess* pMsk = aMask.AcquireReadAccess();
+
+ if ( pBmp && pMsk )
+ {
+ const Color aBlack( COL_BLACK );
+ const BitmapColor aBmpBlack( pBmp->GetBestMatchingColor( aBlack ) );
+ const BitmapColor aMskBlack( pMsk->GetBestMatchingColor( aBlack ) );
+ long nLeft, nTop, nRight, nBottom;
+
+ if( PAINT_ALL != nPos )
+ {
+ const Point aPos( IPOS( nPos ) );
+
+ nLeft = aPos.X();
+ nTop = aPos.Y();
+ nRight = nLeft + aSize.Width();
+ nBottom = nTop + aSize.Height();
+ }
+ else
+ {
+ nLeft = nTop = 0L;
+ nRight = pBmp->Width();
+ nBottom = pBmp->Height();
+ }
+
+ for( long nY = nTop; nY < nBottom; nY++ )
+ for( long nX = nLeft; nX < nRight; nX++ )
+ if( aMskBlack != pMsk->GetPixel( nY, nX ) )
+ pBmp->SetPixel( nY, nX, aBmpBlack );
+ }
+
+ aBmp.ReleaseAccess( pBmp );
+ aMask.ReleaseAccess( pMsk );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplImageBmp::ImplClearCaches()
+{
+ aBmpEx.Clear();
+ aBmpDisp = aMaskDisp = aDisaDisp = Bitmap();
+}
diff --git a/vcl/source/gdi/implncvt.cxx b/vcl/source/gdi/implncvt.cxx
new file mode 100644
index 000000000000..98a428d36380
--- /dev/null
+++ b/vcl/source/gdi/implncvt.cxx
@@ -0,0 +1,605 @@
+/*************************************************************************
+ *
+ * $RCSfile: implncvt.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALBTYPE_HXX
+#include "salbtype.hxx"
+#endif
+#ifndef _SV_IMPLNCVT_HXX
+#include "implncvt.hxx"
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define CURVE_LEFT 1
+#define CURVE_RIGHT 2
+#define CURVE_STRAIGHTON 3
+
+// -----------------
+// - ImplFloatPoint
+// -----------------
+
+struct ImplFloatPoint
+{
+ double fX;
+ double fY;
+
+ inline ImplFloatPoint() {}
+ inline ImplFloatPoint( const Point& rPoint ) { fX = rPoint.X(); fY = rPoint.Y(); }
+ inline ImplFloatPoint( double _fX, double _fY ) { fX = _fX; fY = _fY; }
+ inline ImplFloatPoint( const ImplFloatPoint& rPoint ) { fX = rPoint.fX; fY = rPoint.fY; }
+ inline ~ImplFloatPoint() {}
+
+ void operator+=( const ImplFloatPoint& rPoint ) { fX += rPoint.fX; fY += rPoint.fY; }
+ void operator-=( const ImplFloatPoint& rPoint ) { fX -= rPoint.fX; fY -= rPoint.fY; }
+ void operator*=( const double& rD ) { fX *= rD; fY *= rD; }
+ BOOL operator==( const ImplFloatPoint& rPoint ) const { return ( ( rPoint.fX == fX ) && ( rPoint.fY == fY ) ); } const
+ void operator=( const Point rPoint ) { fX = rPoint.X(); fY = rPoint.Y(); }
+
+ ImplFloatPoint GetOVec( const ImplFloatPoint& rPoint ) const;
+ ImplFloatPoint GetNVec( const ImplFloatPoint& rPoint ) const;
+};
+
+// -----------------------------------------------------------------------------
+
+ImplFloatPoint ImplFloatPoint::GetOVec( const ImplFloatPoint& rPoint ) const
+{
+ double fxt = rPoint.fX - fX;
+ double fyt = rPoint.fY - fY;
+ double fL;
+
+ if( fyt != 0.0 )
+ {
+ fyt = -fxt / fyt;
+ fL = sqrt( 1 + fyt * fyt );
+
+ return ImplFloatPoint( 1.0 / fL, fyt / fL );
+ }
+ else
+ return ImplFloatPoint( fyt, ( fxt > 0.0 ) ? 1.0 : -1.0 );
+};
+
+// -----------------------------------------------------------------------------
+
+ImplFloatPoint ImplFloatPoint::GetNVec( const ImplFloatPoint& rPoint ) const
+{
+ const double fxt = rPoint.fX - fX;
+ const double fyt = rPoint.fY - fY;
+ const double fL = hypot( fxt, fyt );
+
+ return ImplFloatPoint( fxt / fL, fyt / fL );
+};
+
+// --------------------
+// - ImplLineConverter
+// --------------------
+
+ImplLineConverter::ImplLineConverter( const Polygon& rPolygon, const LineInfo& rLineInfo, const Point* pRefPoint ) :
+ maLineInfo ( rLineInfo ),
+ mfWidthHalf ( rLineInfo.GetWidth() >> 1 ),
+ mpFloatPoint ( NULL ),
+ mpFloat0 ( new ImplFloatPoint[ 6 ] ),
+ mpFloat1 ( new ImplFloatPoint[ 6 ] ),
+ mnLines ( 0 )
+{
+ UINT16 nIndex, nPolySize = rPolygon.GetSize();
+ if ( nPolySize )
+ {
+ if( rPolygon.GetFlags( 0 ) == POLY_NORMAL )
+ {
+ mpFloatPoint = new ImplFloatPoint[ nPolySize ];
+ mpFloatPoint[ 0 ] = rPolygon[ 0 ];
+
+ nIndex = 0;
+
+ while( ++nIndex < nPolySize ) // doppelte Punkte eliminieren und ein FloatPointArray anlegen
+ {
+ if( rPolygon.GetFlags( nIndex ) == POLY_NORMAL )
+ {
+ double nxt = mpFloatPoint[ mnLines ].fX;
+ double nyt = mpFloatPoint[ mnLines ].fY;
+
+ if ( ( nxt == rPolygon[ nIndex ].X() ) && ( nyt == rPolygon[ nIndex ].Y() ) )
+ continue;
+
+ mpFloatPoint[ ++mnLines ] = rPolygon[ nIndex ];
+ }
+ else
+ {
+ DBG_ERROR( "Bezier points not supported!" );
+ }
+ }
+ mbClosed = ( mpFloatPoint[ 0 ] == mpFloatPoint[ mnLines ] ) ;
+
+ if ( ( mnLines == 1 ) && ( maLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ BOOL bX = mpFloatPoint[ 0 ].fY == mpFloatPoint[ 1 ].fY;
+ BOOL bY = mpFloatPoint[ 0 ].fX == mpFloatPoint[ 1 ].fX;
+ mbRefPoint = pRefPoint && ( bX || bY );
+ if ( mbRefPoint )
+ {
+ if ( !maLineInfo.GetDashCount() )
+ {
+ maLineInfo.SetDashCount( maLineInfo.GetDotCount() );
+ maLineInfo.SetDashLen( maLineInfo.GetDotLen() );
+ maLineInfo.SetDotCount( 0 );
+ }
+ INT32 nDistance = maLineInfo.GetDistance();
+ INT32 nDashLen = maLineInfo.GetDashCount() * ( maLineInfo.GetDashLen() + nDistance );
+ INT32 nDotLen = maLineInfo.GetDotCount() * ( maLineInfo.GetDotLen() + nDistance );
+ if ( bX )
+ {
+ if ( mpFloatPoint[ 1 ].fX > mpFloatPoint[ 0 ].fX )
+ {
+ ImplFloatPoint aFloat = mpFloatPoint[ 0 ];
+ mpFloatPoint[ 0 ] = mpFloatPoint[ 1 ];
+ mpFloatPoint[ 1 ] = aFloat;
+ }
+ mnRefDistance = (INT32)mpFloatPoint[ mnLines ].fX - pRefPoint->X();
+ }
+ else
+ {
+ if ( mpFloatPoint[ 1 ].fY > mpFloatPoint[ 0 ].fY )
+ {
+ ImplFloatPoint aFloat = mpFloatPoint[ 0 ];
+ mpFloatPoint[ 0 ] = mpFloatPoint[ 1 ];
+ mpFloatPoint[ 1 ] = aFloat;
+ }
+ mnRefDistance = (INT32)mpFloatPoint[ mnLines ].fY - pRefPoint->Y();
+ }
+
+// mnRefDistance = ( (INT32)mpFloatPoint[ mnLines ].fX - pRefPoint->X() ) +
+// ( (INT32)mpFloatPoint[ mnLines ].fY - pRefPoint->Y() );
+
+ mnRefDistance = mnRefDistance % ( nDashLen + nDotLen );
+ if ( mnRefDistance < 0 )
+ mnRefDistance = ( nDashLen + nDotLen ) + mnRefDistance;
+ }
+ }
+ }
+ }
+};
+
+//------------------------------------------------------------------------
+
+ImplLineConverter::~ImplLineConverter()
+{
+ delete[] mpFloat0;
+ delete[] mpFloat1;
+ delete[] mpFloatPoint;
+};
+
+//------------------------------------------------------------------------
+
+const Polygon* ImplLineConverter::ImplGetFirst()
+{
+ mnFloat1Points = 0;
+ mnLinesAvailable = mnLines;
+
+ if ( mnLines )
+ {
+ if ( maLineInfo.GetStyle() == LINE_DASH )
+ {
+ mnDashCount = maLineInfo.GetDashCount();
+ mnDotCount = maLineInfo.GetDotCount();
+ mfDashDotLenght = mnDashCount ? maLineInfo.GetDashLen() : maLineInfo.GetDotLen();
+
+ if ( mbRefPoint )
+ {
+ INT32 nDistance = maLineInfo.GetDistance();
+ INT32 nDashLen = maLineInfo.GetDashLen() + nDistance;
+ INT32 nDashesLen = maLineInfo.GetDashCount() * nDashLen;
+ INT32 nDotLen = maLineInfo.GetDotLen() + nDistance;
+ INT32 nDotsLen = maLineInfo.GetDotCount() * nDotLen;
+
+ if ( mnRefDistance >= nDashesLen )
+ {
+ // get dotcount
+ if ( nDotLen )
+ {
+ INT32 nLen = ( mnRefDistance - nDashesLen ) % nDotLen;
+ if ( nLen >= maLineInfo.GetDotLen() )
+ {
+ mnDotCount -= 1 + ( mnRefDistance - nDashesLen ) / nDotLen;
+ if ( mnDotCount )
+ mnDashCount = 0;
+ else
+ mnDotCount = maLineInfo.GetDotCount();
+ mfDashDotLenght = 0.0;
+ mfDistanceLenght = ( maLineInfo.GetDotLen() + nDistance ) - nLen;
+ }
+ else
+ {
+ mnDashCount = 0;
+ mfDashDotLenght = maLineInfo.GetDotLen() - nLen;
+ mnDotCount -= ( mnRefDistance - nDashesLen ) / nDotLen;
+ }
+ }
+ }
+ else
+ {
+ if ( nDashLen )
+ {
+ // get dashcount
+ INT32 nLen = mnRefDistance % nDashLen;
+ if ( nLen >= maLineInfo.GetDashLen() )
+ {
+ mfDashDotLenght = 0.0;
+ mfDistanceLenght = ( maLineInfo.GetDashLen() + nDistance ) - nLen;
+ mnDashCount -= 1 + ( mnRefDistance / nDashLen );
+ }
+ else
+ {
+ mfDashDotLenght = maLineInfo.GetDashLen() - nLen;
+ mnDashCount -= ( mnRefDistance / nDashLen );
+ }
+ }
+ }
+ if ( ! ( mnDashCount | mnDotCount ) )
+ {
+ mnDashCount = maLineInfo.GetDashCount();
+ mnDotCount = maLineInfo.GetDotCount();
+ }
+ if ( ( mfDashDotLenght == 0.0 ) && ( mfDistanceLenght == 0.0 ) )
+ mfDistanceLenght = maLineInfo.GetDistance();
+ }
+ }
+ }
+ return ImplGetNext();
+};
+
+//------------------------------------------------------------------------
+
+const Polygon* ImplLineConverter::ImplGetNext()
+{
+ while( mnFloat1Points || mnLinesAvailable )
+ {
+ if ( maLineInfo.GetWidth() > 1 )
+ {
+ if ( !mnFloat1Points )
+ {
+ ImplFloatPoint aPointA( mpFloatPoint[ mnLinesAvailable-- ] );
+ ImplFloatPoint aPointB( mpFloatPoint[ mnLinesAvailable ] );
+ ImplFloatPoint aOVecAB( aPointA.GetOVec( aPointB ) );
+ ImplFloatPoint aN1Vec( aPointA.GetNVec( aPointB ) );
+ aN1Vec *= mfWidthHalf;
+
+ if ( !mbClosed && ( ( mnLinesAvailable + 1 ) == mnLines ) )
+ aPointA -= aN1Vec;
+
+ aOVecAB *= mfWidthHalf;
+ mpFloat0[ 0 ] = aPointA;
+ mpFloat0[ 0 ] -= aOVecAB;
+ mpFloat0[ 3 ] = aPointA;
+ mpFloat0[ 3 ] += aOVecAB;
+ mpFloat0[ 1 ] = aPointB;
+ mpFloat0[ 1 ] -= aOVecAB;
+ mpFloat0[ 2 ] = aPointB;
+ mpFloat0[ 2 ] += aOVecAB;
+
+ double f1D = ( aN1Vec.fX == 0 ) ? 1 : ( aN1Vec.fY / aN1Vec.fX );
+ double f2D = -f1D;
+
+ mnFloat0Points = 4;
+
+ int nDirection;
+
+ BOOL bContinues = ( mnLinesAvailable || mbClosed );
+ if ( bContinues )
+ {
+ ImplFloatPoint aPointC;
+
+ if ( mnLinesAvailable )
+ aPointC = mpFloatPoint[ mnLinesAvailable - 1 ];
+ else
+ aPointC = mpFloatPoint[ mnLines - 1 ];
+
+ ImplFloatPoint aOVecBC( aPointB.GetOVec( aPointC ) );
+ aOVecBC *= mfWidthHalf;
+ ImplFloatPoint aPointR0( aPointB );
+ aPointR0 -= aOVecBC;
+ ImplFloatPoint aPointR1( aPointB );
+ aPointR1 += aOVecBC;
+ ImplFloatPoint aN2Vec( aPointB.GetNVec( aPointC ) );
+ aN2Vec *= mfWidthHalf;
+
+ f2D = ( aN2Vec.fX == 0 ) ? 1 : ( aN2Vec.fY / aN2Vec.fX );
+ if ( f1D == f2D )
+ nDirection = CURVE_STRAIGHTON;
+ else
+ {
+ if ( ( aN1Vec.fX * aN2Vec.fY - aN1Vec.fY * aN2Vec.fX ) > 0 )
+ nDirection = CURVE_LEFT;
+ else
+ nDirection = CURVE_RIGHT;
+ }
+ if ( nDirection != CURVE_STRAIGHTON )
+ {
+ double fWidth;
+ ImplFloatPoint aDestPoint;
+ if ( hypot( aPointR0.fX - aPointA.fX, aPointR0.fY - aPointA.fY ) > hypot( aPointR1.fX - aPointA.fX, aPointR1.fY - aPointA.fY ) )
+ aDestPoint = aPointR0;
+ else
+ aDestPoint = aPointR1;
+
+ UINT16 nFirst = 0;
+ if ( aN1Vec.fY > 0 )
+ {
+ if ( nDirection != CURVE_RIGHT )
+ nFirst++;
+ }
+ else
+ {
+ if ( nDirection == CURVE_RIGHT )
+ nFirst++;
+ }
+ fWidth = hypot( mpFloat0[ 1 + nFirst ].fX - aDestPoint.fX, mpFloat0[ 1 + nFirst ].fY - aDestPoint.fY );
+ fWidth = sqrt( fWidth * fWidth / 2 );
+ if ( fWidth > mfWidthHalf )
+ {
+ // Spitzer Winkel :
+ mnFloat0Points = 6;
+ mpFloat0[ 4 + nFirst ^ 1 ] = aDestPoint;
+ aDestPoint -= aN2Vec;
+ mpFloat0[ 4 + nFirst ] = aDestPoint;
+ mpFloat0[ 1 + nFirst ] += aN1Vec;
+ }
+ else
+ {
+ // Stumpferwinkel : Schnittpunkt wird berechnet
+ mnFloat0Points = 5;
+ ImplFloatPoint aSourcePoint;
+ double fX, fY, fBDest, fBSource;
+ aSourcePoint = mpFloat0[ 1 + nFirst ];
+
+ int nValid = 0;
+
+ if ( ( aN2Vec.fX ) == 0 )
+ {
+ fX = aDestPoint.fX;
+ nValid = 1;
+ }
+ else
+ fBDest = aDestPoint.fY - ( aN2Vec.fY / aN2Vec.fX * aDestPoint.fX );
+
+ if ( ( aN1Vec.fX ) == 0 )
+ {
+ fX = aSourcePoint.fX;
+ nValid = 2;
+ }
+ else
+ fBSource = aSourcePoint.fY - ( aN1Vec.fY / aN1Vec.fX * aSourcePoint.fX );
+
+ if ( !nValid )
+ fX = ( fBSource - fBDest ) / ( aN2Vec.fY / aN2Vec.fX - aN1Vec.fY / aN1Vec.fX );
+ if ( nValid < 2 )
+ fY = aN1Vec.fY / aN1Vec.fX * fX + fBSource;
+ else
+ fY = aN2Vec.fY / aN2Vec.fX * fX + fBDest;
+
+ mpFloat0[ 1 + nFirst ].fX = fX;
+ mpFloat0[ 1 + nFirst ].fY = fY;
+ mpFloat0[ 4 ] = aDestPoint;
+ }
+ }
+ else if ( ( aN1Vec.fX - aN2Vec.fX + aN1Vec.fY - aN2Vec.fY ) != 0 ) // besitzt zweiter Richtungsvektor die gleiche Steigung aber andere
+ bContinues = FALSE; // Richtung, dann wird hinten noch eine halbe Linienbreite angehaengt
+ }
+ if ( !bContinues )
+ {
+ mpFloat0[ 1 ] += aN1Vec;
+ mpFloat0[ 2 ] += aN1Vec;
+ }
+ }
+ else
+ {
+ mnFloat0Points = mnFloat1Points;
+ ImplFloatPoint* pTemp = mpFloat1;
+ mpFloat1 = mpFloat0;
+ mpFloat0 = pTemp;
+ }
+ if ( maLineInfo.GetStyle() == LINE_DASH )
+ {
+ double fLenghtDone = 0;
+ double fLenght = ( mfDashDotLenght > 0.0 ) ? mfDashDotLenght : mfDistanceLenght;
+
+ double fDistance;
+
+ fDistance = hypot( mpFloat0[ 0 ].fX - mpFloat0[ 1 ].fX, mpFloat0[ 0 ].fY - mpFloat0[ 1 ].fY );
+ if ( mnFloat0Points == 5 )
+ {
+ double fDist = hypot( mpFloat0[ 2 ].fX - mpFloat0[ 3 ].fX, mpFloat0[ 2 ].fY - mpFloat0[ 3 ].fY );
+ if ( fDist < fDistance )
+ fDistance = fDist;
+ }
+
+ if ( fDistance > fLenght )
+ {
+ fLenghtDone = fLenght;
+
+ ImplFloatPoint aNVec( mpFloat0[ 0 ].GetNVec( mpFloat0[ 1 ] ) );
+ aNVec *= fLenght;
+ mnFloat1Points = mnFloat0Points;
+ ImplFloatPoint* pTemp = mpFloat1;
+ mpFloat1 = mpFloat0;
+ mpFloat0 = pTemp;
+ mnFloat0Points = 4;
+ mpFloat0[ 0 ] = mpFloat0[ 1 ] = mpFloat1[ 0 ];
+ mpFloat0[ 1 ] += aNVec;
+ mpFloat0[ 2 ] = mpFloat0[ 3 ] = mpFloat1[ 3 ];
+ mpFloat0[ 2 ] += aNVec;
+
+ mpFloat1[ 0 ] = mpFloat0[ 1 ];
+ mpFloat1[ 3 ] = mpFloat0[ 2 ];
+ }
+ else
+ {
+ mnFloat1Points = 0;
+ fLenghtDone = fDistance;
+ }
+
+ if ( mfDashDotLenght > 0.0 )
+ { // Ein Dash oder Dot wurde erzeugt
+ mfDashDotLenght -= fLenghtDone;
+ if ( mfDashDotLenght == 0.0 )
+ { // Komplett erzeugt
+ if ( mnDashCount )
+ mnDashCount--;
+ else
+ mnDotCount--;
+
+ if ( ! ( mnDashCount | mnDotCount ) )
+ {
+ mnDashCount = maLineInfo.GetDashCount();
+ mnDotCount = maLineInfo.GetDotCount();
+ }
+ mfDistanceLenght = maLineInfo.GetDistance();
+ }
+ }
+ else
+ { // Das erzeugte Polygon muessen wir ignorieren
+ mfDistanceLenght -= fLenghtDone;
+ if ( mfDistanceLenght == 0.0 )
+ mfDashDotLenght = ( mnDashCount ) ? maLineInfo.GetDashLen() : maLineInfo.GetDotLen();
+ continue;
+ }
+ }
+ maPolygon.SetSize( (UINT16)mnFloat0Points );
+ UINT16 i = 0;
+ maPolygon[ i++ ] = Point( FRound( mpFloat0[ 0 ].fX ), FRound( mpFloat0[ 0 ].fY ) );
+ maPolygon[ i++ ] = Point( FRound( mpFloat0[ 1 ].fX ), FRound( mpFloat0[ 1 ].fY ) );
+ if ( mnFloat0Points > 4 )
+ maPolygon[ i++ ] = Point( FRound( mpFloat0[ 4 ].fX ), FRound( mpFloat0[ 4 ].fY ) );
+ if ( mnFloat0Points > 5 )
+ maPolygon[ i++ ] = Point( FRound( mpFloat0[ 5 ].fX ), FRound( mpFloat0[ 5 ].fY ) );
+ maPolygon[ i++ ] = Point( FRound( mpFloat0[ 2 ].fX ), FRound( mpFloat0[ 2 ].fY ) );
+ maPolygon[ i ] = Point( FRound( mpFloat0[ 3 ].fX ), FRound( mpFloat0[ 3 ].fY ) );
+
+ }
+ else
+ {
+ if ( !mnFloat1Points )
+ {
+ mpFloat0[ 0 ] = mpFloatPoint[ mnLinesAvailable-- ];
+ mpFloat0[ 1 ] = mpFloatPoint[ mnLinesAvailable ];
+ }
+ else
+ {
+ mpFloat0[ 0 ] = mpFloat1[ 0 ];
+ mpFloat0[ 1 ] = mpFloat1[ 1 ];
+ }
+ if ( maLineInfo.GetStyle() == LINE_DASH )
+ {
+ double fLenghtDone = 0;
+ double fLenght = ( mfDashDotLenght > 0.0 ) ? mfDashDotLenght : mfDistanceLenght;
+ double fDistance;
+ fDistance = hypot( mpFloat0[ 0 ].fX - mpFloat0[ 1 ].fX, mpFloat0[ 0 ].fY - mpFloat0[ 1 ].fY );
+ if ( fDistance > fLenght )
+ {
+ fLenghtDone = fLenght;
+ ImplFloatPoint aNVec( mpFloat0[ 0 ].GetNVec( mpFloat0[ 1 ] ) );
+ aNVec *= fLenght;
+ mpFloat1[ 1 ] = mpFloat0[ 1 ];
+ mpFloat0[ 1 ] = mpFloat0[ 0 ];
+ mpFloat0[ 1 ] += aNVec;
+ mpFloat1[ 0 ] = mpFloat0[ 1 ];
+ mnFloat1Points = 2;
+ }
+ else
+ {
+ mnFloat1Points = 0;
+ fLenghtDone = fDistance;
+ }
+ if ( mfDashDotLenght > 0.0 )
+ { // Ein Dash oder Dot wurde erzeugt
+ mfDashDotLenght -= fLenghtDone;
+ if ( mfDashDotLenght == 0.0 )
+ { // Komplett erzeugt
+ if ( mnDashCount )
+ mnDashCount--;
+ else
+ mnDotCount--;
+
+ if ( ! ( mnDashCount | mnDotCount ) )
+ {
+ mnDashCount = maLineInfo.GetDashCount();
+ mnDotCount = maLineInfo.GetDotCount();
+ }
+ mfDistanceLenght = maLineInfo.GetDistance();
+ }
+ }
+ else
+ { // Das erzeugte Polygon muessen wir ignorieren
+ mfDistanceLenght -= fLenghtDone;
+ if ( mfDistanceLenght == 0.0 )
+ mfDashDotLenght = ( mnDashCount ) ? maLineInfo.GetDashLen() : maLineInfo.GetDotLen();
+ continue;
+ }
+ }
+ maPolygon.SetSize( 2 );
+ maPolygon[ 0 ] = Point( (long)mpFloat0[ 0 ].fX, (long)mpFloat0[ 0 ].fY );
+ maPolygon[ 1 ] = Point( (long)mpFloat0[ 1 ].fX, (long)mpFloat0[ 1 ].fY );
+ }
+ return &maPolygon;
+ }
+ return NULL;
+};
diff --git a/vcl/source/gdi/implncvt.hxx b/vcl/source/gdi/implncvt.hxx
new file mode 100644
index 000000000000..5b4aa5bcee6e
--- /dev/null
+++ b/vcl/source/gdi/implncvt.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * $RCSfile: implncvt.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_LINECONV_HXX
+#define _SV_LINECONV_HXX
+
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_LINEINFO_HXX
+#include <lineinfo.hxx>
+#endif
+
+// --------------------
+// - ImplLineConverter
+// --------------------
+
+struct ImplFloatPoint;
+
+class ImplLineConverter
+{
+ BOOL mbClosed;
+ BOOL mbRefPoint;
+ INT32 mnRefDistance;
+
+ double mfWidthHalf;
+ LineInfo maLineInfo;
+
+ double mfDashDotLenght;
+ double mfDistanceLenght;
+
+ UINT32 mnDashCount;
+ UINT32 mnDotCount;
+
+ Polygon maPolygon;
+ UINT32 mnFloat0Points;
+ ImplFloatPoint* mpFloat0;
+ UINT32 mnFloat1Points;
+ ImplFloatPoint* mpFloat1;
+
+ UINT32 mnLinesAvailable;
+ UINT32 mnLines;
+
+ ImplFloatPoint* mpFloatPoint;
+
+ public:
+
+ ImplLineConverter( const Polygon& rPoly, const LineInfo& rLineInfo, const Point* pRefPoint );
+ ~ImplLineConverter();
+
+ const Polygon* ImplGetFirst();
+ const Polygon* ImplGetNext();
+};
+
+#endif
diff --git a/vcl/source/gdi/impprn.cxx b/vcl/source/gdi/impprn.cxx
new file mode 100644
index 000000000000..ce41b8cce763
--- /dev/null
+++ b/vcl/source/gdi/impprn.cxx
@@ -0,0 +1,256 @@
+/*************************************************************************
+ *
+ * $RCSfile: impprn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef REMOTE_APPSERVER
+
+#define _SV_IMPPRN_CXX
+#define _SPOOLPRINTER_EXT
+
+#ifndef _QUEUE_HXX
+#include <tools/queue.hxx>
+#endif
+
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_IMPPRN_HXX
+#include <impprn.hxx>
+#endif
+
+// =======================================================================
+
+struct QueuePage
+{
+ GDIMetaFile* mpMtf;
+ JobSetup* mpSetup;
+ USHORT mnPage;
+ BOOL mbEndJob;
+
+ QueuePage() { mpMtf = NULL; mpSetup = NULL; }
+ ~QueuePage() { delete mpMtf; if ( mpSetup ) delete mpSetup; }
+};
+
+// =======================================================================
+
+ImplQPrinter::ImplQPrinter( Printer* pParent ) :
+ Printer( pParent->GetName() )
+{
+ SetSelfAsQueuePrinter( TRUE );
+ SetPrinterProps( pParent );
+ SetPageQueueSize( 0 );
+ mpParent = pParent;
+ mnCopyCount = pParent->mnCopyCount;
+ mbCollateCopy = pParent->mbCollateCopy;
+ mpQueue = new Queue( mpParent->GetPageQueueSize() );
+ mbAborted = FALSE;
+ mbUserCopy = FALSE;
+ mbDestroyAllowed= TRUE;
+ mbDestroyed = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplQPrinter::~ImplQPrinter()
+{
+ QueuePage* pQueuePage = (QueuePage*)mpQueue->Get();
+ while ( pQueuePage )
+ {
+ delete pQueuePage;
+ pQueuePage = (QueuePage*)mpQueue->Get();
+ }
+
+ delete mpQueue;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplQPrinter::Destroy()
+{
+ if( mbDestroyAllowed )
+ delete this;
+ else
+ mbDestroyed = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ImplQPrinter, ImplPrintHdl, Timer*, EMPTYARG )
+{
+ // Ist Drucken abgebrochen wurden?
+ if ( !IsPrinting() )
+ return 0;
+
+ // Nur drucken, wenn genuegend Seiten im Cache stehen
+ if ( mpParent->IsJobActive() && (mpQueue->Count() < (ULONG)mpParent->GetPageQueueSize()) )
+ return 0;
+
+ // Druck-Job zuende?
+ QueuePage* pActPage = (QueuePage*) mpQueue->Get();
+
+ if ( pActPage->mbEndJob )
+ {
+ maTimer.Stop();
+ delete pActPage;
+ EndJob();
+ mpParent->ImplEndPrint();
+ }
+ else
+ {
+ USHORT nCopyCount = 1;
+ GDIMetaFile aMtf;
+
+ mbDestroyAllowed = FALSE;
+ GetPreparedMetaFile( *pActPage->mpMtf, aMtf );
+
+ if ( mbUserCopy && !mbCollateCopy )
+ nCopyCount = mnCopyCount;
+
+ for ( USHORT i = 0; i < nCopyCount; i++ )
+ {
+ ULONG nActionPos = 0UL;
+
+ if ( pActPage->mpSetup )
+ {
+ SetJobSetup( *pActPage->mpSetup );
+ if ( mbAborted )
+ break;
+ }
+
+ StartPage();
+
+ if ( mbAborted )
+ break;
+
+ for( MetaAction* pAct = aMtf.FirstAction(); pAct; pAct = aMtf.NextAction() )
+ {
+ pAct->Execute( this );
+ Application::Reschedule();
+
+ if( mbAborted )
+ break;
+ }
+
+ if( !mbAborted )
+ EndPage();
+ else
+ break;
+ }
+
+ delete pActPage;
+ mbDestroyAllowed = TRUE;
+
+ if( mbDestroyed )
+ Destroy();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplQPrinter::StartQueuePrint()
+{
+ maTimer.SetTimeout( 50 );
+ maTimer.SetTimeoutHdl( LINK( this, ImplQPrinter, ImplPrintHdl ) );
+ maTimer.Start();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplQPrinter::EndQueuePrint()
+{
+ QueuePage* pQueuePage = new QueuePage;
+ pQueuePage->mbEndJob = TRUE;
+ mpQueue->Put( pQueuePage );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplQPrinter::AbortQueuePrint()
+{
+ maTimer.Stop();
+ mbAborted = TRUE;
+ AbortJob();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplQPrinter::AddQueuePage( GDIMetaFile* pPage, USHORT nPage, BOOL bNewJobSetup )
+{
+ QueuePage* pQueuePage = new QueuePage;
+ pQueuePage->mpMtf = pPage;
+ pQueuePage->mnPage = nPage;
+ pQueuePage->mbEndJob = FALSE;
+ if ( bNewJobSetup )
+ pQueuePage->mpSetup = new JobSetup( mpParent->GetJobSetup() );
+ mpQueue->Put( pQueuePage );
+}
+
+#endif
diff --git a/vcl/source/gdi/impvect.cxx b/vcl/source/gdi/impvect.cxx
new file mode 100644
index 000000000000..2a3e27ebf2c5
--- /dev/null
+++ b/vcl/source/gdi/impvect.cxx
@@ -0,0 +1,1267 @@
+/*************************************************************************
+ *
+ * $RCSfile: impvect.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_IMPVECT_CXX
+
+#include <stdlib.h>
+#include <tools/new.hxx>
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_VECTORIZ_HXX
+#include <impvect.hxx>
+#endif
+
+// !!! ggf. einkommentieren, um Bitmaps zu erzeugen (nur, wenn File mit Debug uebersetzt wurde)
+// #define DEBUG_BMPOUTPUT
+
+#if defined DEBUG && defined DEBUG_BMPOUTPUT
+#define DBG_BMP 1
+#else
+#undef DBG_BMP
+#endif
+
+#ifdef DBG_BMP
+#include <tools/stream.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define VECT_POLY_MAX 8192
+
+// -----------------------------------------------------------------------------
+
+#define VECT_FREE_INDEX 0
+#define VECT_CONT_INDEX 1
+#define VECT_DONE_INDEX 2
+
+// -----------------------------------------------------------------------------
+
+#define VECT_POLY_INLINE_INNER 1UL
+#define VECT_POLY_INLINE_OUTER 2UL
+#define VECT_POLY_OUTLINE_INNER 4UL
+#define VECT_POLY_OUTLINE_OUTER 8UL
+
+// -----------------------------------------------------------------------------
+
+#define VECT_MAP( _def_pIn, _def_pOut, _def_nVal ) _def_pOut[_def_nVal]=(_def_pIn[_def_nVal]=((_def_nVal)*4L)+1L)+5L;
+#define BACK_MAP( _def_nVal ) ((((_def_nVal)+2)>>2)-1)
+#define VECT_PROGRESS( _def_pProgress, _def_nVal ) if(_def_pProgress&&_def_pProgress->IsSet())(_def_pProgress->Call((void*)_def_nVal));
+
+// -----------
+// - statics -
+// -----------
+
+struct ChainMove { long nDX; long nDY; };
+
+static ChainMove aImplMove[ 8 ] = {
+ { 1L, 0L },
+ { 0L, -1L },
+ { -1L, 0L },
+ { 0L, 1L },
+ { 1L, -1L },
+ { -1, -1L },
+ { -1L, 1L },
+ { 1L, 1L }
+ };
+
+static ChainMove aImplMoveInner[ 8 ] = {
+ { 0L, 1L },
+ { 1L, 0L },
+ { 0L, -1L },
+ { -1L, 0L },
+ { 0L, 1L },
+ { 1L, 0L },
+ { 0L, -1L },
+ { -1L, 0L }
+ };
+
+static ChainMove aImplMoveOuter[ 8 ] = {
+ { 0L, -1L },
+ { -1L, 0L },
+ { 0L, 1L },
+ { 1L, 0L },
+ { -1L, 0L },
+ { 0L, 1L },
+ { 1L, 0L },
+ { 0L, -1L }
+ };
+
+// ----------------
+// - ImplColorSet -
+// ----------------
+
+struct ImplColorSet
+{
+ BitmapColor maColor;
+ USHORT mnIndex;
+ BOOL mbSet;
+
+ BOOL operator<( const ImplColorSet& rSet ) const;
+ BOOL operator>( const ImplColorSet& rSet ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+inline BOOL ImplColorSet::operator<( const ImplColorSet& rSet ) const
+{
+ return( mbSet && ( !rSet.mbSet || ( maColor.GetLuminance() > rSet.maColor.GetLuminance() ) ) );
+}
+
+// ----------------------------------------------------------------------------
+
+inline BOOL ImplColorSet::operator>( const ImplColorSet& rSet ) const
+{
+ return( !mbSet || ( rSet.mbSet && maColor.GetLuminance() < rSet.maColor.GetLuminance() ) );
+}
+
+// ----------------------------------------------------------------------------
+
+extern "C" int __LOADONCALLAPI ImplColorSetCmpFnc( const void* p1, const void* p2 )
+{
+ ImplColorSet* pSet1 = (ImplColorSet*) p1;
+ ImplColorSet* pSet2 = (ImplColorSet*) p2;
+ int nRet;
+
+ if( pSet1->mbSet && pSet2->mbSet )
+ {
+ const BYTE cLum1 = pSet1->maColor.GetLuminance();
+ const BYTE cLum2 = pSet2->maColor.GetLuminance();
+ nRet = ( ( cLum1 > cLum2 ) ? -1 : ( ( cLum1 == cLum2 ) ? 0 : 1 ) );
+ }
+ else if( pSet1->mbSet )
+ nRet = -1;
+ else if( pSet2->mbSet )
+ nRet = 1;
+ else
+ nRet = 0;
+
+ return nRet;
+}
+
+// ------------------
+// - ImplPointArray -
+// ------------------
+
+#ifdef WIN
+typedef Point* huge HPPoint;
+#else
+typedef Point* HPPoint;
+#endif
+
+class ImplPointArray
+{
+ HPPoint mpArray;
+ ULONG mnSize;
+ ULONG mnRealSize;
+
+public:
+
+ ImplPointArray();
+ ~ImplPointArray();
+
+ void ImplSetSize( ULONG nSize );
+
+ ULONG ImplGetRealSize() const { return mnRealSize; }
+ void ImplSetRealSize( ULONG nRealSize ) { mnRealSize = nRealSize; }
+
+ inline Point& operator[]( ULONG nPos );
+ inline const Point& operator[]( ULONG nPos ) const;
+
+ void ImplCreatePoly( Polygon& rPoly ) const;
+};
+
+// -----------------------------------------------------------------------------
+
+ImplPointArray::ImplPointArray() :
+ mnSize ( 0UL ),
+ mnRealSize ( 0UL ),
+ mpArray ( NULL )
+
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ImplPointArray::~ImplPointArray()
+{
+ if( mpArray )
+ SvMemFree( mpArray );
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplPointArray::ImplSetSize( ULONG nSize )
+{
+ const ULONG nTotal = nSize * sizeof( Point );
+
+ mnSize = nSize;
+ mnRealSize = 0UL;
+
+ if( mpArray )
+ SvMemFree( mpArray );
+
+ mpArray = (HPPoint) SvMemAlloc( nTotal );
+ HMEMSET( (HPBYTE) mpArray, 0, nTotal );
+}
+
+// -----------------------------------------------------------------------------
+
+inline Point& ImplPointArray::operator[]( ULONG nPos )
+{
+ DBG_ASSERT( nPos < mnSize, "ImplPointArray::operator[]: nPos out of range!" );
+ return mpArray[ nPos ];
+}
+
+// -----------------------------------------------------------------------------
+
+inline const Point& ImplPointArray::operator[]( ULONG nPos ) const
+{
+ DBG_ASSERT( nPos < mnSize, "ImplPointArray::operator[]: nPos out of range!" );
+ return mpArray[ nPos ];
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplPointArray::ImplCreatePoly( Polygon& rPoly ) const
+{
+ rPoly.SetSize( (USHORT) mnRealSize );
+ HMEMCPY( rPoly.ImplGetPointAry(), mpArray, mnRealSize * sizeof( Point ) );
+}
+
+// ---------------
+// - ImplVectMap -
+// ---------------
+
+class ImplVectMap
+{
+private:
+
+ Scanline mpBuf;
+ Scanline* mpScan;
+ long mnWidth;
+ long mnHeight;
+
+ ImplVectMap() {};
+
+public:
+
+ ImplVectMap( long nWidth, long nHeight );
+ ~ImplVectMap();
+
+ inline long Width() const { return mnWidth; }
+ inline long Height() const { return mnHeight; }
+
+ inline void Set( long nY, long nX, BYTE cVal );
+ inline BYTE Get( long nY, long nX ) const;
+
+ inline BOOL IsFree( long nY, long nX ) const;
+ inline BOOL IsCont( long nY, long nX ) const;
+ inline BOOL IsDone( long nY, long nX ) const;
+
+#ifdef DBG_BMP
+ Bitmap GetBitmap() const;
+#endif // DBG_BMP
+};
+
+// -----------------------------------------------------------------------------
+
+ImplVectMap::ImplVectMap( long nWidth, long nHeight ) :
+ mnWidth ( nWidth ),
+ mnHeight( nHeight )
+{
+ const long nWidthAl = ( nWidth >> 2L ) + 1L;
+ const long nSize = nWidthAl * nHeight;
+ Scanline pTmp = mpBuf = (Scanline) SvMemAlloc( nSize );
+
+ HMEMSET( mpBuf, 0, nSize );
+ mpScan = (Scanline*) SvMemAlloc( nHeight * sizeof( Scanline ) );
+
+ for( long nY = 0L; nY < nHeight; pTmp += nWidthAl )
+ mpScan[ nY++ ] = pTmp;
+}
+
+// -----------------------------------------------------------------------------
+
+
+ImplVectMap::~ImplVectMap()
+{
+ SvMemFree( mpBuf );
+ SvMemFree( mpScan );
+}
+
+// -----------------------------------------------------------------------------
+
+inline void ImplVectMap::Set( long nY, long nX, BYTE cVal )
+{
+ const BYTE cShift = 6 - ( ( nX & 3 ) << 1 );
+ ( ( mpScan[ nY ][ nX >> 2 ] ) &= ~( 3 << cShift ) ) |= ( cVal << cShift );
+}
+
+// -----------------------------------------------------------------------------
+
+inline BYTE ImplVectMap::Get( long nY, long nX ) const
+{
+ return( ( ( mpScan[ nY ][ nX >> 2 ] ) >> ( 6 - ( ( nX & 3 ) << 1 ) ) ) & 3 );
+}
+
+// -----------------------------------------------------------------------------
+
+inline BOOL ImplVectMap::IsFree( long nY, long nX ) const
+{
+ return( VECT_FREE_INDEX == Get( nY, nX ) );
+}
+
+// -----------------------------------------------------------------------------
+
+inline BOOL ImplVectMap::IsCont( long nY, long nX ) const
+{
+ return( VECT_CONT_INDEX == Get( nY, nX ) );
+}
+
+// -----------------------------------------------------------------------------
+
+inline BOOL ImplVectMap::IsDone( long nY, long nX ) const
+{
+ return( VECT_DONE_INDEX == Get( nY, nX ) );
+}
+
+// -----------------------------------------------------------------------------
+
+#ifdef DBG_BMP
+Bitmap ImplVectMap::GetBitmap() const
+{
+ Bitmap aBmp( Size( mnWidth, mnHeight ), 4 );
+ BitmapWriteAccess* pAcc = aBmp.AcquireWriteAccess();
+
+ if( pAcc )
+ {
+ for( long nY = 0L; nY < mnHeight; nY++ )
+ {
+ for( long nX = 0L; nX < mnWidth; nX++ )
+ {
+ switch( Get( nY, nX ) )
+ {
+ case( VECT_FREE_INDEX ): pAcc->SetPixel( nY, nX, 15 ); break;
+ case( VECT_CONT_INDEX ): pAcc->SetPixel( nY, nX, 0 ); break;
+ case( VECT_DONE_INDEX ): pAcc->SetPixel( nY, nX, 2); break;
+ }
+ }
+ }
+
+ aBmp.ReleaseAccess( pAcc );
+ }
+
+ return aBmp;
+}
+#endif // DBG_BMP
+
+// -------------
+// - ImplChain -
+// -------------
+
+class ImplChain
+{
+private:
+
+ Polygon maPoly;
+ Point maStartPt;
+ ULONG mnArraySize;
+ ULONG mnCount;
+ long mnResize;
+ BYTE* mpCodes;
+
+ void ImplGetSpace();
+
+ void ImplCreate();
+ void ImplCreateInner();
+ void ImplCreateOuter();
+ void ImplPostProcess( const ImplPointArray& rArr );
+
+public:
+
+ ImplChain( ULONG nInitCount = 1024UL, long nResize = -1L );
+ ~ImplChain();
+
+ void ImplBeginAdd( const Point& rStartPt );
+ inline void ImplAdd( BYTE nCode );
+ void ImplEndAdd( ULONG nTypeFlag );
+
+ const Polygon& ImplGetPoly() { return maPoly; }
+};
+
+// -----------------------------------------------------------------------------
+
+ImplChain::ImplChain( ULONG nInitCount, long nResize ) :
+ mnCount ( 0UL ),
+ mnArraySize ( nInitCount ),
+ mnResize ( nResize )
+{
+ DBG_ASSERT( nInitCount && nResize, "ImplChain::ImplChain(): invalid parameters!" );
+ mpCodes = new BYTE[ mnArraySize ];
+}
+
+// -----------------------------------------------------------------------------
+
+ImplChain::~ImplChain()
+{
+ delete[] mpCodes;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplChain::ImplGetSpace()
+{
+ const ULONG nOldArraySize = mnArraySize;
+ BYTE* pNewCodes;
+
+ mnArraySize = ( mnResize < 0L ) ? ( mnArraySize << 1UL ) : ( mnArraySize + (ULONG) mnResize );
+ pNewCodes = new BYTE[ mnArraySize ];
+ HMEMCPY( pNewCodes, mpCodes, nOldArraySize );
+ delete[] mpCodes;
+ mpCodes = pNewCodes;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplChain::ImplBeginAdd( const Point& rStartPt )
+{
+ maPoly = Polygon();
+ maStartPt = rStartPt;
+ mnCount = 0UL;
+}
+
+// -----------------------------------------------------------------------------
+
+inline void ImplChain::ImplAdd( BYTE nCode )
+{
+ if( mnCount == mnArraySize )
+ ImplGetSpace();
+
+ mpCodes[ mnCount++ ] = nCode;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplChain::ImplEndAdd( ULONG nFlag )
+{
+ if( mnCount )
+ {
+ ImplPointArray aArr;
+
+ if( nFlag & VECT_POLY_INLINE_INNER )
+ {
+ long nFirstX, nFirstY;
+ long nLastX, nLastY;
+
+ nFirstX = nLastX = maStartPt.X();
+ nFirstY = nLastY = maStartPt.Y();
+ aArr.ImplSetSize( mnCount << 1 );
+
+ USHORT i, nPolyPos;
+ for( i = 0, nPolyPos = 0; i < ( mnCount - 1 ); i++ )
+ {
+ const BYTE cMove = mpCodes[ i ];
+ const BYTE cNextMove = mpCodes[ i + 1 ];
+ const ChainMove& rMove = aImplMove[ cMove ];
+ const ChainMove& rMoveInner = aImplMoveInner[ cMove ];
+ Point& rPt = aArr[ nPolyPos ];
+ BOOL bDone = TRUE;
+
+ nLastX += rMove.nDX;
+ nLastY += rMove.nDY;
+
+ if( cMove < 4 )
+ {
+ if( ( cMove == 0 && cNextMove == 3 ) ||
+ ( cMove == 3 && cNextMove == 2 ) ||
+ ( cMove == 2 && cNextMove == 1 ) ||
+ ( cMove == 1 && cNextMove == 0 ) )
+ {
+ }
+ else if( cMove == 2 && cNextMove == 3 )
+ {
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY - 1;
+
+ aArr[ nPolyPos ].X() = nLastX - 1;
+ aArr[ nPolyPos++ ].Y() = nLastY - 1;
+
+ aArr[ nPolyPos ].X() = nLastX - 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+ }
+ else if( cMove == 3 && cNextMove == 0 )
+ {
+ aArr[ nPolyPos ].X() = nLastX - 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+
+ aArr[ nPolyPos ].X() = nLastX - 1;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+ }
+ else if( cMove == 0 && cNextMove == 1 )
+ {
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+ }
+ else if( cMove == 1 && cNextMove == 2 )
+ {
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY - 1;
+
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY - 1;
+ }
+ else
+ bDone = FALSE;
+ }
+ else if( cMove == 7 && cNextMove == 0 )
+ {
+ aArr[ nPolyPos ].X() = nLastX - 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+ }
+ else if( cMove == 4 && cNextMove == 1 )
+ {
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+ }
+ else
+ bDone = FALSE;
+
+ if( !bDone )
+ {
+ aArr[ nPolyPos ].X() = nLastX + rMoveInner.nDX;
+ aArr[ nPolyPos++ ].Y() = nLastY + rMoveInner.nDY;
+ }
+ }
+
+ aArr[ nPolyPos ].X() = nFirstX + 1L;
+ aArr[ nPolyPos++ ].Y() = nFirstY + 1L;
+ aArr.ImplSetRealSize( nPolyPos );
+ }
+ else if( nFlag & VECT_POLY_INLINE_OUTER )
+ {
+ long nFirstX, nFirstY;
+ long nLastX, nLastY;
+
+ nFirstX = nLastX = maStartPt.X();
+ nFirstY = nLastY = maStartPt.Y();
+ aArr.ImplSetSize( mnCount << 1 );
+
+ USHORT i, nPolyPos;
+ for( i = 0, nPolyPos = 0; i < ( mnCount - 1 ); i++ )
+ {
+ const BYTE cMove = mpCodes[ i ];
+ const BYTE cNextMove = mpCodes[ i + 1 ];
+ const ChainMove& rMove = aImplMove[ cMove ];
+ const ChainMove& rMoveOuter = aImplMoveOuter[ cMove ];
+ Point& rPt = aArr[ nPolyPos ];
+ BOOL bDone = TRUE;
+
+ nLastX += rMove.nDX;
+ nLastY += rMove.nDY;
+
+ if( cMove < 4 )
+ {
+ if( ( cMove == 0 && cNextMove == 1 ) ||
+ ( cMove == 1 && cNextMove == 2 ) ||
+ ( cMove == 2 && cNextMove == 3 ) ||
+ ( cMove == 3 && cNextMove == 0 ) )
+ {
+ }
+ else if( cMove == 0 && cNextMove == 3 )
+ {
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY - 1;
+
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY - 1;
+
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+ }
+ else if( cMove == 3 && cNextMove == 2 )
+ {
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+ }
+ else if( cMove == 2 && cNextMove == 1 )
+ {
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+
+ aArr[ nPolyPos ].X() = nLastX - 1;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+
+ aArr[ nPolyPos ].X() = nLastX - 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+ }
+ else if( cMove == 1 && cNextMove == 0 )
+ {
+ aArr[ nPolyPos ].X() = nLastX - 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+
+ aArr[ nPolyPos ].X() = nLastX - 1;
+ aArr[ nPolyPos++ ].Y() = nLastY - 1;
+
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY - 1;
+ }
+ else
+ bDone = FALSE;
+ }
+ else if( cMove == 7 && cNextMove == 3 )
+ {
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY - 1;
+
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+ }
+ else if( cMove == 6 && cNextMove == 2 )
+ {
+ aArr[ nPolyPos ].X() = nLastX + 1;
+ aArr[ nPolyPos++ ].Y() = nLastY;
+
+ aArr[ nPolyPos ].X() = nLastX;
+ aArr[ nPolyPos++ ].Y() = nLastY + 1;
+ }
+ else
+ bDone = FALSE;
+
+ if( !bDone )
+ {
+ aArr[ nPolyPos ].X() = nLastX + rMoveOuter.nDX;
+ aArr[ nPolyPos++ ].Y() = nLastY + rMoveOuter.nDY;
+ }
+ }
+
+ aArr[ nPolyPos ].X() = nFirstX - 1L;
+ aArr[ nPolyPos++ ].Y() = nFirstY - 1L;
+ aArr.ImplSetRealSize( nPolyPos );
+ }
+ else
+ {
+ long nLastX = maStartPt.X(), nLastY = maStartPt.Y();
+
+ aArr.ImplSetSize( mnCount + 1 );
+ aArr[ 0 ] = Point( nLastX, nLastY );
+
+ for( ULONG i = 0; i < mnCount; )
+ {
+ const ChainMove& rMove = aImplMove[ mpCodes[ i ] ];
+ aArr[ ++i ] = Point( nLastX += rMove.nDX, nLastY += rMove.nDY );
+ }
+
+ aArr.ImplSetRealSize( mnCount + 1 );
+ }
+
+ ImplPostProcess( aArr );
+ }
+ else
+ maPoly.SetSize( 0 );
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplChain::ImplPostProcess( const ImplPointArray& rArr )
+{
+ ImplPointArray aNewArr1;
+ ImplPointArray aNewArr2;
+ Point* pLast;
+ Point* pLeast;
+ ULONG nNewPos;
+ ULONG nCount = rArr.ImplGetRealSize();
+ ULONG n;
+
+ // pass 1
+ aNewArr1.ImplSetSize( nCount );
+ pLast = &( aNewArr1[ 0 ] );
+ pLast->X() = BACK_MAP( rArr[ 0 ].X() );
+ pLast->Y() = BACK_MAP( rArr[ 0 ].Y() );
+
+ for( n = nNewPos = 1; n < nCount; )
+ {
+ const Point& rPt = rArr[ n++ ];
+ const long nX = BACK_MAP( rPt.X() );
+ const long nY = BACK_MAP( rPt.Y() );
+
+ if( nX != pLast->X() || nY != pLast->Y() )
+ {
+ pLast = pLeast = &( aNewArr1[ nNewPos++ ] );
+ pLeast->X() = nX;
+ pLeast->Y() = nY;
+ }
+ }
+
+ aNewArr1.ImplSetRealSize( nCount = nNewPos );
+
+ // pass 2
+ aNewArr2.ImplSetSize( nCount );
+ pLast = &( aNewArr2[ 0 ] );
+ *pLast = aNewArr1[ 0 ];
+
+ for( n = nNewPos = 1; n < nCount; )
+ {
+ pLeast = &( aNewArr1[ n++ ] );
+
+ if( pLeast->X() == pLast->X() )
+ {
+ while( n < nCount && aNewArr1[ n ].X() == pLast->X() )
+ pLeast = &( aNewArr1[ n++ ] );
+ }
+ else if( pLeast->Y() == pLast->Y() )
+ {
+ while( n < nCount && aNewArr1[ n ].Y() == pLast->Y() )
+ pLeast = &( aNewArr1[ n++ ] );
+ }
+
+ aNewArr2[ nNewPos++ ] = *( pLast = pLeast );
+ }
+
+ aNewArr2.ImplSetRealSize( nNewPos );
+ aNewArr2.ImplCreatePoly( maPoly );
+}
+
+// ------------------
+// - ImplVectorizer -
+// ------------------
+
+ImplVectorizer::ImplVectorizer()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ImplVectorizer::~ImplVectorizer()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ImplVectorizer::ImplVectorize( const Bitmap& rColorBmp, GDIMetaFile& rMtf,
+ BYTE cReduce, ULONG nFlags, const Link* pProgress )
+{
+ BOOL bRet = FALSE;
+
+ VECT_PROGRESS( pProgress, 0 );
+
+ Bitmap* pBmp = new Bitmap( rColorBmp );
+ BitmapReadAccess* pRAcc = pBmp->AcquireReadAccess();
+
+ if( pRAcc )
+ {
+ PolyPolygon aPolyPoly;
+ double fPercent = 0.0;
+ double fPercentStep_2 = 0.0;
+ const long nWidth = pRAcc->Width();
+ const long nHeight = pRAcc->Height();
+ const USHORT nColorCount = pRAcc->GetPaletteEntryCount();
+ USHORT n;
+ ImplColorSet* pColorSet = (ImplColorSet*) new BYTE[ 256 * sizeof( ImplColorSet ) ];
+
+ memset( pColorSet, 0, 256 * sizeof( ImplColorSet ) );
+ rMtf.Clear();
+
+ // get used palette colors and sort them from light to dark colors
+ for( n = 0; n < nColorCount; n++ )
+ {
+ pColorSet[ n ].mnIndex = n;
+ pColorSet[ n ].maColor = pRAcc->GetPaletteColor( n );
+ }
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pColorSet[ pRAcc->GetPixel( nY, nX ).GetIndex() ].mbSet = 1;
+
+ qsort( pColorSet, 256, sizeof( ImplColorSet ), ImplColorSetCmpFnc );
+
+ for( n = 0; n < 256; n++ )
+ if( !pColorSet[ n ].mbSet )
+ break;
+
+ if( n )
+ fPercentStep_2 = 45.0 / n;
+
+ VECT_PROGRESS( pProgress, FRound( fPercent += 10.0 ) );
+
+ for( USHORT i = 0; i < n; i++ )
+ {
+ const BitmapColor aBmpCol( pRAcc->GetPaletteColor( pColorSet[ i ].mnIndex ) );
+ const Color aFindColor( aBmpCol.GetRed(), aBmpCol.GetGreen(), aBmpCol.GetBlue() );
+ const BYTE cLum = aFindColor.GetLuminance();
+ ImplVectMap* pMap = ImplExpand( pRAcc, aFindColor );
+
+ VECT_PROGRESS( pProgress, FRound( fPercent += fPercentStep_2 ) );
+
+ if( pMap )
+ {
+ aPolyPoly.Clear();
+ ImplCalculate( pMap, aPolyPoly, cReduce, nFlags );
+ delete pMap;
+
+ if( aPolyPoly.Count() )
+ {
+ ImplLimitPolyPoly( aPolyPoly );
+
+ if( nFlags & BMP_VECTORIZE_REDUCE_EDGES )
+ aPolyPoly.Optimize( POLY_OPTIMIZE_EDGES );
+
+ if( aPolyPoly.Count() )
+ {
+ rMtf.AddAction( new MetaLineColorAction( aFindColor, TRUE ) );
+ rMtf.AddAction( new MetaFillColorAction( aFindColor, TRUE ) );
+ rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
+ }
+ }
+ }
+
+ VECT_PROGRESS( pProgress, FRound( fPercent += fPercentStep_2 ) );
+ }
+
+ delete[] (BYTE*) pColorSet;
+
+ if( rMtf.GetActionCount() )
+ {
+ MapMode aMap( MAP_100TH_MM );
+ VirtualDevice aVDev;
+ const Size aLogSize1( aVDev.PixelToLogic( Size( 1, 1 ), aMap ) );
+
+ rMtf.SetPrefMapMode( aMap );
+ rMtf.SetPrefSize( Size( nWidth + 2, nHeight + 2 ) );
+ rMtf.Move( 1, 1 );
+ rMtf.Scale( aLogSize1.Width(), aLogSize1.Height() );
+ bRet = TRUE;
+ }
+ }
+
+ pBmp->ReleaseAccess( pRAcc );
+ delete pBmp;
+ VECT_PROGRESS( pProgress, 100 );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ImplVectorizer::ImplVectorize( const Bitmap& rMonoBmp,
+ PolyPolygon& rPolyPoly,
+ ULONG nFlags, const Link* pProgress )
+{
+ Bitmap* pBmp = new Bitmap( rMonoBmp );
+ BitmapReadAccess* pRAcc;
+ ImplVectMap* pMap;
+ BOOL bRet = FALSE;
+
+ VECT_PROGRESS( pProgress, 10 );
+
+ if( pBmp->GetBitCount() > 1 )
+ pBmp->Convert( BMP_CONVERSION_1BIT_THRESHOLD );
+
+ VECT_PROGRESS( pProgress, 30 );
+
+ pRAcc = pBmp->AcquireReadAccess();
+ pMap = ImplExpand( pRAcc, COL_BLACK );
+ pBmp->ReleaseAccess( pRAcc );
+ delete pBmp;
+
+ VECT_PROGRESS( pProgress, 60 );
+
+ if( pMap )
+ {
+ rPolyPoly.Clear();
+ ImplCalculate( pMap, rPolyPoly, 0, nFlags );
+ delete pMap;
+ ImplLimitPolyPoly( rPolyPoly );
+
+ if( nFlags & BMP_VECTORIZE_REDUCE_EDGES )
+ rPolyPoly.Optimize( POLY_OPTIMIZE_EDGES );
+
+ bRet = TRUE;
+ }
+
+ VECT_PROGRESS( pProgress, 100 );
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplVectorizer::ImplLimitPolyPoly( PolyPolygon& rPolyPoly )
+{
+ if( rPolyPoly.Count() > VECT_POLY_MAX )
+ {
+ PolyPolygon aNewPolyPoly;
+ long nReduce = 0;
+ USHORT nNewCount;
+
+ do
+ {
+ aNewPolyPoly.Clear();
+ nReduce++;
+
+ for( USHORT i = 0, nCount = rPolyPoly.Count(); i < nCount; i++ )
+ {
+ const Rectangle aBound( rPolyPoly[ i ].GetBoundRect() );
+
+ if( aBound.GetWidth() > nReduce && aBound.GetHeight() > nReduce )
+ {
+ if( rPolyPoly[ i ].GetSize() )
+ aNewPolyPoly.Insert( rPolyPoly[ i ] );
+ }
+ }
+
+ nNewCount = aNewPolyPoly.Count();
+ }
+ while( nNewCount > VECT_POLY_MAX );
+
+ rPolyPoly = aNewPolyPoly;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+ImplVectMap* ImplVectorizer::ImplExpand( BitmapReadAccess* pRAcc, const Color& rColor )
+{
+ ImplVectMap* pMap = NULL;
+
+ if( pRAcc && pRAcc->Width() && pRAcc->Height() )
+ {
+ const long nOldWidth = pRAcc->Width();
+ const long nOldHeight = pRAcc->Height();
+ const long nNewWidth = ( nOldWidth << 2L ) + 4L;
+ const long nNewHeight = ( nOldHeight << 2L ) + 4L;
+ const BitmapColor aTest( pRAcc->GetBestMatchingColor( rColor ) );
+ long* pMapIn = new long[ Max( nOldWidth, nOldHeight ) ];
+ long* pMapOut = new long[ Max( nOldWidth, nOldHeight ) ];
+ long nX, nY, nTmpX, nTmpY;
+
+ pMap = new ImplVectMap( nNewWidth, nNewHeight );
+
+ for( nX = 0L; nX < nOldWidth; nX++ )
+ VECT_MAP( pMapIn, pMapOut, nX );
+
+ for( nY = 0L, nTmpY = 5L; nY < nOldHeight; nY++, nTmpY += 4L )
+ {
+ for( nX = 0L; nX < nOldWidth; )
+ {
+ if( pRAcc->GetPixel( nY, nX ) == aTest )
+ {
+ nTmpX = pMapIn[ nX++ ];
+ nTmpY -= 3L;
+
+ pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
+ pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
+ pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
+ pMap->Set( nTmpY, nTmpX, VECT_CONT_INDEX );
+
+ while( nX < nOldWidth && pRAcc->GetPixel( nY, nX ) == aTest )
+ nX++;
+
+ nTmpX = pMapOut[ nX - 1L ];
+ nTmpY -= 3L;
+
+ pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
+ pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
+ pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
+ pMap->Set( nTmpY, nTmpX, VECT_CONT_INDEX );
+ }
+ else
+ nX++;
+ }
+ }
+
+ for( nY = 0L; nY < nOldHeight; nY++ )
+ VECT_MAP( pMapIn, pMapOut, nY );
+
+ for( nX = 0L, nTmpX = 5L; nX < nOldWidth; nX++, nTmpX += 4L )
+ {
+ for( nY = 0L; nY < nOldHeight; )
+ {
+ if( pRAcc->GetPixel( nY, nX ) == aTest )
+ {
+ nTmpX -= 3L;
+ nTmpY = pMapIn[ nY++ ];
+
+ pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
+ pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
+ pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
+ pMap->Set( nTmpY, nTmpX, VECT_CONT_INDEX );
+
+ while( nY < nOldHeight && pRAcc->GetPixel( nY, nX ) == aTest )
+ nY++;
+
+ nTmpX -= 3L;
+ nTmpY = pMapOut[ nY - 1L ];
+
+ pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
+ pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
+ pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
+ pMap->Set( nTmpY, nTmpX, VECT_CONT_INDEX );
+ }
+ else
+ nY++;
+ }
+ }
+
+ // cleanup
+ delete[] pMapIn;
+ delete[] pMapOut;
+ }
+
+ return pMap;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplVectorizer::ImplCalculate( ImplVectMap* pMap, PolyPolygon& rPolyPoly, BYTE cReduce, ULONG nFlags )
+{
+ const long nWidth = pMap->Width(), nHeight= pMap->Height();
+
+#ifdef DBG_BMP
+ if( pMap )
+ {
+ SvFileStream aOStm( "d:\\cont.bmp", STREAM_WRITE | STREAM_TRUNC );
+ aOStm << pMap->GetBitmap();
+ }
+#endif // DBG_BMP
+
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ long nX = 0L;
+ BOOL bInner = TRUE;
+
+ while( nX < nWidth )
+ {
+ // skip free
+ while( ( nX < nWidth ) && pMap->IsFree( nY, nX ) )
+ nX++;
+
+ if( nX == nWidth )
+ break;
+
+ if( pMap->IsCont( nY, nX ) )
+ {
+ // new contour
+ ImplChain aChain;
+ const Point aStartPt( nX++, nY );
+
+ // get chain code
+ aChain.ImplBeginAdd( aStartPt );
+ ImplGetChain( pMap, aStartPt, aChain );
+
+ if( nFlags & BMP_VECTORIZE_INNER )
+ aChain.ImplEndAdd( bInner ? VECT_POLY_INLINE_INNER : VECT_POLY_INLINE_OUTER );
+ else
+ aChain.ImplEndAdd( bInner ? VECT_POLY_OUTLINE_INNER : VECT_POLY_OUTLINE_OUTER );
+
+ const Polygon& rPoly = aChain.ImplGetPoly();
+
+ if( rPoly.GetSize() > 2 )
+ {
+ if( cReduce )
+ {
+ const Rectangle aBound( rPoly.GetBoundRect() );
+
+ if( aBound.GetWidth() > cReduce && aBound.GetHeight() > cReduce )
+ rPolyPoly.Insert( rPoly );
+ }
+ else
+ rPolyPoly.Insert( rPoly );
+ }
+
+ // skip rest of detected contour
+ while( pMap->IsCont( nY, nX ) )
+ nX++;
+ }
+ else
+ {
+ // process done segment
+ const long nStartSegX = nX++;
+
+ while( pMap->IsDone( nY, nX ) )
+ nX++;
+
+ if( ( ( nX - nStartSegX ) == 1L ) || ( ImplIsUp( pMap, nY, nStartSegX ) != ImplIsUp( pMap, nY, nX - 1L ) ) )
+ bInner = !bInner;
+ }
+ }
+ }
+
+#ifdef DBG_BMP
+ if( pMap )
+ {
+ SvFileStream aOStm( "d:\\vect.bmp", STREAM_WRITE | STREAM_TRUNC );
+ aOStm << pMap->GetBitmap();
+ }
+#endif // DBG_BMP
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ImplVectorizer::ImplGetChain( ImplVectMap* pMap, const Point& rStartPt, ImplChain& rChain )
+{
+ long nActX = rStartPt.X();
+ long nActY = rStartPt.Y();
+ long nTryX;
+ long nTryY;
+ ULONG nFound;
+ ULONG nLastDir = 0UL;
+ ULONG nDir;
+
+ do
+ {
+ nFound = 0UL;
+
+ // first try last direction
+ nTryX = nActX + aImplMove[ nLastDir ].nDX;
+ nTryY = nActY + aImplMove[ nLastDir ].nDY;
+
+ if( pMap->IsCont( nTryY, nTryX ) )
+ {
+ rChain.ImplAdd( (BYTE) nLastDir );
+ pMap->Set( nActY = nTryY, nActX = nTryX, VECT_DONE_INDEX );
+ nFound = 1UL;
+ }
+ else
+ {
+ // try other directions
+ for( nDir = 0UL; nDir < 8UL; nDir++ )
+ {
+ // we already tried nLastDir
+ if( nDir != nLastDir )
+ {
+ nTryX = nActX + aImplMove[ nDir ].nDX;
+ nTryY = nActY + aImplMove[ nDir ].nDY;
+
+ if( pMap->IsCont( nTryY, nTryX ) )
+ {
+ rChain.ImplAdd( (BYTE) nDir );
+ pMap->Set( nActY = nTryY, nActX = nTryX, VECT_DONE_INDEX );
+ nFound = 1UL;
+ nLastDir = nDir;
+ break;
+ }
+ }
+ }
+ }
+ }
+ while( nFound );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ImplVectorizer::ImplIsUp( ImplVectMap* pMap, long nY, long nX ) const
+{
+ if( pMap->IsDone( nY - 1L, nX ) )
+ return TRUE;
+ else if( pMap->IsDone( nY + 1L, nX ) )
+ return FALSE;
+ else if( pMap->IsDone( nY - 1L, nX - 1L ) || pMap->IsDone( nY - 1L, nX + 1L ) )
+ return TRUE;
+ else
+ return FALSE;
+}
diff --git a/vcl/source/gdi/impvect.hxx b/vcl/source/gdi/impvect.hxx
new file mode 100644
index 000000000000..34750c220109
--- /dev/null
+++ b/vcl/source/gdi/impvect.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * $RCSfile: impvect.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_IMPVECT_HXX
+#define _SV_IMPVECT_HXX
+
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+
+// --------------
+// - Vectorizer -
+// --------------
+
+class BitmapReadAccess;
+class ImplChain;
+class ImplVectMap;
+
+class ImplVectorizer
+{
+private:
+
+ ImplVectMap* ImplExpand( BitmapReadAccess* pRAcc, const Color& rColor );
+ void ImplCalculate( ImplVectMap* pMap, PolyPolygon& rPolyPoly, BYTE cReduce, ULONG nFlags );
+ BOOL ImplGetChain( ImplVectMap* pMap, const Point& rStartPt, ImplChain& rChain );
+ BOOL ImplIsUp( ImplVectMap* pMap, long nY, long nX ) const;
+ void ImplLimitPolyPoly( PolyPolygon& rPolyPoly );
+
+public:
+
+ ImplVectorizer();
+ ~ImplVectorizer();
+
+ BOOL ImplVectorize( const Bitmap& rColorBmp, GDIMetaFile& rMtf,
+ BYTE cReduce, ULONG nFlags, const Link* pProgress );
+ BOOL ImplVectorize( const Bitmap& rMonoBmp, PolyPolygon& rPolyPoly,
+ ULONG nFlags, const Link* pProgress );
+};
+
+#endif
diff --git a/vcl/source/gdi/jobset.cxx b/vcl/source/gdi/jobset.cxx
new file mode 100644
index 000000000000..7edcf104d113
--- /dev/null
+++ b/vcl/source/gdi/jobset.cxx
@@ -0,0 +1,415 @@
+/*************************************************************************
+ *
+ * $RCSfile: jobset.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_JOBSET_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+
+#ifndef _SV_JOBSET_HXX
+#include <jobset.hxx>
+#endif
+#ifndef _SV_JOBSET_H
+#include <jobset.h>
+#endif
+
+// =======================================================================
+
+DBG_NAME( JobSetup );
+
+#define JOBSET_FILEFORMAT2 3780
+#define JOBSET_FILE364_SYSTEM ((USHORT)0xFFFF)
+
+struct ImplOldJobSetupData
+{
+ char cPrinterName[64];
+ char cDeviceName[32];
+ char cPortName[32];
+ char cDriverName[32];
+};
+
+struct Impl364JobSetupData
+{
+ SVBT16 nSize;
+ SVBT16 nSystem;
+ SVBT32 nDriverDataLen;
+ SVBT16 nOrientation;
+ SVBT16 nPaperBin;
+ SVBT16 nPaperFormat;
+ SVBT32 nPaperWidth;
+ SVBT32 nPaperHeight;
+};
+
+// =======================================================================
+
+ImplJobSetup::ImplJobSetup()
+{
+ mnRefCount = 1;
+ mnSystem = 0;
+ meOrientation = ORIENTATION_PORTRAIT;
+ mnPaperBin = 0;
+ mePaperFormat = PAPER_USER;
+ mnPaperWidth = 0;
+ mnPaperHeight = 0;
+ mnDriverDataLen = 0;
+ mpDriverData = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplJobSetup::ImplJobSetup( const ImplJobSetup& rJobSetup ) :
+ maPrinterName( rJobSetup.maPrinterName ),
+ maDriver( rJobSetup.maDriver )
+{
+ mnRefCount = 1;
+ mnSystem = rJobSetup.mnSystem;
+ meOrientation = rJobSetup.meOrientation;
+ mnPaperBin = rJobSetup.mnPaperBin;
+ mePaperFormat = rJobSetup.mePaperFormat;
+ mnPaperWidth = rJobSetup.mnPaperWidth;
+ mnPaperHeight = rJobSetup.mnPaperHeight;
+ mnDriverDataLen = rJobSetup.mnDriverDataLen;
+ if ( rJobSetup.mpDriverData )
+ {
+ mpDriverData = new BYTE[mnDriverDataLen];
+ memcpy( mpDriverData, rJobSetup.mpDriverData, mnDriverDataLen );
+ }
+ else
+ mpDriverData = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplJobSetup::~ImplJobSetup()
+{
+ delete mpDriverData;
+}
+
+// =======================================================================
+
+ImplJobSetup* JobSetup::ImplGetData()
+{
+ if ( !mpData )
+ mpData = new ImplJobSetup;
+ else if ( mpData->mnRefCount != 1 )
+ {
+ mpData->mnRefCount--;
+ mpData = new ImplJobSetup( *mpData );
+ }
+
+ return mpData;
+}
+
+// -----------------------------------------------------------------------
+
+ImplJobSetup* JobSetup::ImplGetConstData()
+{
+ if ( !mpData )
+ mpData = new ImplJobSetup;
+ return mpData;
+}
+
+// -----------------------------------------------------------------------
+
+const ImplJobSetup* JobSetup::ImplGetConstData() const
+{
+ if ( !mpData )
+ ((JobSetup*)this)->mpData = new ImplJobSetup;
+ return mpData;
+}
+
+// =======================================================================
+
+JobSetup::JobSetup()
+{
+ DBG_CTOR( JobSetup, NULL );
+
+ mpData = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+JobSetup::JobSetup( const JobSetup& rJobSetup )
+{
+ DBG_CTOR( JobSetup, NULL );
+ DBG_CHKOBJ( &rJobSetup, JobSetup, NULL );
+ DBG_ASSERT( !rJobSetup.mpData || (rJobSetup.mpData->mnRefCount < 0xFFFE), "JobSetup: RefCount overflow" );
+
+ mpData = rJobSetup.mpData;
+ if ( mpData )
+ mpData->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+JobSetup::~JobSetup()
+{
+ DBG_DTOR( JobSetup, NULL );
+
+ if ( mpData )
+ {
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString JobSetup::GetPrinterName() const
+{
+ if ( mpData )
+ return mpData->maPrinterName;
+ else
+ {
+ XubString aName;
+ return aName;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString JobSetup::GetDriverName() const
+{
+ if ( mpData )
+ return mpData->maDriver;
+ else
+ {
+ XubString aDriver;
+ return aDriver;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+JobSetup& JobSetup::operator=( const JobSetup& rJobSetup )
+{
+ DBG_CHKTHIS( JobSetup, NULL );
+ DBG_CHKOBJ( &rJobSetup, JobSetup, NULL );
+ DBG_ASSERT( !rJobSetup.mpData || (rJobSetup.mpData->mnRefCount) < 0xFFFE, "JobSetup: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ if ( rJobSetup.mpData )
+ rJobSetup.mpData->mnRefCount++;
+
+ // Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
+ // die letzte Referenz ist, sonst Referenzcounter decrementieren
+ if ( mpData )
+ {
+ if ( mpData->mnRefCount == 1 )
+ delete mpData;
+ else
+ mpData->mnRefCount--;
+ }
+
+ mpData = rJobSetup.mpData;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL JobSetup::operator==( const JobSetup& rJobSetup ) const
+{
+ DBG_CHKTHIS( JobSetup, NULL );
+ DBG_CHKOBJ( &rJobSetup, JobSetup, NULL );
+
+ if ( mpData == rJobSetup.mpData )
+ return TRUE;
+
+ if ( !mpData || !rJobSetup.mpData )
+ return FALSE;
+
+ ImplJobSetup* pData1 = mpData;
+ ImplJobSetup* pData2 = rJobSetup.mpData;
+ if ( (pData1->mnSystem == pData2->mnSystem) &&
+ (pData1->maPrinterName == pData2->maPrinterName) &&
+ (pData1->maDriver == pData2->maDriver) &&
+ (pData1->meOrientation == pData2->meOrientation) &&
+ (pData1->mnPaperBin == pData2->mnPaperBin) &&
+ (pData1->mePaperFormat == pData2->mePaperFormat) &&
+ (pData1->mnPaperWidth == pData2->mnPaperWidth) &&
+ (pData1->mnPaperHeight == pData2->mnPaperHeight) &&
+ (pData1->mnDriverDataLen == pData2->mnDriverDataLen) &&
+ (memcmp( pData1->mpDriverData, pData2->mpDriverData, pData1->mnDriverDataLen ) == 0) )
+ return TRUE;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, JobSetup& rJobSetup )
+{
+ DBG_ASSERTWARNING( rIStream.GetVersion(), "JobSetup::>> - Solar-Version not set on rOStream" );
+
+ // Zur Zeit haben wir noch kein neues FileFormat
+// if ( rIStream.GetVersion() < JOBSET_FILEFORMAT2 )
+ {
+ USHORT nLen;
+ USHORT nSystem;
+ rIStream >> nLen;
+ if ( !nLen )
+ return rIStream;
+ rIStream >> nSystem;
+ char* pTempBuf = new char[nLen];
+ rIStream.Read( pTempBuf, nLen - sizeof( nLen ) - sizeof( nSystem ) );
+ if ( nLen >= sizeof(ImplOldJobSetupData)+4 )
+ {
+ ImplOldJobSetupData* pData = (ImplOldJobSetupData*)pTempBuf;
+ if ( rJobSetup.mpData )
+ {
+ if ( rJobSetup.mpData->mnRefCount == 1 )
+ delete rJobSetup.mpData;
+ else
+ rJobSetup.mpData->mnRefCount--;
+ }
+ rJobSetup.mpData = new ImplJobSetup;
+ ImplJobSetup* pJobData = rJobSetup.mpData;
+ pJobData->maPrinterName = UniString( pData->cPrinterName, RTL_TEXTENCODING_UTF8 );
+ pJobData->maDriver = UniString( pData->cDriverName, RTL_TEXTENCODING_UTF8 );
+
+ // Sind es unsere neuen JobSetup-Daten?
+ if ( nSystem == JOBSET_FILE364_SYSTEM )
+ {
+ Impl364JobSetupData* pOldJobData = (Impl364JobSetupData*)(pTempBuf + sizeof( ImplOldJobSetupData ));
+ USHORT nOldJobDataSize = SVBT16ToShort( pOldJobData->nSize );
+ pJobData->mnSystem = SVBT16ToShort( pOldJobData->nSystem );
+ pJobData->mnDriverDataLen = SVBT32ToLong( pOldJobData->nDriverDataLen );
+ pJobData->meOrientation = (Orientation)SVBT16ToShort( pOldJobData->nOrientation );
+ pJobData->mnPaperBin = SVBT16ToShort( pOldJobData->nPaperBin );
+ pJobData->mePaperFormat = (Paper)SVBT16ToShort( pOldJobData->nPaperFormat );
+ pJobData->mnPaperWidth = (long)SVBT32ToLong( pOldJobData->nPaperWidth );
+ pJobData->mnPaperHeight = (long)SVBT32ToLong( pOldJobData->nPaperHeight );
+ if ( pJobData->mnDriverDataLen )
+ {
+ BYTE* pDriverData = ((BYTE*)pOldJobData) + nOldJobDataSize;
+ pJobData->mpDriverData = new BYTE[pJobData->mnDriverDataLen];
+ memcpy( pJobData->mpDriverData, pDriverData, pJobData->mnDriverDataLen );
+ }
+ }
+ }
+ delete pTempBuf;
+ }
+/*
+ else
+ {
+ }
+*/
+
+ return rIStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const JobSetup& rJobSetup )
+{
+ DBG_ASSERTWARNING( rOStream.GetVersion(), "JobSetup::<< - Solar-Version not set on rOStream" );
+
+ // Zur Zeit haben wir noch kein neues FileFormat
+// if ( rOStream.GetVersion() < JOBSET_FILEFORMAT2 )
+ {
+ USHORT nLen = 0;
+ if ( !rJobSetup.mpData )
+ rOStream << nLen;
+ else
+ {
+ USHORT nSystem = JOBSET_FILE364_SYSTEM;
+
+ const ImplJobSetup* pJobData = rJobSetup.ImplGetConstData();
+ Impl364JobSetupData aOldJobData;
+ USHORT nOldJobDataSize = sizeof( aOldJobData );
+ ShortToSVBT16( nOldJobDataSize, aOldJobData.nSize );
+ ShortToSVBT16( pJobData->mnSystem, aOldJobData.nSystem );
+ LongToSVBT32( pJobData->mnDriverDataLen, aOldJobData.nDriverDataLen );
+ ShortToSVBT16( (USHORT)(pJobData->meOrientation), aOldJobData.nOrientation );
+ ShortToSVBT16( pJobData->mnPaperBin, aOldJobData.nPaperBin );
+ ShortToSVBT16( (USHORT)(pJobData->mePaperFormat), aOldJobData.nPaperFormat );
+ LongToSVBT32( (ULONG)(pJobData->mnPaperWidth), aOldJobData.nPaperWidth );
+ LongToSVBT32( (ULONG)(pJobData->mnPaperHeight), aOldJobData.nPaperHeight );
+
+ ImplOldJobSetupData aOldData;
+ memset( &aOldData, 0, sizeof( aOldData ) );
+ ByteString aPrnByteName( rJobSetup.GetPrinterName(), RTL_TEXTENCODING_UTF8 );
+ strncpy( aOldData.cPrinterName, aPrnByteName.GetBuffer(), 63 );
+ ByteString aDriverByteName( rJobSetup.GetDriverName(), RTL_TEXTENCODING_UTF8 );
+ strncpy( aOldData.cDriverName, aDriverByteName.GetBuffer(), 31 );
+ nLen = sizeof( aOldData ) + 4 + nOldJobDataSize + pJobData->mnDriverDataLen;
+ rOStream << nLen;
+ rOStream << nSystem;
+ rOStream.Write( (char*)&aOldData, sizeof( aOldData ) );
+ rOStream.Write( (char*)&aOldJobData, nOldJobDataSize );
+ rOStream.Write( (char*)pJobData->mpDriverData, pJobData->mnDriverDataLen );
+ }
+ }
+/*
+ else
+ {
+ }
+*/
+
+ return rOStream;
+}
diff --git a/vcl/source/gdi/lineinfo.cxx b/vcl/source/gdi/lineinfo.cxx
new file mode 100644
index 000000000000..fde91e8ee702
--- /dev/null
+++ b/vcl/source/gdi/lineinfo.cxx
@@ -0,0 +1,300 @@
+/*************************************************************************
+ *
+ * $RCSfile: lineinfo.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_LINEINFO_CXX
+
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_LINEINFO_HXX
+#include <lineinfo.hxx>
+#endif
+
+DBG_NAME( LineInfo );
+
+// ----------------
+// - ImplLineInfo -
+// ----------------
+
+ImplLineInfo::ImplLineInfo() :
+ mnRefCount ( 1 ),
+ meStyle ( LINE_SOLID ),
+ mnWidth ( 0 ),
+ mnDashCount ( 0 ),
+ mnDashLen ( 0 ),
+ mnDotCount ( 0 ),
+ mnDotLen ( 0 ),
+ mnDistance ( 0 )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ImplLineInfo::ImplLineInfo( const ImplLineInfo& rImplLineInfo ) :
+ mnRefCount ( 1 ),
+ meStyle ( rImplLineInfo.meStyle ),
+ mnWidth ( rImplLineInfo.mnWidth ),
+ mnDashCount ( rImplLineInfo.mnDashCount ),
+ mnDashLen ( rImplLineInfo.mnDashLen ),
+ mnDotCount ( rImplLineInfo.mnDotCount ),
+ mnDotLen ( rImplLineInfo.mnDotLen ),
+ mnDistance ( rImplLineInfo.mnDistance )
+{
+}
+
+// ------------
+// - LineInfo -
+// ------------
+
+LineInfo::LineInfo( LineStyle eStyle, long nWidth )
+{
+ DBG_CTOR( LineInfo, NULL );
+ mpImplLineInfo = new ImplLineInfo;
+ mpImplLineInfo->meStyle = eStyle;
+ mpImplLineInfo->mnWidth = nWidth;
+}
+
+// -----------------------------------------------------------------------
+
+LineInfo::LineInfo( const LineInfo& rLineInfo )
+{
+ DBG_CTOR( LineInfo, NULL );
+ DBG_CHKOBJ( &rLineInfo, LineInfo, NULL );
+ mpImplLineInfo = rLineInfo.mpImplLineInfo;
+ mpImplLineInfo->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+LineInfo::~LineInfo()
+{
+ DBG_DTOR( LineInfo, NULL );
+ if( !( --mpImplLineInfo->mnRefCount ) )
+ delete mpImplLineInfo;
+}
+
+// -----------------------------------------------------------------------
+
+LineInfo& LineInfo::operator=( const LineInfo& rLineInfo )
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+ DBG_CHKOBJ( &rLineInfo, LineInfo, NULL );
+
+ rLineInfo.mpImplLineInfo->mnRefCount++;
+
+ if( !( --mpImplLineInfo->mnRefCount ) )
+ delete mpImplLineInfo;
+
+ mpImplLineInfo = rLineInfo.mpImplLineInfo;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL LineInfo::operator==( const LineInfo& rLineInfo ) const
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+ DBG_CHKOBJ( &rLineInfo, LineInfo, NULL );
+
+ return( mpImplLineInfo == rLineInfo.mpImplLineInfo ||
+ ( mpImplLineInfo->meStyle == rLineInfo.mpImplLineInfo->meStyle &&
+ mpImplLineInfo->mnWidth == rLineInfo.mpImplLineInfo->mnWidth &&
+ mpImplLineInfo->mnDashCount == rLineInfo.mpImplLineInfo->mnDashCount &&
+ mpImplLineInfo->mnDashLen == rLineInfo.mpImplLineInfo->mnDashLen &&
+ mpImplLineInfo->mnDotCount == rLineInfo.mpImplLineInfo->mnDotCount &&
+ mpImplLineInfo->mnDotLen == rLineInfo.mpImplLineInfo->mnDotLen &&
+ mpImplLineInfo->mnDistance == rLineInfo.mpImplLineInfo->mnDistance ) );
+}
+
+// -----------------------------------------------------------------------
+
+void LineInfo::ImplMakeUnique()
+{
+ if( mpImplLineInfo->mnRefCount != 1 )
+ {
+ if( mpImplLineInfo->mnRefCount )
+ mpImplLineInfo->mnRefCount--;
+
+ mpImplLineInfo = new ImplLineInfo( *mpImplLineInfo );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void LineInfo::SetStyle( LineStyle eStyle )
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+ ImplMakeUnique();
+ mpImplLineInfo->meStyle = eStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void LineInfo::SetWidth( long nWidth )
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+ ImplMakeUnique();
+ mpImplLineInfo->mnWidth = nWidth;
+}
+
+// -----------------------------------------------------------------------
+
+void LineInfo::SetDashCount( USHORT nDashCount )
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+ ImplMakeUnique();
+ mpImplLineInfo->mnDashCount = nDashCount;
+}
+
+// -----------------------------------------------------------------------
+
+void LineInfo::SetDashLen( long nDashLen )
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+ ImplMakeUnique();
+ mpImplLineInfo->mnDashLen = nDashLen;
+}
+
+// -----------------------------------------------------------------------
+
+void LineInfo::SetDotCount( USHORT nDotCount )
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+ ImplMakeUnique();
+ mpImplLineInfo->mnDotCount = nDotCount;
+}
+
+// -----------------------------------------------------------------------
+
+void LineInfo::SetDotLen( long nDotLen )
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+ ImplMakeUnique();
+ mpImplLineInfo->mnDotLen = nDotLen;
+}
+
+// -----------------------------------------------------------------------
+
+void LineInfo::SetDistance( long nDistance )
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+ ImplMakeUnique();
+ mpImplLineInfo->mnDistance = nDistance;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, ImplLineInfo& rImplLineInfo )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ UINT16 nTmp16;
+
+ rIStm >> nTmp16; rImplLineInfo.meStyle = (LineStyle) nTmp16;
+ rIStm >> rImplLineInfo.mnWidth;
+
+ if( aCompat.GetVersion() >= 2 )
+ {
+ // version 2
+ rIStm >> rImplLineInfo.mnDashCount >> rImplLineInfo.mnDashLen;
+ rIStm >> rImplLineInfo.mnDotCount >> rImplLineInfo.mnDotLen;
+ rIStm >> rImplLineInfo.mnDistance;
+ }
+
+ return rIStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const ImplLineInfo& rImplLineInfo )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 2 );
+
+ // version 1
+ rOStm << (UINT16) rImplLineInfo.meStyle << rImplLineInfo.mnWidth;
+
+ // since version2
+ rOStm << rImplLineInfo.mnDashCount << rImplLineInfo.mnDashLen;
+ rOStm << rImplLineInfo.mnDotCount << rImplLineInfo.mnDotLen;
+ rOStm << rImplLineInfo.mnDistance;
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, LineInfo& rLineInfo )
+{
+ rLineInfo.ImplMakeUnique();
+ return( rIStm >> *rLineInfo.mpImplLineInfo );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const LineInfo& rLineInfo )
+{
+ return( rOStm << *rLineInfo.mpImplLineInfo );
+}
diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk
new file mode 100644
index 000000000000..cecf617abb1c
--- /dev/null
+++ b/vcl/source/gdi/makefile.mk
@@ -0,0 +1,156 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=vcl
+TARGET=gdi
+
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+.IF "$(COM)"=="ICC"
+CDEFS+=-D_STD_NO_NAMESPACE -D_VOS_NO_NAMESPACE -D_UNO_NO_NAMESPACE
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/salmisc.obj \
+ $(SLO)$/animate.obj \
+ $(SLO)$/impanmvw.obj \
+ $(SLO)$/bitmap.obj \
+ $(SLO)$/bitmap2.obj \
+ $(SLO)$/bitmap3.obj \
+ $(SLO)$/bitmap4.obj \
+ $(SLO)$/alpha.obj \
+ $(SLO)$/bitmapex.obj \
+ $(SLO)$/imgcons.obj \
+ $(SLO)$/bmpacc.obj \
+ $(SLO)$/bmpacc2.obj \
+ $(SLO)$/bmpacc3.obj \
+ $(SLO)$/color.obj \
+ $(SLO)$/cvtsvm.obj \
+ $(SLO)$/cvtgrf.obj \
+ $(SLO)$/font.obj \
+ $(SLO)$/gdimtf.obj \
+ $(SLO)$/gfxlink.obj \
+ $(SLO)$/gradient.obj \
+ $(SLO)$/hatch.obj \
+ $(SLO)$/graph.obj \
+ $(SLO)$/image.obj \
+ $(SLO)$/impbmp.obj \
+ $(SLO)$/impgraph.obj \
+ $(SLO)$/impimage.obj \
+ $(SLO)$/impprn.obj \
+ $(SLO)$/impvect.obj \
+ $(SLO)$/implncvt.obj \
+ $(SLO)$/jobset.obj \
+ $(SLO)$/line.obj \
+ $(SLO)$/lineinfo.obj \
+ $(SLO)$/mapmod.obj \
+ $(SLO)$/metaact.obj \
+ $(SLO)$/metric.obj \
+ $(SLO)$/octree.obj \
+ $(SLO)$/outmap.obj \
+ $(SLO)$/outdev.obj \
+ $(SLO)$/outdev2.obj \
+ $(SLO)$/outdev3.obj \
+ $(SLO)$/outdev4.obj \
+ $(SLO)$/outdev5.obj \
+ $(SLO)$/outdev6.obj \
+ $(SLO)$/poly.obj \
+ $(SLO)$/poly2.obj \
+ $(SLO)$/print.obj \
+ $(SLO)$/print2.obj \
+ $(SLO)$/regband.obj \
+ $(SLO)$/region.obj \
+ $(SLO)$/virdev.obj \
+ $(SLO)$/wall.obj \
+ $(SLO)$/opengl.obj
+
+.IF "$(remote)"!=""
+EXCEPTIONSFILES= $(SLO)$/bitmap.obj \
+ $(SLO)$/color.obj \
+ $(SLO)$/gfxlink.obj \
+ $(SLO)$/impgraph.obj \
+ $(SLO)$/impvect.obj \
+ $(SLO)$/outdev.obj \
+ $(SLO)$/outdev3.obj \
+ $(SLO)$/outdev6.obj \
+ $(SLO)$/print.obj \
+ $(SLO)$/print2.obj \
+ $(SLO)$/virdev.obj
+
+.ELSE
+EXCEPTIONSFILES= $(SLO)$/outdev.obj \
+ $(SLO)$/gfxlink.obj \
+ $(SLO)$/impgraph.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/source/gdi/mapmod.cxx b/vcl/source/gdi/mapmod.cxx
new file mode 100644
index 000000000000..5690e1c7cf0f
--- /dev/null
+++ b/vcl/source/gdi/mapmod.cxx
@@ -0,0 +1,356 @@
+/*************************************************************************
+ *
+ * $RCSfile: mapmod.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_MAPMOD_CXX
+
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#define private public
+#ifndef _SV_MAPMOD_HXX
+#include <mapmod.hxx>
+#endif
+#undef private
+
+// =======================================================================
+
+DBG_NAME( MapMode );
+
+// -----------------------------------------------------------------------
+
+ImplMapMode::ImplMapMode() :
+ maOrigin( 0, 0 ),
+ maScaleX( 1, 1 ),
+ maScaleY( 1, 1 )
+{
+ mnRefCount = 1;
+ meUnit = MAP_PIXEL;
+ mbSimple = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplMapMode::ImplMapMode( const ImplMapMode& rImplMapMode ) :
+ maOrigin( rImplMapMode.maOrigin ),
+ maScaleX( rImplMapMode.maScaleX ),
+ maScaleY( rImplMapMode.maScaleY )
+{
+ mnRefCount = 1;
+ meUnit = rImplMapMode.meUnit;
+ mbSimple = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, ImplMapMode& rImplMapMode )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ UINT16 nTmp16;
+
+ rIStm >> nTmp16; rImplMapMode.meUnit = (MapUnit) nTmp16;
+ rIStm >> rImplMapMode.maOrigin >> rImplMapMode.maScaleX >>
+ rImplMapMode.maScaleY >> rImplMapMode.mbSimple;
+
+ return rIStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const ImplMapMode& rImplMapMode )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 1 );
+
+ rOStm << (UINT16) rImplMapMode.meUnit <<
+ rImplMapMode.maOrigin <<
+ rImplMapMode.maScaleX <<
+ rImplMapMode.maScaleY <<
+ rImplMapMode.mbSimple;
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------
+
+static ImplMapMode* ImplGetStaticMapMode( MapUnit eUnit )
+{
+ // Achtung: Ganz fies und dreckig !!!
+#ifdef WIN
+ static long _near aStaticImplMapModeAry[(MAP_LASTENUMDUMMY)*sizeof(ImplMapMode)/sizeof(long)];
+#else
+ static long aStaticImplMapModeAry[(MAP_LASTENUMDUMMY)*sizeof(ImplMapMode)/sizeof(long)];
+#endif
+
+ ImplMapMode* pImplMapMode = ((ImplMapMode*)aStaticImplMapModeAry)+eUnit;
+ if ( !pImplMapMode->mbSimple )
+ {
+ Fraction aDefFraction( 1, 1 );
+ pImplMapMode->maScaleX = aDefFraction;
+ pImplMapMode->maScaleY = aDefFraction;
+ pImplMapMode->meUnit = eUnit;
+ pImplMapMode->mbSimple = TRUE;
+ }
+
+ return pImplMapMode;
+}
+
+// -----------------------------------------------------------------------
+
+inline void MapMode::ImplMakeUnique()
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpImplMapMode->mnRefCount != 1 )
+ {
+ if ( mpImplMapMode->mnRefCount )
+ mpImplMapMode->mnRefCount--;
+ mpImplMapMode = new ImplMapMode( *mpImplMapMode );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+MapMode::MapMode()
+{
+ DBG_CTOR( MapMode, NULL );
+
+ mpImplMapMode = ImplGetStaticMapMode( MAP_PIXEL );
+}
+
+// -----------------------------------------------------------------------
+
+MapMode::MapMode( const MapMode& rMapMode )
+{
+ DBG_CTOR( MapMode, NULL );
+ DBG_CHKOBJ( &rMapMode, MapMode, NULL );
+ DBG_ASSERT( rMapMode.mpImplMapMode->mnRefCount < 0xFFFE, "MapMode: RefCount overflow" );
+
+ // shared Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpImplMapMode = rMapMode.mpImplMapMode;
+ // RefCount == 0 fuer statische Objekte
+ if ( mpImplMapMode->mnRefCount )
+ mpImplMapMode->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+MapMode::MapMode( MapUnit eUnit )
+{
+ DBG_CTOR( MapMode, NULL );
+
+ mpImplMapMode = ImplGetStaticMapMode( eUnit );
+}
+
+// -----------------------------------------------------------------------
+
+MapMode::MapMode( MapUnit eUnit, const Point& rLogicOrg,
+ const Fraction& rScaleX, const Fraction& rScaleY )
+{
+ DBG_CTOR( MapMode, NULL );
+
+ mpImplMapMode = new ImplMapMode;
+ mpImplMapMode->meUnit = eUnit;
+ mpImplMapMode->maOrigin = rLogicOrg;
+ mpImplMapMode->maScaleX = rScaleX;
+ mpImplMapMode->maScaleY = rScaleY;
+}
+
+// -----------------------------------------------------------------------
+
+MapMode::~MapMode()
+{
+ DBG_DTOR( MapMode, NULL );
+
+ // Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
+ // die letzte Referenz ist, sonst Referenzcounter decrementieren
+ if ( mpImplMapMode->mnRefCount )
+ {
+ if ( mpImplMapMode->mnRefCount == 1 )
+ delete mpImplMapMode;
+ else
+ mpImplMapMode->mnRefCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void MapMode::SetMapUnit( MapUnit eUnit )
+{
+ DBG_CHKTHIS( MapMode, NULL );
+
+ ImplMakeUnique();
+ mpImplMapMode->meUnit = eUnit;
+}
+
+// -----------------------------------------------------------------------
+
+void MapMode::SetOrigin( const Point& rLogicOrg )
+{
+ DBG_CHKTHIS( MapMode, NULL );
+
+ ImplMakeUnique();
+ mpImplMapMode->maOrigin = rLogicOrg;
+}
+
+// -----------------------------------------------------------------------
+
+void MapMode::SetScaleX( const Fraction& rScaleX )
+{
+ DBG_CHKTHIS( MapMode, NULL );
+
+ ImplMakeUnique();
+ mpImplMapMode->maScaleX = rScaleX;
+}
+
+// -----------------------------------------------------------------------
+
+void MapMode::SetScaleY( const Fraction& rScaleY )
+{
+ DBG_CHKTHIS( MapMode, NULL );
+
+ ImplMakeUnique();
+ mpImplMapMode->maScaleY = rScaleY;
+}
+
+// -----------------------------------------------------------------------
+
+MapMode& MapMode::operator=( const MapMode& rMapMode )
+{
+ DBG_CHKTHIS( MapMode, NULL );
+ DBG_CHKOBJ( &rMapMode, MapMode, NULL );
+ DBG_ASSERT( rMapMode.mpImplMapMode->mnRefCount < 0xFFFE, "MapMode: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ // RefCount == 0 fuer statische Objekte
+ if ( rMapMode.mpImplMapMode->mnRefCount )
+ rMapMode.mpImplMapMode->mnRefCount++;
+
+ // Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
+ // die letzte Referenz ist, sonst Referenzcounter decrementieren
+ if ( mpImplMapMode->mnRefCount )
+ {
+ if ( mpImplMapMode->mnRefCount == 1 )
+ delete mpImplMapMode;
+ else
+ mpImplMapMode->mnRefCount--;
+ }
+
+ mpImplMapMode = rMapMode.mpImplMapMode;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MapMode::operator==( const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( MapMode, NULL );
+ DBG_CHKOBJ( &rMapMode, MapMode, NULL );
+
+ if ( mpImplMapMode == rMapMode.mpImplMapMode )
+ return TRUE;
+
+ if ( (mpImplMapMode->meUnit == rMapMode.mpImplMapMode->meUnit) &&
+ (mpImplMapMode->maOrigin == rMapMode.mpImplMapMode->maOrigin) &&
+ (mpImplMapMode->maScaleX == rMapMode.mpImplMapMode->maScaleX) &&
+ (mpImplMapMode->maScaleY == rMapMode.mpImplMapMode->maScaleY) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MapMode::IsDefault() const
+{
+ DBG_CHKTHIS( MapMode, NULL );
+
+ ImplMapMode* pDefMapMode = ImplGetStaticMapMode( MAP_PIXEL );
+ if ( mpImplMapMode == pDefMapMode )
+ return TRUE;
+
+ if ( (mpImplMapMode->meUnit == pDefMapMode->meUnit) &&
+ (mpImplMapMode->maOrigin == pDefMapMode->maOrigin) &&
+ (mpImplMapMode->maScaleX == pDefMapMode->maScaleX) &&
+ (mpImplMapMode->maScaleY == pDefMapMode->maScaleY) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, MapMode& rMapMode )
+{
+ rMapMode.ImplMakeUnique();
+ return (rIStm >> *rMapMode.mpImplMapMode);
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const MapMode& rMapMode )
+{
+ return (rOStm << *rMapMode.mpImplMapMode);
+}
diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx
new file mode 100644
index 000000000000..caa28f1ee856
--- /dev/null
+++ b/vcl/source/gdi/metaact.cxx
@@ -0,0 +1,3434 @@
+/*************************************************************************
+ *
+ * $RCSfile: metaact.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_METAACT_CXX
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+
+#include <string.h>
+
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+
+// ========================================================================
+
+inline void ImplScalePoint( Point& rPt, double fScaleX, double fScaleY )
+{
+ rPt.X() = FRound( fScaleX * rPt.X() );
+ rPt.Y() = FRound( fScaleY * rPt.Y() );
+}
+
+// ------------------------------------------------------------------------
+
+inline void ImplScaleSize( Size& rSz, double fScaleX, double fScaleY )
+{
+ rSz.Width() = FRound( fScaleX * rSz.Width() );
+ rSz.Height() = FRound( fScaleY * rSz.Height() );
+}
+
+// ------------------------------------------------------------------------
+
+inline void ImplScaleRect( Rectangle& rRect, double fScaleX, double fScaleY )
+{
+ Point aTL( rRect.TopLeft() );
+ Point aBR( rRect.BottomRight() );
+
+ ImplScalePoint( aTL, fScaleX, fScaleY );
+ ImplScalePoint( aBR, fScaleX, fScaleY );
+
+ rRect = Rectangle( aTL, aBR );
+}
+
+// ------------------------------------------------------------------------
+
+inline void ImplScalePoly( Polygon& rPoly, double fScaleX, double fScaleY )
+{
+ for( USHORT i = 0, nCount = rPoly.GetSize(); i < nCount; i++ )
+ ImplScalePoint( rPoly[ i ], fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+inline void ImplScaleLineInfo( LineInfo& rLineInfo, double fScaleX, double fScaleY )
+{
+ if( !rLineInfo.IsDefault() )
+ {
+ const double fScale = ( fScaleX + fScaleY ) * 0.5;
+
+ rLineInfo.SetWidth( FRound( fScale * rLineInfo.GetWidth() ) );
+ rLineInfo.SetDashLen( FRound( fScale * rLineInfo.GetDashLen() ) );
+ rLineInfo.SetDotLen( FRound( fScale * rLineInfo.GetDotLen() ) );
+ rLineInfo.SetDistance( FRound( fScale * rLineInfo.GetDistance() ) );
+ }
+}
+
+// ========================================================================
+
+#define COMPAT( _def_rIStm ) VersionCompat aCompat( ( _def_rIStm ), STREAM_READ );
+#define COMPAT_VERSION() aCompat.GetVersion()
+#define WRITE_BASE_COMPAT( _def_rOStm, _def_nVer, _pWriteData ) \
+ MetaAction::Write( ( _def_rOStm ), _pWriteData ); \
+ VersionCompat aCompat( ( _def_rOStm ), STREAM_WRITE, ( _def_nVer ) );
+
+// ========================================================================
+
+MetaAction::MetaAction() :
+ mnRefCount( 1 ),
+ mnType( META_NULL_ACTION )
+{
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction::MetaAction( USHORT nType ) :
+ mnRefCount( 1 ),
+ mnType( nType )
+{
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction::~MetaAction()
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaAction::Execute( OutputDevice* pOut )
+{
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaAction::Clone()
+{
+ return new MetaAction;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaAction::Move( long nHorzMove, long nVertMove )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaAction::Scale( double fScaleX, double fScaleY )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaAction::Write( SvStream& rOStm, ImplMetaWriteData* )
+{
+ rOStm << mnType;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ rIStm >> mnType;
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaAction::ReadMetaAction( SvStream& rIStm, ImplMetaReadData* pData )
+{
+ MetaAction* pAction = NULL;
+ UINT16 nType;
+
+ rIStm >> nType;
+
+ switch( nType )
+ {
+ case( META_NULL_ACTION ): pAction = new MetaAction; break;
+ case( META_PIXEL_ACTION ): pAction = new MetaPixelAction; break;
+ case( META_POINT_ACTION ): pAction = new MetaPointAction; break;
+ case( META_LINE_ACTION ): pAction = new MetaLineAction; break;
+ case( META_RECT_ACTION ): pAction = new MetaRectAction; break;
+ case( META_ROUNDRECT_ACTION ): pAction = new MetaRoundRectAction; break;
+ case( META_ELLIPSE_ACTION ): pAction = new MetaEllipseAction; break;
+ case( META_ARC_ACTION ): pAction = new MetaArcAction; break;
+ case( META_PIE_ACTION ): pAction = new MetaPieAction; break;
+ case( META_CHORD_ACTION ): pAction = new MetaChordAction; break;
+ case( META_POLYLINE_ACTION ): pAction = new MetaPolyLineAction; break;
+ case( META_POLYGON_ACTION ): pAction = new MetaPolygonAction; break;
+ case( META_POLYPOLYGON_ACTION ): pAction = new MetaPolyPolygonAction; break;
+ case( META_TEXT_ACTION ): pAction = new MetaTextAction; break;
+ case( META_TEXTARRAY_ACTION ): pAction = new MetaTextArrayAction; break;
+ case( META_STRETCHTEXT_ACTION ): pAction = new MetaStretchTextAction; break;
+ case( META_TEXTRECT_ACTION ): pAction = new MetaTextRectAction; break;
+ case( META_TEXTLINE_ACTION ): pAction = new MetaTextLineAction; break;
+ case( META_BMP_ACTION ): pAction = new MetaBmpAction; break;
+ case( META_BMPSCALE_ACTION ): pAction = new MetaBmpScaleAction; break;
+ case( META_BMPSCALEPART_ACTION ): pAction = new MetaBmpScalePartAction; break;
+ case( META_BMPEX_ACTION ): pAction = new MetaBmpExAction; break;
+ case( META_BMPEXSCALE_ACTION ): pAction = new MetaBmpExScaleAction; break;
+ case( META_BMPEXSCALEPART_ACTION ): pAction = new MetaBmpExScalePartAction; break;
+ case( META_MASK_ACTION ): pAction = new MetaMaskAction; break;
+ case( META_MASKSCALE_ACTION ): pAction = new MetaMaskScaleAction; break;
+ case( META_MASKSCALEPART_ACTION ): pAction = new MetaMaskScalePartAction; break;
+ case( META_GRADIENT_ACTION ): pAction = new MetaGradientAction; break;
+ case( META_GRADIENTEX_ACTION ): pAction = new MetaGradientExAction; break;
+ case( META_HATCH_ACTION ): pAction = new MetaHatchAction; break;
+ case( META_WALLPAPER_ACTION ): pAction = new MetaWallpaperAction; break;
+ case( META_CLIPREGION_ACTION ): pAction = new MetaClipRegionAction; break;
+ case( META_ISECTRECTCLIPREGION_ACTION ): pAction = new MetaISectRectClipRegionAction; break;
+ case( META_ISECTREGIONCLIPREGION_ACTION ): pAction = new MetaISectRegionClipRegionAction; break;
+ case( META_MOVECLIPREGION_ACTION ): pAction = new MetaMoveClipRegionAction; break;
+ case( META_LINECOLOR_ACTION ): pAction = new MetaLineColorAction; break;
+ case( META_FILLCOLOR_ACTION ): pAction = new MetaFillColorAction; break;
+ case( META_TEXTCOLOR_ACTION ): pAction = new MetaTextColorAction; break;
+ case( META_TEXTFILLCOLOR_ACTION ): pAction = new MetaTextFillColorAction; break;
+ case( META_TEXTLINECOLOR_ACTION ): pAction = new MetaTextLineColorAction; break;
+ case( META_TEXTALIGN_ACTION ): pAction = new MetaTextAlignAction; break;
+ case( META_MAPMODE_ACTION ): pAction = new MetaMapModeAction; break;
+ case( META_FONT_ACTION ): pAction = new MetaFontAction; break;
+ case( META_PUSH_ACTION ): pAction = new MetaPushAction; break;
+ case( META_POP_ACTION ): pAction = new MetaPopAction; break;
+ case( META_RASTEROP_ACTION ): pAction = new MetaRasterOpAction; break;
+ case( META_TRANSPARENT_ACTION ): pAction = new MetaTransparentAction; break;
+ case( META_FLOATTRANSPARENT_ACTION ): pAction = new MetaFloatTransparentAction; break;
+ case( META_EPS_ACTION ): pAction = new MetaEPSAction; break;
+ case( META_REFPOINT_ACTION ): pAction = new MetaRefPointAction; break;
+ case( META_COMMENT_ACTION ): pAction = new MetaCommentAction; break;
+
+ default:
+ {
+ // Action ueberlesen durch Kombination Ctor/Dtor,
+ // new/delete, weil Compiler sonst vielleicht wegoptimieren
+ delete ( new VersionCompat( rIStm, STREAM_READ ) );
+ }
+ break;
+ }
+
+ if( pAction )
+ pAction->Read( rIStm, pData );
+
+ return pAction;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Pixel, META_PIXEL_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaPixelAction::MetaPixelAction( const Point& rPt, const Color& rColor ) :
+ MetaAction ( META_PIXEL_ACTION ),
+ maPt ( rPt ),
+ maColor ( rColor )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPixelAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawPixel( maPt, maColor );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaPixelAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaPixelAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPixelAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPixelAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPixelAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maPt;
+ maColor.Write( rOStm, TRUE );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPixelAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maPt;
+ maColor.Read( rIStm, TRUE );
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Point, META_POINT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaPointAction::MetaPointAction( const Point& rPt ) :
+ MetaAction ( META_POINT_ACTION ),
+ maPt ( rPt )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPointAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawPixel( maPt );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaPointAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaPointAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPointAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPointAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPointAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maPt;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPointAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maPt;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Line, META_LINE_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaLineAction::MetaLineAction( const Point& rStart, const Point& rEnd ) :
+ MetaAction ( META_LINE_ACTION ),
+ maStartPt ( rStart ),
+ maEndPt ( rEnd )
+{
+}
+
+// ------------------------------------------------------------------------
+
+MetaLineAction::MetaLineAction( const Point& rStart, const Point& rEnd,
+ const LineInfo& rLineInfo ) :
+ MetaAction ( META_LINE_ACTION ),
+ maLineInfo ( rLineInfo ),
+ maStartPt ( rStart ),
+ maEndPt ( rEnd )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaLineAction::Execute( OutputDevice* pOut )
+{
+ if( maLineInfo.IsDefault() )
+ pOut->DrawLine( maStartPt, maEndPt );
+ else
+ pOut->DrawLine( maStartPt, maEndPt, maLineInfo );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaLineAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaLineAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaLineAction::Move( long nHorzMove, long nVertMove )
+{
+ maStartPt.Move( nHorzMove, nVertMove );
+ maEndPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaLineAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maStartPt, fScaleX, fScaleY );
+ ImplScalePoint( maEndPt, fScaleX, fScaleY );
+ ImplScaleLineInfo( maLineInfo, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaLineAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 2, pData );
+
+ rOStm << maStartPt << maEndPt; // Version 1
+ rOStm << maLineInfo; // Version 2
+}
+
+// ------------------------------------------------------------------------
+
+void MetaLineAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+
+ // Version 1
+ rIStm >> maStartPt >> maEndPt;
+
+ // Version 2
+ if( aCompat.GetVersion() >= 2 )
+ {
+ rIStm >> maLineInfo;
+ }
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Rect, META_RECT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaRectAction::MetaRectAction( const Rectangle& rRect ) :
+ MetaAction ( META_RECT_ACTION ),
+ maRect ( rRect )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRectAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawRect( maRect );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaRectAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaRectAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRectAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRectAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRectAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRect;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRectAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRect;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( RoundRect, META_ROUNDRECT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaRoundRectAction::MetaRoundRectAction( const Rectangle& rRect,
+ long nHorzRound, long nVertRound ) :
+ MetaAction ( META_ROUNDRECT_ACTION ),
+ maRect ( rRect ),
+ mnHorzRound ( nHorzRound ),
+ mnVertRound ( nVertRound )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRoundRectAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawRect( maRect, mnHorzRound, mnVertRound );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaRoundRectAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaRoundRectAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRoundRectAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRoundRectAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+ mnHorzRound = FRound( mnHorzRound * fScaleX );
+ mnVertRound = FRound( mnVertRound * fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRoundRectAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRect << mnHorzRound << mnVertRound;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRoundRectAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRect >> mnHorzRound >> mnVertRound;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Ellipse, META_ELLIPSE_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaEllipseAction::MetaEllipseAction( const Rectangle& rRect ) :
+ MetaAction ( META_ELLIPSE_ACTION ),
+ maRect ( rRect )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEllipseAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawEllipse( maRect );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaEllipseAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaEllipseAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEllipseAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEllipseAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEllipseAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRect;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEllipseAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRect;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Arc, META_ARC_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaArcAction::MetaArcAction( const Rectangle& rRect,
+ const Point& rStart, const Point& rEnd ) :
+ MetaAction ( META_ARC_ACTION ),
+ maRect ( rRect ),
+ maStartPt ( rStart ),
+ maEndPt ( rEnd )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaArcAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawArc( maRect, maStartPt, maEndPt );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaArcAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaArcAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaArcAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+ maStartPt.Move( nHorzMove, nVertMove );
+ maEndPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaArcAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+ ImplScalePoint( maStartPt, fScaleX, fScaleY );
+ ImplScalePoint( maEndPt, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaArcAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRect << maStartPt << maEndPt;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaArcAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRect >> maStartPt >> maEndPt;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Pie, META_PIE_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaPieAction::MetaPieAction( const Rectangle& rRect,
+ const Point& rStart, const Point& rEnd ) :
+ MetaAction ( META_PIE_ACTION ),
+ maRect ( rRect ),
+ maStartPt ( rStart ),
+ maEndPt ( rEnd )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPieAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawPie( maRect, maStartPt, maEndPt );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaPieAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaPieAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPieAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+ maStartPt.Move( nHorzMove, nVertMove );
+ maEndPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPieAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+ ImplScalePoint( maStartPt, fScaleX, fScaleY );
+ ImplScalePoint( maEndPt, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPieAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRect << maStartPt << maEndPt;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPieAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRect >> maStartPt >> maEndPt;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Chord, META_CHORD_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaChordAction::MetaChordAction( const Rectangle& rRect,
+ const Point& rStart, const Point& rEnd ) :
+ MetaAction ( META_CHORD_ACTION ),
+ maRect ( rRect ),
+ maStartPt ( rStart ),
+ maEndPt ( rEnd )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaChordAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawChord( maRect, maStartPt, maEndPt );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaChordAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaChordAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaChordAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+ maStartPt.Move( nHorzMove, nVertMove );
+ maEndPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaChordAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+ ImplScalePoint( maStartPt, fScaleX, fScaleY );
+ ImplScalePoint( maEndPt, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaChordAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRect << maStartPt << maEndPt;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaChordAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRect >> maStartPt >> maEndPt;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( PolyLine, META_POLYLINE_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaPolyLineAction::MetaPolyLineAction( const Polygon& rPoly ) :
+ MetaAction ( META_POLYLINE_ACTION ),
+ maPoly ( rPoly )
+{
+}
+
+// ------------------------------------------------------------------------
+
+MetaPolyLineAction::MetaPolyLineAction( const Polygon& rPoly, const LineInfo& rLineInfo ) :
+ MetaAction ( META_POLYLINE_ACTION ),
+ maLineInfo ( rLineInfo ),
+ maPoly ( rPoly )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyLineAction::Execute( OutputDevice* pOut )
+{
+ if( maLineInfo.IsDefault() )
+ pOut->DrawPolyLine( maPoly );
+ else
+ pOut->DrawPolyLine( maPoly, maLineInfo );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaPolyLineAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaPolyLineAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyLineAction::Move( long nHorzMove, long nVertMove )
+{
+ maPoly.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyLineAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoly( maPoly, fScaleX, fScaleY );
+ ImplScaleLineInfo( maLineInfo, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyLineAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 2, pData );
+
+ rOStm << maPoly; // Version 1
+ rOStm << maLineInfo; // Version 2
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyLineAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+
+ // Version 1
+ rIStm >> maPoly;
+
+ // Version 2
+ if( aCompat.GetVersion() >= 2 )
+ {
+ rIStm >> maLineInfo;
+ }
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Polygon, META_POLYGON_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaPolygonAction::MetaPolygonAction( const Polygon& rPoly ) :
+ MetaAction ( META_POLYGON_ACTION ),
+ maPoly ( rPoly )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolygonAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawPolygon( maPoly );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaPolygonAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaPolygonAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolygonAction::Move( long nHorzMove, long nVertMove )
+{
+ maPoly.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolygonAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoly( maPoly, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolygonAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maPoly;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolygonAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maPoly;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( PolyPolygon, META_POLYPOLYGON_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaPolyPolygonAction::MetaPolyPolygonAction( const PolyPolygon& rPolyPoly ) :
+ MetaAction ( META_POLYPOLYGON_ACTION ),
+ maPolyPoly ( rPolyPoly )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyPolygonAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawPolyPolygon( maPolyPoly );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaPolyPolygonAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaPolyPolygonAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyPolygonAction::Move( long nHorzMove, long nVertMove )
+{
+ maPolyPoly.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyPolygonAction::Scale( double fScaleX, double fScaleY )
+{
+ for( USHORT i = 0, nCount = maPolyPoly.Count(); i < nCount; i++ )
+ ImplScalePoly( maPolyPoly[ i ], fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyPolygonAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maPolyPoly;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPolyPolygonAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maPolyPoly;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Text, META_TEXT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaTextAction::MetaTextAction( const Point& rPt, const XubString& rStr,
+ USHORT nIndex, USHORT nLen ) :
+ MetaAction ( META_TEXT_ACTION ),
+ maPt ( rPt ),
+ maStr ( rStr ),
+ mnIndex ( nIndex ),
+ mnLen ( nLen )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawText( maPt, maStr, mnIndex, mnLen );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaTextAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaTextAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maPt;
+ rOStm.WriteByteString( maStr, pData->meActualCharSet );
+ rOStm << mnIndex;
+ rOStm << mnLen;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextAction::Read( SvStream& rIStm, ImplMetaReadData* pData )
+{
+ COMPAT( rIStm );
+ rIStm >> maPt;
+ rIStm.ReadByteString( maStr, pData->meActualCharSet );
+ rIStm >> mnIndex;
+ rIStm >> mnLen;
+}
+
+// ========================================================================
+
+MetaTextArrayAction::MetaTextArrayAction() :
+ MetaAction ( META_TEXTARRAY_ACTION ),
+ mpDXAry ( NULL ),
+ mnIndex ( 0 ),
+ mnLen ( 0 )
+{
+}
+
+// ------------------------------------------------------------------------
+
+MetaTextArrayAction::MetaTextArrayAction( const MetaTextArrayAction& rAction ) :
+ MetaAction ( META_TEXTARRAY_ACTION ),
+ maStartPt ( rAction.maStartPt ),
+ maStr ( rAction.maStr ),
+ mnIndex ( rAction.mnIndex ),
+ mnLen ( rAction.mnLen )
+{
+ if( rAction.mpDXAry )
+ {
+ const ULONG nAryLen = mnLen - 1;
+
+ mpDXAry = new long[ nAryLen ];
+ memcpy( mpDXAry, rAction.mpDXAry, nAryLen * sizeof( long ) );
+ }
+ else
+ mpDXAry = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+MetaTextArrayAction::MetaTextArrayAction( const Point& rStartPt,
+ const XubString& rStr,
+ const long* pDXAry,
+ USHORT nIndex,
+ USHORT nLen ) :
+ MetaAction ( META_TEXTARRAY_ACTION ),
+ maStartPt ( rStartPt ),
+ maStr ( rStr ),
+ mnIndex ( nIndex ),
+ mnLen ( ( nLen == STRING_LEN ) ? rStr.Len() : nLen )
+{
+ const ULONG nAryLen = ( ( mnLen > 1 ) && pDXAry ) ? ( mnLen - 1 ) : 0UL;
+
+ if( nAryLen )
+ {
+ mpDXAry = new long[ nAryLen ];
+ memcpy( mpDXAry, pDXAry, nAryLen * sizeof( long ) );
+ }
+ else
+ mpDXAry = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+MetaTextArrayAction::~MetaTextArrayAction()
+{
+ delete[] mpDXAry;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextArrayAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawTextArray( maStartPt, maStr, mpDXAry, mnIndex, mnLen );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaTextArrayAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaTextArrayAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextArrayAction::Move( long nHorzMove, long nVertMove )
+{
+ maStartPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextArrayAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maStartPt, fScaleX, fScaleY );
+
+ if ( mpDXAry && mnLen )
+ {
+ for ( USHORT i = 0, nCount = mnLen - 1; i < nCount; i++ )
+ mpDXAry[ i ] = FRound( mpDXAry[ i ] * fScaleX );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextArrayAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ const ULONG nAryLen = ( ( mnLen > 1 ) && mpDXAry ) ? ( mnLen - 1 ) : 0UL;
+
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maStartPt;
+ rOStm.WriteByteString( maStr, pData->meActualCharSet );
+ rOStm << mnIndex;
+ rOStm << mnLen;
+ rOStm << nAryLen;
+
+ for( ULONG i = 0UL; i < nAryLen; i++ )
+ rOStm << mpDXAry[ i ];
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextArrayAction::Read( SvStream& rIStm, ImplMetaReadData* pData )
+{
+ ULONG nAryLen;
+
+ delete[] mpDXAry;
+
+ COMPAT( rIStm );
+ rIStm >> maStartPt;
+ rIStm.ReadByteString( maStr, pData->meActualCharSet );
+ rIStm >> mnIndex;
+ rIStm >> mnLen;
+ rIStm >> nAryLen;
+
+ if( nAryLen )
+ {
+ mpDXAry = new long[ nAryLen ];
+
+ for( ULONG i = 0UL; i < nAryLen; i++ )
+ rIStm >> mpDXAry[ i ];
+ }
+ else
+ mpDXAry = NULL;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( StretchText, META_STRETCHTEXT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaStretchTextAction::MetaStretchTextAction( const Point& rPt, ULONG nWidth,
+ const XubString& rStr,
+ USHORT nIndex, USHORT nLen ) :
+ MetaAction ( META_STRETCHTEXT_ACTION ),
+ maPt ( rPt ),
+ maStr ( rStr ),
+ mnWidth ( nWidth ),
+ mnIndex ( nIndex ),
+ mnLen ( nLen )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaStretchTextAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawStretchText( maPt, mnWidth, maStr, mnIndex, mnLen );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaStretchTextAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaStretchTextAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaStretchTextAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaStretchTextAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+ mnWidth = (ULONG)FRound( mnWidth * fScaleX );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaStretchTextAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maPt;
+ rOStm.WriteByteString( maStr, pData->meActualCharSet );
+ rOStm << mnWidth;
+ rOStm << mnIndex;
+ rOStm << mnLen;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaStretchTextAction::Read( SvStream& rIStm, ImplMetaReadData* pData )
+{
+ COMPAT( rIStm );
+ rIStm >> maPt;
+ rIStm.ReadByteString( maStr, pData->meActualCharSet );
+ rIStm >> mnWidth;
+ rIStm >> mnIndex;
+ rIStm >> mnLen;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( TextRect, META_TEXTRECT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaTextRectAction::MetaTextRectAction( const Rectangle& rRect,
+ const XubString& rStr, USHORT nStyle ) :
+ MetaAction ( META_TEXTRECT_ACTION ),
+ maRect ( rRect ),
+ maStr ( rStr ),
+ mnStyle ( nStyle )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextRectAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawText( maRect, maStr, mnStyle );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaTextRectAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaTextRectAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextRectAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextRectAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextRectAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRect;
+ rOStm.WriteByteString( maStr, pData->meActualCharSet );
+ rOStm << mnStyle;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextRectAction::Read( SvStream& rIStm, ImplMetaReadData* pData )
+{
+ COMPAT( rIStm );
+ rIStm >> maRect;
+ rIStm.ReadByteString( maStr, pData->meActualCharSet );
+ rIStm >> mnStyle;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( TextLine, META_TEXTLINE_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaTextLineAction::MetaTextLineAction( const Point& rPos, long nWidth,
+ FontStrikeout eStrikeout,
+ FontUnderline eUnderline ) :
+ MetaAction ( META_TEXTLINE_ACTION ),
+ maPos ( rPos ),
+ mnWidth ( nWidth ),
+ meStrikeout ( eStrikeout ),
+ meUnderline ( eUnderline )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextLineAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawTextLine( maPos, mnWidth, meStrikeout, meUnderline );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaTextLineAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*)new MetaTextLineAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextLineAction::Move( long nHorzMove, long nVertMove )
+{
+ maPos.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextLineAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPos, fScaleX, fScaleY );
+ mnWidth = FRound( mnWidth * fScaleX );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextLineAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 2, pData );
+
+ rOStm << maPos;
+ rOStm << mnWidth;
+ rOStm << (ULONG)meStrikeout;
+ rOStm << (ULONG)meUnderline;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextLineAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+
+ ULONG nTemp;
+ rIStm >> maPos;
+ rIStm >> mnWidth;
+ rIStm >> nTemp;
+ meStrikeout = (FontStrikeout)nTemp;
+ rIStm >> nTemp;
+ meUnderline = (FontUnderline)nTemp;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Bmp, META_BMP_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaBmpAction::MetaBmpAction( const Point& rPt, const Bitmap& rBmp ) :
+ MetaAction ( META_BMP_ACTION ),
+ maBmp ( rBmp ),
+ maPt ( rPt )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawBitmap( maPt, maBmp );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaBmpAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaBmpAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ if( !!maBmp )
+ {
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maBmp << maPt;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maBmp >> maPt;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( BmpScale, META_BMPSCALE_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaBmpScaleAction::MetaBmpScaleAction( const Point& rPt, const Size& rSz,
+ const Bitmap& rBmp ) :
+ MetaAction ( META_BMPSCALE_ACTION ),
+ maBmp ( rBmp ),
+ maPt ( rPt ),
+ maSz ( rSz )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScaleAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawBitmap( maPt, maSz, maBmp );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaBmpScaleAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaBmpScaleAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScaleAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScaleAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+ ImplScaleSize( maSz, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScaleAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ if( !!maBmp )
+ {
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maBmp << maPt << maSz;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScaleAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maBmp >> maPt >> maSz;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( BmpScalePart, META_BMPSCALEPART_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaBmpScalePartAction::MetaBmpScalePartAction( const Point& rDstPt, const Size& rDstSz,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Bitmap& rBmp ) :
+ MetaAction ( META_BMPSCALEPART_ACTION ),
+ maBmp ( rBmp ),
+ maDstPt ( rDstPt ),
+ maDstSz ( rDstSz ),
+ maSrcPt ( rSrcPt ),
+ maSrcSz ( rSrcSz )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScalePartAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawBitmap( maDstPt, maDstSz, maSrcPt, maSrcSz, maBmp );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaBmpScalePartAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaBmpScalePartAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScalePartAction::Move( long nHorzMove, long nVertMove )
+{
+ maDstPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScalePartAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maDstPt, fScaleX, fScaleY );
+ ImplScaleSize( maDstSz, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScalePartAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ if( !!maBmp )
+ {
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maBmp << maDstPt << maDstSz << maSrcPt << maSrcSz;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpScalePartAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maBmp >> maDstPt >> maDstSz >> maSrcPt >> maSrcSz;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( BmpEx, META_BMPEX_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaBmpExAction::MetaBmpExAction( const Point& rPt, const BitmapEx& rBmpEx ) :
+ MetaAction ( META_BMPEX_ACTION ),
+ maBmpEx ( rBmpEx ),
+ maPt ( rPt )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawBitmapEx( maPt, maBmpEx );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaBmpExAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaBmpExAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ if( !!maBmpEx.GetBitmap() )
+ {
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maBmpEx << maPt;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maBmpEx >> maPt;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( BmpExScale, META_BMPEXSCALE_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaBmpExScaleAction::MetaBmpExScaleAction( const Point& rPt, const Size& rSz,
+ const BitmapEx& rBmpEx ) :
+ MetaAction ( META_BMPEXSCALE_ACTION ),
+ maBmpEx ( rBmpEx ),
+ maPt ( rPt ),
+ maSz ( rSz )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScaleAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawBitmapEx( maPt, maSz, maBmpEx );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaBmpExScaleAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaBmpExScaleAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScaleAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScaleAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+ ImplScaleSize( maSz, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScaleAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ if( !!maBmpEx.GetBitmap() )
+ {
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maBmpEx << maPt << maSz;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScaleAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maBmpEx >> maPt >> maSz;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( BmpExScalePart, META_BMPEXSCALEPART_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaBmpExScalePartAction::MetaBmpExScalePartAction( const Point& rDstPt, const Size& rDstSz,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const BitmapEx& rBmpEx ) :
+ MetaAction ( META_BMPEXSCALEPART_ACTION ),
+ maBmpEx ( rBmpEx ),
+ maDstPt ( rDstPt ),
+ maDstSz ( rDstSz ),
+ maSrcPt ( rSrcPt ),
+ maSrcSz ( rSrcSz )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScalePartAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawBitmapEx( maDstPt, maDstSz, maSrcPt, maSrcSz, maBmpEx );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaBmpExScalePartAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaBmpExScalePartAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScalePartAction::Move( long nHorzMove, long nVertMove )
+{
+ maDstPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScalePartAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maDstPt, fScaleX, fScaleY );
+ ImplScaleSize( maDstSz, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScalePartAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ if( !!maBmpEx.GetBitmap() )
+ {
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maBmpEx << maDstPt << maDstSz << maSrcPt << maSrcSz;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaBmpExScalePartAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maBmpEx >> maDstPt >> maDstSz >> maSrcPt >> maSrcSz;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Mask, META_MASK_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaMaskAction::MetaMaskAction( const Point& rPt,
+ const Bitmap& rBmp,
+ const Color& rColor ) :
+ MetaAction ( META_MASK_ACTION ),
+ maBmp ( rBmp ),
+ maColor ( rColor ),
+ maPt ( rPt )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawMask( maPt, maBmp, maColor );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaMaskAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaMaskAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ if( !!maBmp )
+ {
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maBmp << maPt;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maBmp >> maPt;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( MaskScale, META_MASKSCALE_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaMaskScaleAction::MetaMaskScaleAction( const Point& rPt, const Size& rSz,
+ const Bitmap& rBmp,
+ const Color& rColor ) :
+ MetaAction ( META_MASKSCALE_ACTION ),
+ maBmp ( rBmp ),
+ maColor ( rColor ),
+ maPt ( rPt ),
+ maSz ( rSz )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScaleAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawMask( maPt, maSz, maBmp, maColor );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaMaskScaleAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaMaskScaleAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScaleAction::Move( long nHorzMove, long nVertMove )
+{
+ maPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScaleAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPt, fScaleX, fScaleY );
+ ImplScaleSize( maSz, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScaleAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ if( !!maBmp )
+ {
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maBmp << maPt << maSz;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScaleAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maBmp >> maPt >> maSz;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( MaskScalePart, META_MASKSCALEPART_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaMaskScalePartAction::MetaMaskScalePartAction( const Point& rDstPt, const Size& rDstSz,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const Bitmap& rBmp,
+ const Color& rColor ) :
+ MetaAction ( META_MASKSCALEPART_ACTION ),
+ maBmp ( rBmp ),
+ maColor ( rColor ),
+ maDstPt ( rDstPt ),
+ maDstSz ( rDstSz ),
+ maSrcPt ( rSrcPt ),
+ maSrcSz ( rSrcSz )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScalePartAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawMask( maDstPt, maDstSz, maSrcPt, maSrcSz, maBmp, maColor );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaMaskScalePartAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaMaskScalePartAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScalePartAction::Move( long nHorzMove, long nVertMove )
+{
+ maDstPt.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScalePartAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maDstPt, fScaleX, fScaleY );
+ ImplScaleSize( maDstSz, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScalePartAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ if( !!maBmp )
+ {
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maBmp;
+ maColor.Write( rOStm, TRUE );
+ rOStm << maDstPt << maDstSz << maSrcPt << maSrcSz;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMaskScalePartAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maBmp;
+ maColor.Read( rIStm, TRUE );
+ rIStm >> maDstPt >> maDstSz >> maSrcPt >> maSrcSz;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Gradient, META_GRADIENT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaGradientAction::MetaGradientAction( const Rectangle& rRect, const Gradient& rGradient ) :
+ MetaAction ( META_GRADIENT_ACTION ),
+ maRect ( rRect ),
+ maGradient ( rGradient )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawGradient( maRect, maGradient );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaGradientAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaGradientAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRect << maGradient;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRect >> maGradient;
+}
+
+// ========================================================================
+
+MetaGradientExAction::MetaGradientExAction() :
+ MetaAction ( META_GRADIENTEX_ACTION )
+{
+}
+
+// ------------------------------------------------------------------------
+
+MetaGradientExAction::MetaGradientExAction( const PolyPolygon& rPolyPoly, const Gradient& rGradient ) :
+ MetaAction ( META_GRADIENTEX_ACTION ),
+ maPolyPoly ( rPolyPoly ),
+ maGradient ( rGradient )
+{
+}
+
+// ------------------------------------------------------------------------
+
+MetaGradientExAction::~MetaGradientExAction()
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientExAction::Execute( OutputDevice* pOut )
+{
+ if( pOut->GetConnectMetaFile() )
+ pOut->GetConnectMetaFile()->AddAction( Clone() );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaGradientExAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaGradientExAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientExAction::Move( long nHorzMove, long nVertMove )
+{
+ maPolyPoly.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientExAction::Scale( double fScaleX, double fScaleY )
+{
+ for( USHORT i = 0, nCount = maPolyPoly.Count(); i < nCount; i++ )
+ ImplScalePoly( maPolyPoly[ i ], fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientExAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maPolyPoly << maGradient;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaGradientExAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maPolyPoly >> maGradient;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Hatch, META_HATCH_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaHatchAction::MetaHatchAction( const PolyPolygon& rPolyPoly, const Hatch& rHatch ) :
+ MetaAction ( META_HATCH_ACTION ),
+ maPolyPoly ( rPolyPoly ),
+ maHatch ( rHatch )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaHatchAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawHatch( maPolyPoly, maHatch );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaHatchAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaHatchAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaHatchAction::Move( long nHorzMove, long nVertMove )
+{
+ maPolyPoly.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaHatchAction::Scale( double fScaleX, double fScaleY )
+{
+ for( USHORT i = 0, nCount = maPolyPoly.Count(); i < nCount; i++ )
+ ImplScalePoly( maPolyPoly[ i ], fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaHatchAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maPolyPoly << maHatch;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaHatchAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maPolyPoly >> maHatch;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Wallpaper, META_WALLPAPER_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaWallpaperAction::MetaWallpaperAction( const Rectangle& rRect,
+ const Wallpaper& rPaper ) :
+ MetaAction ( META_WALLPAPER_ACTION ),
+ maRect ( rRect ),
+ maWallpaper ( rPaper )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaWallpaperAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawWallpaper( maRect, maWallpaper );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaWallpaperAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaWallpaperAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaWallpaperAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaWallpaperAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaWallpaperAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maWallpaper;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaWallpaperAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maWallpaper;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( ClipRegion, META_CLIPREGION_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaClipRegionAction::MetaClipRegionAction( const Region& rRegion, BOOL bClip ) :
+ MetaAction ( META_CLIPREGION_ACTION ),
+ maRegion ( rRegion ),
+ mbClip ( bClip )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaClipRegionAction::Execute( OutputDevice* pOut )
+{
+ if( mbClip )
+ pOut->SetClipRegion( maRegion );
+ else
+ pOut->SetClipRegion();
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaClipRegionAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaClipRegionAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaClipRegionAction::Move( long nHorzMove, long nVertMove )
+{
+ maRegion.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaClipRegionAction::Scale( double fScaleX, double fScaleY )
+{
+ maRegion.Scale( fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaClipRegionAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRegion << mbClip;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaClipRegionAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRegion >> mbClip;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( ISectRectClipRegion, META_ISECTRECTCLIPREGION_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaISectRectClipRegionAction::MetaISectRectClipRegionAction( const Rectangle& rRect ) :
+ MetaAction ( META_ISECTRECTCLIPREGION_ACTION ),
+ maRect ( rRect )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaISectRectClipRegionAction::Execute( OutputDevice* pOut )
+{
+ pOut->IntersectClipRegion( maRect );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaISectRectClipRegionAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaISectRectClipRegionAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaISectRectClipRegionAction::Move( long nHorzMove, long nVertMove )
+{
+ maRect.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaISectRectClipRegionAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScaleRect( maRect, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaISectRectClipRegionAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRect;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaISectRectClipRegionAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRect;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( ISectRegionClipRegion, META_ISECTREGIONCLIPREGION_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaISectRegionClipRegionAction::MetaISectRegionClipRegionAction( const Region& rRegion ) :
+ MetaAction ( META_ISECTREGIONCLIPREGION_ACTION ),
+ maRegion ( rRegion )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaISectRegionClipRegionAction::Execute( OutputDevice* pOut )
+{
+ pOut->IntersectClipRegion( maRegion );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaISectRegionClipRegionAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaISectRegionClipRegionAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaISectRegionClipRegionAction::Move( long nHorzMove, long nVertMove )
+{
+ maRegion.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaISectRegionClipRegionAction::Scale( double fScaleX, double fScaleY )
+{
+ maRegion.Scale( fScaleX, fScaleY );
+}
+
+
+// ------------------------------------------------------------------------
+
+void MetaISectRegionClipRegionAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRegion;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaISectRegionClipRegionAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRegion;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( MoveClipRegion, META_MOVECLIPREGION_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaMoveClipRegionAction::MetaMoveClipRegionAction( long nHorzMove, long nVertMove ) :
+ MetaAction ( META_MOVECLIPREGION_ACTION ),
+ mnHorzMove ( nHorzMove ),
+ mnVertMove ( nVertMove )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMoveClipRegionAction::Execute( OutputDevice* pOut )
+{
+ pOut->MoveClipRegion( mnHorzMove, mnVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaMoveClipRegionAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaMoveClipRegionAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMoveClipRegionAction::Scale( double fScaleX, double fScaleY )
+{
+ mnHorzMove = FRound( mnHorzMove * fScaleX );
+ mnVertMove = FRound( mnVertMove * fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMoveClipRegionAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << mnHorzMove << mnVertMove;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMoveClipRegionAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> mnHorzMove >> mnVertMove;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( LineColor, META_LINECOLOR_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaLineColorAction::MetaLineColorAction( const Color& rColor, BOOL bSet ) :
+ MetaAction ( META_LINECOLOR_ACTION ),
+ maColor ( rColor ),
+ mbSet ( bSet )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaLineColorAction::Execute( OutputDevice* pOut )
+{
+ if( mbSet )
+ pOut->SetLineColor( maColor );
+ else
+ pOut->SetLineColor();
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaLineColorAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaLineColorAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaLineColorAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ maColor.Write( rOStm, TRUE );
+ rOStm << mbSet;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaLineColorAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ maColor.Read( rIStm, TRUE );
+ rIStm >> mbSet;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( FillColor, META_FILLCOLOR_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaFillColorAction::MetaFillColorAction( const Color& rColor, BOOL bSet ) :
+ MetaAction ( META_FILLCOLOR_ACTION ),
+ maColor ( rColor ),
+ mbSet ( bSet )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFillColorAction::Execute( OutputDevice* pOut )
+{
+ if( mbSet )
+ pOut->SetFillColor( maColor );
+ else
+ pOut->SetFillColor();
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaFillColorAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaFillColorAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFillColorAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ maColor.Write( rOStm, TRUE );
+ rOStm << mbSet;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFillColorAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ maColor.Read( rIStm, TRUE );
+ rIStm >> mbSet;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( TextColor, META_TEXTCOLOR_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaTextColorAction::MetaTextColorAction( const Color& rColor ) :
+ MetaAction ( META_TEXTCOLOR_ACTION ),
+ maColor ( rColor )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextColorAction::Execute( OutputDevice* pOut )
+{
+ pOut->SetTextColor( maColor );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaTextColorAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaTextColorAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextColorAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ maColor.Write( rOStm, TRUE );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextColorAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ maColor.Read( rIStm, TRUE );
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( TextFillColor, META_TEXTFILLCOLOR_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaTextFillColorAction::MetaTextFillColorAction( const Color& rColor, BOOL bSet ) :
+ MetaAction ( META_TEXTFILLCOLOR_ACTION ),
+ maColor ( rColor ),
+ mbSet ( bSet )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextFillColorAction::Execute( OutputDevice* pOut )
+{
+ if( mbSet )
+ pOut->SetTextFillColor( maColor );
+ else
+ pOut->SetTextFillColor();
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaTextFillColorAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaTextFillColorAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextFillColorAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ maColor.Write( rOStm, TRUE );
+ rOStm << mbSet;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextFillColorAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ maColor.Read( rIStm, TRUE );
+ rIStm >> mbSet;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( TextLineColor, META_TEXTLINECOLOR_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaTextLineColorAction::MetaTextLineColorAction( const Color& rColor, BOOL bSet ) :
+ MetaAction ( META_TEXTLINECOLOR_ACTION ),
+ maColor ( rColor ),
+ mbSet ( bSet )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextLineColorAction::Execute( OutputDevice* pOut )
+{
+ if( mbSet )
+ pOut->SetTextLineColor( maColor );
+ else
+ pOut->SetTextLineColor();
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaTextLineColorAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaTextLineColorAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextLineColorAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ maColor.Write( rOStm, TRUE );
+ rOStm << mbSet;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextLineColorAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ maColor.Read( rIStm, TRUE );
+ rIStm >> mbSet;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( TextAlign, META_TEXTALIGN_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaTextAlignAction::MetaTextAlignAction( TextAlign aAlign ) :
+ MetaAction ( META_TEXTALIGN_ACTION ),
+ maAlign ( aAlign )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextAlignAction::Execute( OutputDevice* pOut )
+{
+ pOut->SetTextAlign( maAlign );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaTextAlignAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaTextAlignAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextAlignAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << (UINT16) maAlign;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTextAlignAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ UINT16 nTmp16;
+
+ COMPAT( rIStm );
+ rIStm >> nTmp16; maAlign = (TextAlign) nTmp16;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( MapMode, META_MAPMODE_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaMapModeAction::MetaMapModeAction( const MapMode& rMapMode ) :
+ MetaAction ( META_MAPMODE_ACTION ),
+ maMapMode ( rMapMode )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMapModeAction::Execute( OutputDevice* pOut )
+{
+ pOut->SetMapMode( maMapMode );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaMapModeAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaMapModeAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMapModeAction::Scale( double fScaleX, double fScaleY )
+{
+ Point aPoint( maMapMode.GetOrigin() );
+
+ ImplScalePoint( aPoint, fScaleX, fScaleY );
+ maMapMode.SetOrigin( aPoint );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMapModeAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maMapMode;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaMapModeAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maMapMode;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Font, META_FONT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaFontAction::MetaFontAction( const Font& rFont ) :
+ MetaAction ( META_FONT_ACTION ),
+ maFont ( rFont )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFontAction::Execute( OutputDevice* pOut )
+{
+ pOut->SetFont( maFont );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaFontAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaFontAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFontAction::Scale( double fScaleX, double fScaleY )
+{
+ Size aSize( maFont.GetSize() );
+
+ ImplScaleSize( aSize, fScaleX, fScaleY );
+ maFont.SetSize( aSize );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFontAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maFont;
+ pData->meActualCharSet = maFont.GetCharSet();
+ if ( pData->meActualCharSet == RTL_TEXTENCODING_DONTKNOW )
+ pData->meActualCharSet = gsl_getSystemTextEncoding();
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFontAction::Read( SvStream& rIStm, ImplMetaReadData* pData )
+{
+ COMPAT( rIStm );
+ rIStm >> maFont;
+ pData->meActualCharSet = maFont.GetCharSet();
+ if ( pData->meActualCharSet == RTL_TEXTENCODING_DONTKNOW )
+ pData->meActualCharSet = gsl_getSystemTextEncoding();
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Push, META_PUSH_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaPushAction::MetaPushAction( USHORT nFlags ) :
+ MetaAction ( META_PUSH_ACTION ),
+ mnFlags ( nFlags )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPushAction::Execute( OutputDevice* pOut )
+{
+ pOut->Push( mnFlags );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaPushAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaPushAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPushAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << mnFlags;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPushAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> mnFlags;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Pop, META_POP_ACTION )
+
+// ------------------------------------------------------------------------
+
+void MetaPopAction::Execute( OutputDevice* pOut )
+{
+ pOut->Pop();
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaPopAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaPopAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPopAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaPopAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( RasterOp, META_RASTEROP_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaRasterOpAction::MetaRasterOpAction( RasterOp eRasterOp ) :
+ MetaAction ( META_RASTEROP_ACTION ),
+ meRasterOp ( eRasterOp )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRasterOpAction::Execute( OutputDevice* pOut )
+{
+ pOut->SetRasterOp( meRasterOp );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaRasterOpAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaRasterOpAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRasterOpAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << (UINT16) meRasterOp;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRasterOpAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ UINT16 nTmp16;
+
+ COMPAT( rIStm );
+ rIStm >> nTmp16; meRasterOp = (RasterOp) nTmp16;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( Transparent, META_TRANSPARENT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaTransparentAction::MetaTransparentAction( const PolyPolygon& rPolyPoly, USHORT nTransPercent ) :
+ MetaAction ( META_TRANSPARENT_ACTION ),
+ maPolyPoly ( rPolyPoly ),
+ mnTransPercent ( nTransPercent )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTransparentAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawTransparent( maPolyPoly, mnTransPercent );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaTransparentAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaTransparentAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTransparentAction::Move( long nHorzMove, long nVertMove )
+{
+ maPolyPoly.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTransparentAction::Scale( double fScaleX, double fScaleY )
+{
+ for( USHORT i = 0, nCount = maPolyPoly.Count(); i < nCount; i++ )
+ ImplScalePoly( maPolyPoly[ i ], fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTransparentAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maPolyPoly;
+ rOStm << mnTransPercent;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaTransparentAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maPolyPoly;
+ rIStm >> mnTransPercent;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( FloatTransparent, META_FLOATTRANSPARENT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaFloatTransparentAction::MetaFloatTransparentAction( const GDIMetaFile& rMtf, const Point& rPos,
+ const Size& rSize, const Gradient& rGradient ) :
+ MetaAction ( META_FLOATTRANSPARENT_ACTION ),
+ maMtf ( rMtf ),
+ maPoint ( rPos ),
+ maSize ( rSize ),
+ maGradient ( rGradient )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFloatTransparentAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawTransparent( maMtf, maPoint, maSize, maGradient );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaFloatTransparentAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaFloatTransparentAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFloatTransparentAction::Move( long nHorzMove, long nVertMove )
+{
+ maPoint.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFloatTransparentAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPoint, fScaleX, fScaleY );
+ ImplScaleSize( maSize, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFloatTransparentAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maMtf << maPoint << maSize << maGradient;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaFloatTransparentAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maMtf >> maPoint >> maSize >> maGradient;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( EPS, META_EPS_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaEPSAction::MetaEPSAction( const Point& rPoint, const Size& rSize,
+ const GfxLink& rGfxLink, const GDIMetaFile& rSubst ) :
+ MetaAction ( META_EPS_ACTION ),
+ maGfxLink ( rGfxLink ),
+ maSubst ( rSubst ),
+ maPoint ( rPoint ),
+ maSize ( rSize )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEPSAction::Execute( OutputDevice* pOut )
+{
+ pOut->DrawEPS( maPoint, maSize, maGfxLink, &maSubst );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaEPSAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaEPSAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEPSAction::Move( long nHorzMove, long nVertMove )
+{
+ maPoint.Move( nHorzMove, nVertMove );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEPSAction::Scale( double fScaleX, double fScaleY )
+{
+ ImplScalePoint( maPoint, fScaleX, fScaleY );
+ ImplScaleSize( maSize, fScaleX, fScaleY );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEPSAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maGfxLink;
+ rOStm << maPoint;
+ rOStm << maSize;
+ rOStm << maSubst;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaEPSAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maGfxLink;
+ rIStm >> maPoint;
+ rIStm >> maSize;
+ rIStm >> maSubst;
+}
+
+// ========================================================================
+
+IMPL_META_ACTION( RefPoint, META_REFPOINT_ACTION )
+
+// ------------------------------------------------------------------------
+
+MetaRefPointAction::MetaRefPointAction( const Point& rRefPoint, BOOL bSet ) :
+ MetaAction ( META_REFPOINT_ACTION ),
+ maRefPoint ( rRefPoint ),
+ mbSet ( bSet )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRefPointAction::Execute( OutputDevice* pOut )
+{
+ if( mbSet )
+ pOut->SetRefPoint( maRefPoint );
+ else
+ pOut->SetRefPoint();
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaRefPointAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaRefPointAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRefPointAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maRefPoint << mbSet;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaRefPointAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maRefPoint >> mbSet;
+}
+
+// ========================================================================
+
+MetaCommentAction::MetaCommentAction( long nValue ) :
+ MetaAction ( META_COMMENT_ACTION ),
+ mnValue ( nValue )
+{
+ ImplInitDynamicData( NULL, 0UL );
+}
+
+// ------------------------------------------------------------------------
+
+MetaCommentAction::MetaCommentAction( const MetaCommentAction& rAct ) :
+ MetaAction ( META_COMMENT_ACTION ),
+ maComment ( rAct.maComment ),
+ mnValue ( rAct.mnValue )
+{
+ ImplInitDynamicData( rAct.mpData, rAct.mnDataSize );
+}
+
+// ------------------------------------------------------------------------
+
+MetaCommentAction::MetaCommentAction( const ByteString& rComment, long nValue, const BYTE* pData, ULONG nDataSize ) :
+ MetaAction ( META_COMMENT_ACTION ),
+ maComment ( rComment ),
+ mnValue ( nValue )
+{
+ ImplInitDynamicData( pData, nDataSize );
+}
+
+// ------------------------------------------------------------------------
+
+MetaCommentAction::MetaCommentAction( const BYTE* pData, ULONG nDataSize ) :
+ MetaAction ( META_COMMENT_ACTION ),
+ mnValue ( 0L )
+{
+ ImplInitDynamicData( pData, nDataSize );
+}
+
+// ------------------------------------------------------------------------
+
+MetaCommentAction::~MetaCommentAction()
+{
+ if ( mpData )
+ delete[] mpData;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaCommentAction::ImplInitDynamicData( const BYTE* pData, ULONG nDataSize )
+{
+ if ( nDataSize && pData )
+ {
+ mnDataSize = nDataSize, mpData = new BYTE[ mnDataSize ];
+ HMEMCPY( mpData, pData, mnDataSize );
+ }
+ else
+ {
+ mnDataSize = 0;
+ mpData = NULL;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void MetaCommentAction::Execute( OutputDevice* pOut )
+{
+ if ( pOut->GetConnectMetaFile() )
+ pOut->GetConnectMetaFile()->AddAction( Clone() );
+}
+
+// ------------------------------------------------------------------------
+
+MetaAction* MetaCommentAction::Clone()
+{
+ MetaAction* pClone = (MetaAction*) new MetaCommentAction( *this );
+ pClone->ResetRefCount();
+ return pClone;
+}
+
+// ------------------------------------------------------------------------
+
+void MetaCommentAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
+{
+ WRITE_BASE_COMPAT( rOStm, 1, pData );
+ rOStm << maComment << mnValue << mnDataSize;
+
+ if ( mnDataSize )
+ rOStm.Write( mpData, mnDataSize );
+}
+
+// ------------------------------------------------------------------------
+
+void MetaCommentAction::Read( SvStream& rIStm, ImplMetaReadData* )
+{
+ COMPAT( rIStm );
+ rIStm >> maComment >> mnValue >> mnDataSize;
+
+ if( mpData )
+ delete[] mpData;
+
+ if( mnDataSize )
+ {
+ mpData = new BYTE[ mnDataSize ];
+ rIStm.Read( mpData, mnDataSize );
+ }
+ else
+ mpData = NULL;
+}
diff --git a/vcl/source/gdi/metric.cxx b/vcl/source/gdi/metric.cxx
new file mode 100644
index 000000000000..b4a5f70fa5cd
--- /dev/null
+++ b/vcl/source/gdi/metric.cxx
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * $RCSfile: metric.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <metric.hxx>
+
+// =======================================================================
+
+FontInfo::FontInfo()
+{
+ mpImplMetric = new ImplFontMetric;
+ mpImplMetric->mnRefCount = 1;
+ mpImplMetric->meType = TYPE_DONTKNOW;
+ mpImplMetric->mbDevice = FALSE;
+ mpImplMetric->mnAscent = 0;
+ mpImplMetric->mnDescent = 0;
+ mpImplMetric->mnLeading = 0;
+ mpImplMetric->mnLineHeight = 0;
+ mpImplMetric->mnSlant = 0;
+ mpImplMetric->mnFirstChar = 0;
+ mpImplMetric->mnLastChar = 0;
+}
+
+// -----------------------------------------------------------------------
+
+FontInfo::FontInfo( const FontInfo& rInfo ) :
+ Font( rInfo )
+{
+ mpImplMetric = rInfo.mpImplMetric;
+ mpImplMetric->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+FontInfo::~FontInfo()
+{
+ // Eventuell Metric loeschen
+ if ( mpImplMetric->mnRefCount > 1 )
+ mpImplMetric->mnRefCount--;
+ else
+ delete mpImplMetric;
+}
+
+// -----------------------------------------------------------------------
+
+FontInfo& FontInfo::operator=( const FontInfo& rInfo )
+{
+ Font::operator=( rInfo );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ rInfo.mpImplMetric->mnRefCount++;
+
+ // Sind wir nicht die letzten ?
+ if ( mpImplMetric->mnRefCount > 1 )
+ mpImplMetric->mnRefCount--;
+ else
+ delete mpImplMetric;
+
+ mpImplMetric = rInfo.mpImplMetric;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontInfo::operator==( const FontInfo& rInfo ) const
+{
+ if ( !Font::operator==( rInfo ) )
+ return FALSE;
+
+ if ( mpImplMetric == rInfo.mpImplMetric )
+ return TRUE;
+
+ if ( (mpImplMetric->meType == rInfo.mpImplMetric->meType ) &&
+ (mpImplMetric->mbDevice == rInfo.mpImplMetric->mbDevice ) &&
+ (mpImplMetric->mnAscent == rInfo.mpImplMetric->mnAscent ) &&
+ (mpImplMetric->mnDescent == rInfo.mpImplMetric->mnDescent ) &&
+ (mpImplMetric->mnLeading == rInfo.mpImplMetric->mnLeading ) &&
+ (mpImplMetric->mnSlant == rInfo.mpImplMetric->mnSlant ) &&
+ (mpImplMetric->mnFirstChar == rInfo.mpImplMetric->mnFirstChar ) &&
+ (mpImplMetric->mnLastChar == rInfo.mpImplMetric->mnLastChar ) )
+ return TRUE;
+ else
+ return FALSE;
+}
diff --git a/vcl/source/gdi/octree.cxx b/vcl/source/gdi/octree.cxx
new file mode 100644
index 000000000000..7d4f9f688d65
--- /dev/null
+++ b/vcl/source/gdi/octree.cxx
@@ -0,0 +1,419 @@
+/*************************************************************************
+ *
+ * $RCSfile: octree.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <limits.h>
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_IMPOCT_HXX
+#include <impoct.hxx>
+#endif
+#ifndef _NEW_HXX
+#include<tools/new.hxx>
+#endif
+#include <octree.hxx>
+
+// ------------
+// - Typedefs -
+// ------------
+
+#ifdef WIN
+typedef ULONG huge* HPULONG;
+#else
+typedef ULONG* HPULONG;
+#endif
+
+// ---------
+// - pMask -
+// ---------
+
+static BYTE pImplMask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+
+// -------------
+// - NodeCache -
+// -------------
+
+ImpNodeCache::ImpNodeCache( const ULONG nInitSize ) :
+ pActNode( NULL )
+{
+ const ULONG nSize = nInitSize + 4;
+
+ for( ULONG i = 0; i < nSize; i++ )
+ {
+ OctreeNode* pNewNode = new NODE;
+
+ pNewNode->pNextInCache = pActNode;
+ pActNode = pNewNode;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ImpNodeCache::~ImpNodeCache()
+{
+ while( pActNode )
+ {
+ OctreeNode* pNode = pActNode;
+
+ pActNode = pNode->pNextInCache;
+ delete pNode;
+ }
+}
+
+// ----------
+// - Octree -
+// ----------
+
+Octree::Octree( ULONG nColors ) :
+ nMax ( nColors ),
+ nLeafCount ( 0L ),
+ pTree ( NULL ),
+ pAcc ( NULL )
+{
+ pNodeCache = new ImpNodeCache( nColors );
+ memset( pReduce, 0, ( OCTREE_BITS + 1 ) * sizeof( PNODE ) );
+}
+
+// ------------------------------------------------------------------------
+
+Octree::Octree( const BitmapReadAccess& rReadAcc, ULONG nColors ) :
+ nMax ( nColors ),
+ nLeafCount ( 0L ),
+ pTree ( NULL ),
+ pAcc ( &rReadAcc )
+{
+ pNodeCache = new ImpNodeCache( nColors );
+ memset( pReduce, 0, ( OCTREE_BITS + 1 ) * sizeof( PNODE ) );
+ ImplCreateOctree();
+}
+
+// ------------------------------------------------------------------------
+
+Octree::~Octree()
+{
+ ImplDeleteOctree( &pTree );
+ delete pNodeCache;
+}
+
+// ------------------------------------------------------------------------
+
+void Octree::AddColor( const BitmapColor& rColor )
+{
+ pColor = &(BitmapColor&) rColor;
+ nLevel = 0L;
+ ImplAdd( &pTree );
+
+ while( nLeafCount > nMax )
+ ImplReduce();
+}
+
+// ------------------------------------------------------------------------
+
+void Octree::ImplCreateOctree()
+{
+ if( !!*pAcc )
+ {
+ const long nWidth = pAcc->Width();
+ const long nHeight = pAcc->Height();
+
+ if( pAcc->HasPalette() )
+ {
+ for( long nY = 0; nY < nHeight; nY++ )
+ {
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ pColor = &(BitmapColor&) pAcc->GetPaletteColor( pAcc->GetPixel( nY, nX ) );
+ nLevel = 0L;
+ ImplAdd( &pTree );
+
+ while( nLeafCount > nMax )
+ ImplReduce();
+ }
+ }
+ }
+ else
+ {
+ BitmapColor aColor;
+
+ pColor = &aColor;
+
+ for( long nY = 0; nY < nHeight; nY++ )
+ {
+ for( long nX = 0; nX < nWidth; nX++ )
+ {
+ aColor = pAcc->GetPixel( nY, nX );
+ nLevel = 0L;
+ ImplAdd( &pTree );
+
+ while( nLeafCount > nMax )
+ ImplReduce();
+ }
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void Octree::ImplDeleteOctree( PPNODE ppNode )
+{
+ for ( ULONG i = 0UL; i < 8UL; i++ )
+ {
+ if ( (*ppNode)->pChild[ i ] )
+ ImplDeleteOctree( &(*ppNode)->pChild[ i ] );
+ }
+
+ pNodeCache->ImplReleaseNode( *ppNode );
+ *ppNode = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+void Octree::ImplAdd( PPNODE ppNode )
+{
+ // ggf. neuen Knoten erzeugen
+ if( !*ppNode )
+ {
+ *ppNode = pNodeCache->ImplGetFreeNode();
+ (*ppNode)->bLeaf = ( OCTREE_BITS == nLevel );
+
+ if( (*ppNode)->bLeaf )
+ nLeafCount++;
+ else
+ {
+ (*ppNode)->pNext = pReduce[ nLevel ];
+ pReduce[ nLevel ] = *ppNode;
+ }
+ }
+
+ if( (*ppNode)->bLeaf )
+ {
+ (*ppNode)->nCount++;
+ (*ppNode)->nRed += pColor->GetRed();
+ (*ppNode)->nGreen += pColor->GetGreen();
+ (*ppNode)->nBlue += pColor->GetBlue();
+ }
+ else
+ {
+ const ULONG nShift = 7 - nLevel;
+ const BYTE cMask = pImplMask[ nLevel ];
+ const ULONG nIndex = ( ( ( pColor->GetRed() & cMask ) >> nShift ) << 2 ) |
+ ( ( ( pColor->GetGreen() & cMask ) >> nShift ) << 1 ) |
+ ( ( pColor->GetBlue() & cMask ) >> nShift );
+
+ nLevel++;
+ ImplAdd( &(*ppNode)->pChild[ nIndex ] );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void Octree::ImplReduce()
+{
+ ULONG i;
+ PNODE pNode;
+ ULONG nRedSum = 0L;
+ ULONG nGreenSum = 0L;
+ ULONG nBlueSum = 0L;
+ ULONG nChilds = 0L;
+
+ for ( i = OCTREE_BITS - 1; i && !pReduce[i]; i-- ) {}
+
+ pNode = pReduce[ i ];
+ pReduce[ i ] = pNode->pNext;
+
+ for ( i = 0; i < 8; i++ )
+ {
+ if ( pNode->pChild[ i ] )
+ {
+ PNODE pChild = pNode->pChild[ i ];
+
+ nRedSum += pChild->nRed;
+ nGreenSum += pChild->nGreen;
+ nBlueSum += pChild->nBlue;
+ pNode->nCount += pChild->nCount;
+
+ pNodeCache->ImplReleaseNode( pNode->pChild[ i ] );
+ pNode->pChild[ i ] = NULL;
+ nChilds++;
+ }
+ }
+
+ pNode->bLeaf = TRUE;
+ pNode->nRed = nRedSum;
+ pNode->nGreen = nGreenSum;
+ pNode->nBlue = nBlueSum;
+ nLeafCount -= --nChilds;
+}
+
+// ------------------------------------------------------------------------
+
+void Octree::CreatePalette( PNODE pNode )
+{
+ if( pNode->bLeaf )
+ {
+ pNode->nPalIndex = nPalIndex;
+ aPal[ nPalIndex++ ] = BitmapColor( (BYTE) ( (double) pNode->nRed / pNode->nCount ),
+ (BYTE) ( (double) pNode->nGreen / pNode->nCount ),
+ (BYTE) ( (double) pNode->nBlue / pNode->nCount ) );
+ }
+ else for( ULONG i = 0UL; i < 8UL; i++ )
+ if( pNode->pChild[ i ] )
+ CreatePalette( pNode->pChild[ i ] );
+
+}
+
+// ------------------------------------------------------------------------
+
+void Octree::GetPalIndex( PNODE pNode )
+{
+ if ( pNode->bLeaf )
+ nPalIndex = pNode->nPalIndex;
+ else
+ {
+ const ULONG nShift = 7 - nLevel;
+ const BYTE cMask = pImplMask[ nLevel++ ];
+ const ULONG nIndex = ( ( ( pColor->GetRed() & cMask ) >> nShift ) << 2 ) |
+ ( ( ( pColor->GetGreen() & cMask ) >> nShift ) << 1 ) |
+ ( ( pColor->GetBlue() & cMask ) >> nShift );
+
+ GetPalIndex( pNode->pChild[ nIndex ] );
+ }
+}
+
+// -------------------
+// - InverseColorMap -
+// -------------------
+
+InverseColorMap::InverseColorMap( const BitmapPalette& rPal ) :
+ nBits( 8 - OCTREE_BITS )
+{
+ HPULONG cdp;
+ BYTE* crgbp;
+ const ULONG nColorMax = 1 << OCTREE_BITS;
+ const ULONG xsqr = 1 << ( nBits << 1 );
+ const ULONG xsqr2 = xsqr << 1;
+ const ULONG gstride = nColorMax;
+ const ULONG rstride = nColorMax * nColorMax;
+ const ULONG nColors = rPal.GetEntryCount();
+ const long x = 1L << nBits;
+ const long x2 = x >> 1L;
+ ULONG r, g, b;
+ long rxx, gxx, bxx;
+ long rdist, gdist, bdist;
+ long crinc, cginc, cbinc;
+
+ ImplCreateBuffers( nColorMax );
+
+ for( ULONG nIndex = 0; nIndex < nColors; nIndex++ )
+ {
+ const BitmapColor& rColor = rPal[ (USHORT) nIndex ];
+ const BYTE cRed = rColor.GetRed();
+ const BYTE cGreen = rColor.GetGreen();
+ const BYTE cBlue = rColor.GetBlue();
+
+ rdist = cRed - x2;
+ gdist = cGreen - x2;
+ bdist = cBlue - x2;
+ rdist = rdist*rdist + gdist*gdist + bdist*bdist;
+
+ crinc = ( xsqr - ( cRed << nBits ) ) << 1L;
+ cginc = ( xsqr - ( cGreen << nBits ) ) << 1L;
+ cbinc = ( xsqr - ( cBlue << nBits ) ) << 1L;
+
+ cdp = (HPULONG) pBuffer;
+ crgbp = pMap;
+
+ for( r = 0, rxx = crinc; r < nColorMax; rdist += rxx, r++, rxx += xsqr2 )
+ {
+ for( g = 0, gdist = rdist, gxx = cginc; g < nColorMax; gdist += gxx, g++, gxx += xsqr2 )
+ {
+ for( b = 0, bdist = gdist, bxx = cbinc; b < nColorMax; bdist += bxx, b++, cdp++, crgbp++, bxx += xsqr2 )
+ if ( !nIndex || ( (long) *cdp ) > bdist )
+ {
+ *cdp = bdist;
+ *crgbp = (BYTE) nIndex;
+ }
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+InverseColorMap::~InverseColorMap()
+{
+ SvMemFree( pBuffer );
+ SvMemFree( pMap );
+}
+
+// ------------------------------------------------------------------------
+
+void InverseColorMap::ImplCreateBuffers( const ULONG nMax )
+{
+ const ULONG nCount = nMax * nMax * nMax;
+ const ULONG nSize = nCount * sizeof( ULONG );
+
+ pMap = (BYTE*) SvMemAlloc( nCount );
+ HMEMSET( pMap, 0x00, nCount );
+
+ pBuffer = (BYTE*) SvMemAlloc( nSize );
+ HMEMSET( pBuffer, 0xff, nSize );
+}
diff --git a/vcl/source/gdi/opengl.cxx b/vcl/source/gdi/opengl.cxx
new file mode 100644
index 000000000000..fa45d1700725
--- /dev/null
+++ b/vcl/source/gdi/opengl.cxx
@@ -0,0 +1,1714 @@
+/*************************************************************************
+ *
+ * $RCSfile: opengl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_OPENGL_CXX
+
+#define private public
+#include <svsys.h>
+#include <window.hxx>
+#undef private
+#define private public
+
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_SALOGL_HXX
+#include <salogl.hxx>
+#endif
+#ifndef _SV_OPENGL_HXX
+#include <opengl.hxx>
+#endif
+
+#include <svapp.hxx>
+#include <vos/mutex.hxx>
+
+// -----------------------
+// - Fnc-Pointer-Typedef -
+// -----------------------
+
+typedef void ( *OGLFncClearDepth )( GLclampd fDepth );
+typedef void ( *OGLFncDepthFunc )( GLenum fFunc );
+typedef void ( *OGLFncEnable )( GLenum eCap );
+typedef void ( *OGLFncDisable )( GLenum eCap );
+typedef void ( *OGLFncDepthMask )( GLboolean bFlag );
+typedef void ( *OGLFncShadeModel )( GLenum eMode );
+typedef void ( *OGLFncEdgeFlag )( GLboolean bFlag );
+typedef void ( *OGLFncClear )( GLbitfield nMask );
+typedef void ( *OGLFncFlush )( void );
+typedef void ( *OGLFncFinish )( void );
+typedef void ( *OGLFncViewport )( GLint nX, GLint nY, GLsizei nWidth, GLsizei nHeight );
+typedef void ( *OGLFncBegin )( GLenum eMode );
+typedef void ( *OGLFncEnd )( void );
+typedef void ( *OGLFncVertex3dv )( const GLdouble *fV );
+typedef void ( *OGLFncNormal3dv )( const GLdouble *fV );
+typedef void ( *OGLFncColor4ub )( GLubyte cRed, GLubyte cGreen, GLubyte cBlue, GLubyte cAlpha );
+typedef void ( *OGLFncMaterialfv )( GLenum eFace, GLenum ePNname, const GLfloat *fParams );
+typedef void ( *OGLFncMaterialf )( GLenum eFace, GLenum ePName, GLfloat fParam );
+typedef void ( *OGLFncLightModelfv )( GLenum ePNname, const GLfloat *fParams );
+typedef void ( *OGLFncLightModelf )( GLenum ePname, GLfloat fParam );
+typedef void ( *OGLFncLightfv )( GLenum eLight, GLenum ePNname, const GLfloat *fParams );
+typedef void ( *OGLFncLightf )( GLenum eLight, GLenum ePname, GLfloat fParam );
+typedef void ( *OGLFncPolygonMode )( GLenum eFace, GLenum eMode );
+typedef void ( *OGLFncCullFace )( GLenum eMode );
+typedef void ( *OGLFncPointSize )( GLfloat fSize );
+typedef void ( *OGLFncLineWidth )( GLfloat fWidth );
+typedef void ( *OGLFncMatrixMode )( GLenum eMode );
+typedef void ( *OGLFncLoadMatrixd )( const GLdouble *fM );
+typedef void ( *OGLFncTexCoord2dv )( const GLdouble *pParams );
+typedef void ( *OGLFncTexCoord3dv )( const GLdouble *fV );
+typedef void ( *OGLFncTexImage1D )( GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels );
+typedef void ( *OGLFncTexImage2D )( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels );
+typedef void ( *OGLFncCopyTexImage1D )( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border );
+typedef void ( *OGLFncCopyTexImage2D )( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border );
+typedef void ( *OGLFncCopyTexSubImage1D )( GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width );
+typedef void ( *OGLFncCopyTexSubImage2D )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height );
+typedef void ( *OGLFncPixelTransferf )( GLenum pname, GLfloat param );
+typedef void ( *OGLFncPixelTransferi )( GLenum pname, GLint param );
+typedef void ( *OGLFncGetTexLevelParameterfv )( GLenum target, GLint level, GLenum pname, GLfloat *params );
+typedef void ( *OGLFncGetTexLevelParameteriv )( GLenum target, GLint level, GLenum pname, GLint *params );
+typedef void ( *OGLFncGetTexParameterfv )( GLenum target, GLenum pname, GLfloat *params );
+typedef void ( *OGLFncGetTexParameteriv )( GLenum target, GLenum pname, GLint *params );
+typedef void ( *OGLFncTexSubImage1D )( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels );
+typedef void ( *OGLFncTexSubImage2D )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels );
+typedef void ( *OGLFncPixelStoref )( GLenum pname, GLfloat param );
+typedef void ( *OGLFncPixelStorei )( GLenum pname, GLint param );
+typedef void ( *OGLFncGenTextures )( GLsizei n, GLuint *textures );
+typedef GLboolean ( *OGLFncIsTexture )( GLuint texture );
+typedef void ( *OGLFncBindTexture )( GLenum target, GLuint texture );
+typedef void ( *OGLFncDeleteTextures )( GLsizei n, const GLuint *textures );
+typedef GLboolean ( *OGLFncAreTexturesResident )( GLsizei n, const GLuint *textures, GLboolean *residences );
+typedef void ( *OGLFncPrioritizeTextures )( GLsizei n, const GLuint *textures, const GLclampf *priorities );
+typedef void ( *OGLFncTexEnvf )( GLenum target, GLenum pname, GLfloat param );
+typedef void ( *OGLFncTexEnvfv )( GLenum target, GLenum pname, const GLfloat *params );
+typedef void ( *OGLFncTexEnvi )( GLenum target, GLenum pname, GLint param );
+typedef void ( *OGLFncTexEnviv )( GLenum target, GLenum pname, const GLint *params );
+typedef void ( *OGLFncTexParameterf )( GLenum target, GLenum pname, GLfloat param );
+typedef void ( *OGLFncTexParameterfv )( GLenum target, GLenum pname, const GLfloat *params );
+typedef void ( *OGLFncTexParameteri )( GLenum target, GLenum pname, GLint param );
+typedef void ( *OGLFncTexParameteriv )( GLenum target, GLenum pname, const GLint *params );
+typedef void ( *OGLFncTexGend )( GLenum coord, GLenum pname, GLdouble param );
+typedef void ( *OGLFncTexGendv )( GLenum coord, GLenum pname, const GLdouble *params );
+typedef void ( *OGLFncTexGenf )( GLenum coord, GLenum pname, GLfloat param );
+typedef void ( *OGLFncTexGenfv )( GLenum coord, GLenum pname, const GLfloat *params );
+typedef void ( *OGLFncTexGeni )( GLenum coord, GLenum pname, GLint param );
+typedef void ( *OGLFncTexGeniv )( GLenum coord, GLenum pname, const GLint *params );
+typedef void ( *OGLFncGetIntegerv )( GLenum pname, GLint *params );
+typedef void ( *OGLFncPolygonOffset ) ( GLfloat factor, GLfloat units );
+typedef void ( *OGLFncScissor ) ( GLint x, GLint y, GLsizei width, GLsizei height );
+
+typedef void ( *OGLFncEnableClientState ) ( GLenum array );
+typedef void ( *OGLFncDisableClientState ) ( GLenum array );
+typedef void ( *OGLFncVertexPointer ) ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer );
+typedef void ( *OGLFncColorPointer ) ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer );
+typedef void ( *OGLFncIndexPointer ) ( GLenum type, GLsizei stride, const GLvoid *pointer );
+typedef void ( *OGLFncNormalPointer ) ( GLenum type, GLsizei stride, const GLvoid *pointer );
+typedef void ( *OGLFncTexCoordPointer ) ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer );
+typedef void ( *OGLFncEdgeFlagPointer ) ( GLsizei stride, const GLvoid *pointer );
+typedef void ( *OGLFncArrayElement ) ( GLint i );
+typedef void ( *OGLFncDrawElements ) ( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices );
+typedef void ( *OGLFncDrawArrays ) ( GLenum mode, GLint first, GLsizei count );
+typedef void ( *OGLFncInterleavedArrays ) ( GLenum format, GLsizei stride, const GLvoid *pointer );
+
+typedef void ( *OGLFncLoadIdentity ) ();
+typedef void ( *OGLFncBlendFunc ) ( GLenum sfactor, GLenum dfactor );
+
+// ----------
+// - Macros -
+// ----------
+
+#define PGRAPHICS mpOutDev->mpGraphics
+
+#ifndef REMOTE_APPSERVER
+#define OGL_INIT() (mpOGL && (mpOutDev->mpGraphics || mpOutDev->ImplGetGraphics()))
+#else
+#define OGL_INIT() (mpOGL && (mpOutDev->mpGraphics || mpOutDev->ImplGetGraphics()))
+#endif
+
+#define INIT_OGLFNC( FncName ) static OGLFnc##FncName pImplOpenGLFnc##FncName = NULL;
+#define GET_OGLFNC_GL( FncName ) \
+pImplOpenGLFnc##FncName = (OGLFnc##FncName##) mpOGL->GetOGLFnc( "gl" #FncName ); \
+if( !pImplOpenGLFnc##FncName ) bRet = FALSE;
+
+// ----------
+// - OpenGL -
+// ----------
+
+static BOOL bImplOpenGLFncPtrInitialized = FALSE;
+
+INIT_OGLFNC( ClearDepth );
+INIT_OGLFNC( DepthFunc );
+INIT_OGLFNC( Enable );
+INIT_OGLFNC( Disable );
+INIT_OGLFNC( DepthMask );
+INIT_OGLFNC( ShadeModel );
+INIT_OGLFNC( EdgeFlag );
+INIT_OGLFNC( Clear );
+INIT_OGLFNC( Flush );
+INIT_OGLFNC( Finish );
+INIT_OGLFNC( Viewport );
+INIT_OGLFNC( Begin );
+INIT_OGLFNC( End );
+INIT_OGLFNC( Vertex3dv );
+INIT_OGLFNC( Normal3dv );
+INIT_OGLFNC( Color4ub );
+INIT_OGLFNC( Materialfv );
+INIT_OGLFNC( Materialf );
+INIT_OGLFNC( LightModelfv );
+INIT_OGLFNC( LightModelf );
+INIT_OGLFNC( Lightfv );
+INIT_OGLFNC( Lightf );
+INIT_OGLFNC( PolygonMode );
+INIT_OGLFNC( CullFace );
+INIT_OGLFNC( PointSize );
+INIT_OGLFNC( LineWidth );
+INIT_OGLFNC( MatrixMode );
+INIT_OGLFNC( LoadMatrixd );
+INIT_OGLFNC( TexCoord2dv );
+INIT_OGLFNC( TexCoord3dv );
+INIT_OGLFNC( TexImage1D );
+INIT_OGLFNC( TexImage2D );
+INIT_OGLFNC( CopyTexImage1D );
+INIT_OGLFNC( CopyTexImage2D );
+INIT_OGLFNC( CopyTexSubImage1D );
+INIT_OGLFNC( CopyTexSubImage2D );
+INIT_OGLFNC( PixelTransferf );
+INIT_OGLFNC( PixelTransferi );
+INIT_OGLFNC( GetTexLevelParameterfv );
+INIT_OGLFNC( GetTexLevelParameteriv );
+INIT_OGLFNC( GetTexParameterfv );
+INIT_OGLFNC( GetTexParameteriv );
+INIT_OGLFNC( TexSubImage1D );
+INIT_OGLFNC( TexSubImage2D );
+INIT_OGLFNC( PixelStoref );
+INIT_OGLFNC( PixelStorei );
+INIT_OGLFNC( GenTextures );
+INIT_OGLFNC( IsTexture );
+INIT_OGLFNC( BindTexture );
+INIT_OGLFNC( DeleteTextures );
+INIT_OGLFNC( AreTexturesResident );
+INIT_OGLFNC( PrioritizeTextures );
+INIT_OGLFNC( TexEnvf );
+INIT_OGLFNC( TexEnvfv );
+INIT_OGLFNC( TexEnvi );
+INIT_OGLFNC( TexEnviv );
+INIT_OGLFNC( TexParameterf );
+INIT_OGLFNC( TexParameterfv );
+INIT_OGLFNC( TexParameteri );
+INIT_OGLFNC( TexParameteriv );
+INIT_OGLFNC( TexGend );
+INIT_OGLFNC( TexGendv );
+INIT_OGLFNC( TexGenf );
+INIT_OGLFNC( TexGenfv );
+INIT_OGLFNC( TexGeni );
+INIT_OGLFNC( TexGeniv );
+INIT_OGLFNC( GetIntegerv );
+INIT_OGLFNC( PolygonOffset );
+INIT_OGLFNC( Scissor );
+
+INIT_OGLFNC( EnableClientState );
+INIT_OGLFNC( DisableClientState );
+INIT_OGLFNC( VertexPointer );
+INIT_OGLFNC( ColorPointer );
+INIT_OGLFNC( IndexPointer );
+INIT_OGLFNC( NormalPointer );
+INIT_OGLFNC( TexCoordPointer );
+INIT_OGLFNC( EdgeFlagPointer );
+INIT_OGLFNC( ArrayElement );
+INIT_OGLFNC( DrawElements );
+INIT_OGLFNC( DrawArrays );
+INIT_OGLFNC( InterleavedArrays );
+
+INIT_OGLFNC( LoadIdentity );
+INIT_OGLFNC( BlendFunc );
+
+// ------------------------------------------------------------------------
+
+BOOL OpenGL::ImplInitFncPointers()
+{
+#ifndef REMOTE_APPSERVER
+ BOOL bRet = TRUE;
+
+ GET_OGLFNC_GL( ClearDepth );
+ GET_OGLFNC_GL( DepthFunc );
+ GET_OGLFNC_GL( Enable );
+ GET_OGLFNC_GL( Disable );
+ GET_OGLFNC_GL( DepthMask );
+ GET_OGLFNC_GL( ShadeModel );
+ GET_OGLFNC_GL( EdgeFlag );
+ GET_OGLFNC_GL( Clear );
+ GET_OGLFNC_GL( Flush );
+ GET_OGLFNC_GL( Finish );
+ GET_OGLFNC_GL( Viewport );
+ GET_OGLFNC_GL( Begin );
+ GET_OGLFNC_GL( End );
+ GET_OGLFNC_GL( Vertex3dv );
+ GET_OGLFNC_GL( Normal3dv );
+ GET_OGLFNC_GL( Color4ub );
+ GET_OGLFNC_GL( Materialfv );
+ GET_OGLFNC_GL( Materialf );
+ GET_OGLFNC_GL( LightModelfv );
+ GET_OGLFNC_GL( LightModelf );
+ GET_OGLFNC_GL( Lightfv );
+ GET_OGLFNC_GL( Lightf );
+ GET_OGLFNC_GL( PolygonMode );
+ GET_OGLFNC_GL( CullFace );
+ GET_OGLFNC_GL( PointSize );
+ GET_OGLFNC_GL( LineWidth );
+ GET_OGLFNC_GL( MatrixMode );
+ GET_OGLFNC_GL( LoadMatrixd );
+ GET_OGLFNC_GL( TexCoord2dv );
+ GET_OGLFNC_GL( TexCoord3dv );
+ GET_OGLFNC_GL( TexImage1D );
+ GET_OGLFNC_GL( TexImage2D );
+ GET_OGLFNC_GL( CopyTexImage1D );
+ GET_OGLFNC_GL( CopyTexImage2D );
+ GET_OGLFNC_GL( CopyTexSubImage1D );
+ GET_OGLFNC_GL( CopyTexSubImage2D );
+ GET_OGLFNC_GL( PixelTransferf );
+ GET_OGLFNC_GL( PixelTransferi );
+ GET_OGLFNC_GL( GetTexLevelParameterfv );
+ GET_OGLFNC_GL( GetTexLevelParameteriv );
+ GET_OGLFNC_GL( GetTexParameterfv );
+ GET_OGLFNC_GL( GetTexParameteriv );
+ GET_OGLFNC_GL( TexSubImage1D );
+ GET_OGLFNC_GL( TexSubImage2D );
+ GET_OGLFNC_GL( PixelStoref );
+ GET_OGLFNC_GL( PixelStorei );
+ GET_OGLFNC_GL( GenTextures );
+ GET_OGLFNC_GL( IsTexture );
+ GET_OGLFNC_GL( BindTexture );
+ GET_OGLFNC_GL( DeleteTextures );
+ GET_OGLFNC_GL( AreTexturesResident );
+ GET_OGLFNC_GL( PrioritizeTextures );
+ GET_OGLFNC_GL( TexEnvf );
+ GET_OGLFNC_GL( TexEnvfv );
+ GET_OGLFNC_GL( TexEnvi );
+ GET_OGLFNC_GL( TexEnviv );
+ GET_OGLFNC_GL( TexParameterf );
+ GET_OGLFNC_GL( TexParameterfv );
+ GET_OGLFNC_GL( TexParameteri );
+ GET_OGLFNC_GL( TexParameteriv );
+ GET_OGLFNC_GL( TexGend );
+ GET_OGLFNC_GL( TexGendv );
+ GET_OGLFNC_GL( TexGenf );
+ GET_OGLFNC_GL( TexGenfv );
+ GET_OGLFNC_GL( TexGeni );
+ GET_OGLFNC_GL( TexGeniv );
+ GET_OGLFNC_GL( GetIntegerv );
+ GET_OGLFNC_GL( PolygonOffset );
+ GET_OGLFNC_GL( Scissor );
+
+ GET_OGLFNC_GL( EnableClientState );
+ GET_OGLFNC_GL( DisableClientState );
+ GET_OGLFNC_GL( VertexPointer );
+ GET_OGLFNC_GL( ColorPointer );
+ GET_OGLFNC_GL( IndexPointer );
+ GET_OGLFNC_GL( NormalPointer );
+ GET_OGLFNC_GL( TexCoordPointer );
+ GET_OGLFNC_GL( EdgeFlagPointer );
+ GET_OGLFNC_GL( ArrayElement );
+ GET_OGLFNC_GL( DrawElements );
+ GET_OGLFNC_GL( DrawArrays );
+ GET_OGLFNC_GL( InterleavedArrays );
+
+ GET_OGLFNC_GL( LoadIdentity );
+ GET_OGLFNC_GL( BlendFunc );
+
+ return bRet;
+#else
+ return FALSE;
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+OpenGL::OpenGL( OutputDevice* pOutDev ) :
+ mpOutDev( pOutDev )
+{
+ ImplInit();
+}
+
+// ------------------------------------------------------------------------
+
+OpenGL::~OpenGL()
+{
+#ifndef REMOTE_APPSERVER
+ delete mpOGL;
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::ImplInit()
+{
+#ifndef REMOTE_APPSERVER
+ if( PGRAPHICS || mpOutDev->ImplGetGraphics() )
+ {
+ mpOGL = new SalOpenGL( PGRAPHICS );
+
+ if ( !mpOGL->Create() || (!bImplOpenGLFncPtrInitialized && !ImplInitFncPointers()) )
+ {
+ delete mpOGL;
+ mpOGL = NULL;
+ }
+ else
+ bImplOpenGLFncPtrInitialized = TRUE;
+ }
+ else
+ mpOGL = NULL;
+#else
+ mpOGL = NULL;
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::SetConnectOutputDevice( OutputDevice* pOutDev )
+{
+#ifndef REMOTE_APPSERVER
+ delete mpOGL;
+ mpOutDev = pOutDev;
+ ImplInit();
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::ClearDepth( GLclampd fDepth )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncClearDepth( fDepth );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::DepthFunc( GLenum eFunc )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncDepthFunc( eFunc );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Enable( GLenum eCap )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncEnable( eCap );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Disable( GLenum eCap )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncDisable( eCap );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::DepthMask( GLboolean bFlag )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncDepthMask( bFlag );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::ShadeModel( GLenum eMode )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncShadeModel( eMode );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::EdgeFlag( GLboolean bFlag )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncEdgeFlag( bFlag );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Clear( GLbitfield nMask )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+#if defined UNX && ! defined MACOSX
+ mpOGL->StartScene( PGRAPHICS );
+#endif
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncClear( nMask );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Flush()
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncFlush();
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Finish()
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncFinish();
+#if defined UNX && ! defined MACOSX
+ mpOGL->StopScene();
+#endif
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Viewport( GLint nX, GLint nY, GLsizei nWidth, GLsizei nHeight )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ long nOutHeight;
+
+ if( mpOutDev->GetOutDevType() == OUTDEV_WINDOW )
+ nOutHeight = ( (Window*) mpOutDev )->mpFrameWindow->mnOutHeight;
+ else
+ nOutHeight = mpOutDev->mnOutHeight;
+
+ mpOGL->OGLEntry( PGRAPHICS );
+
+ pImplOpenGLFncViewport( nX + mpOutDev->mnOutOffX,
+ nOutHeight - nY - nHeight - mpOutDev->mnOutOffY,
+ nWidth, nHeight );
+
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Begin( GLenum eMode )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncBegin( eMode );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::End()
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncEnd();
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Vertex3dv( const GLdouble* fVar )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncVertex3dv( fVar );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Normal3dv( const GLdouble* fVar )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncNormal3dv( fVar );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Color4ub( GLubyte cRed, GLubyte cGreen, GLubyte cBlue, GLubyte cAlpha )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncColor4ub( cRed, cGreen, cBlue, cAlpha );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Materialfv( GLenum eFace, GLenum ePName, const GLfloat *fParams )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncMaterialfv( eFace, ePName, fParams );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Materialf( GLenum eFace, GLenum ePName, GLfloat fParam )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncMaterialf( eFace, ePName, fParam );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::LightModelfv( GLenum ePName, const GLfloat *fParams )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncLightModelfv( ePName, fParams );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::LightModelf( GLenum ePName, GLfloat fParam )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncLightModelf( ePName, fParam );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Lightfv( GLenum eLight, GLenum ePName, const GLfloat *fParams )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncLightfv( eLight, ePName, fParams );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Lightf( GLenum eLight, GLenum ePName, GLfloat fParam )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncLightf( eLight, ePName, fParam );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::PolygonMode( GLenum eFace, GLenum eMode )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncPolygonMode( eFace, eMode );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::CullFace( GLenum eMode )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncCullFace( eMode );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::PointSize( GLfloat fSize )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncPointSize( fSize );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::LineWidth( GLfloat fWidth )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncLineWidth( fWidth );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::MatrixMode( GLenum eMode )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncMatrixMode( eMode );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::LoadMatrixd( const GLdouble *fM )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncLoadMatrixd( fM );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexCoord2dv( const GLdouble *pParams )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexCoord2dv( pParams );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexCoord3dv( const GLdouble *fVar )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexCoord3dv( fVar );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexImage1D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexImage1D( target, level, internalformat, width, border, format, type, pixels );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexImage2D( target, level, internalformat, width, height, border, format, type, pixels );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::CopyTexImage1D( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncCopyTexImage1D( target, level, internalFormat, x, y, width, border );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncCopyTexImage2D( target, level, internalFormat, x, y, width, height, border );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncCopyTexSubImage1D( target, level, xoffset, x, y, width );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::CopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncCopyTexSubImage2D( target, level, xoffset, yoffset, x, y, width, height );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::PixelTransferf( GLenum pname, GLfloat param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncPixelTransferf( pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::PixelTransferi( GLenum pname, GLint param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncPixelTransferi( pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::GetTexLevelParameterfv( GLenum target, GLint level, GLenum pname, GLfloat *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncGetTexLevelParameterfv( target, level, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::GetTexLevelParameteriv( GLenum target, GLint level, GLenum pname, GLint *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncGetTexLevelParameteriv( target, level, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncGetTexParameterfv( target, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncGetTexParameteriv( target, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexSubImage1D( target, level, xoffset, width, format, type, pixels );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::PixelStoref( GLenum pname, GLfloat param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncPixelStoref( pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::PixelStorei( GLenum pname, GLint param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncPixelStorei( pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::GenTextures( GLsizei n, GLuint *textures )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncGenTextures( n, textures );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+GLboolean OpenGL::IsTexture( GLuint texture )
+{
+ GLboolean bRet = FALSE;
+
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ bRet = pImplOpenGLFncIsTexture( texture );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::BindTexture( GLenum target, GLuint texture )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncBindTexture( target, texture );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::DeleteTextures( GLsizei n, const GLuint *textures )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncDeleteTextures( n, textures );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+GLboolean OpenGL::AreTexturesResident( GLsizei n, const GLuint *textures, GLboolean *residences )
+{
+ GLboolean bRet = FALSE;
+
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ bRet = pImplOpenGLFncAreTexturesResident( n, textures, residences );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::PrioritizeTextures( GLsizei n, const GLuint *textures, const GLclampf *priorities )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncPrioritizeTextures( n, textures, priorities );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexEnvf( GLenum target, GLenum pname, GLfloat param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexEnvf( target, pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexEnvfv( GLenum target, GLenum pname, const GLfloat *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexEnvfv( target, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexEnvi( GLenum target, GLenum pname, GLint param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexEnvi( target, pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexEnviv( GLenum target, GLenum pname, const GLint *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexEnviv( target, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexParameterf( GLenum target, GLenum pname, GLfloat param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexParameterf( target, pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexParameterfv( target, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexParameteri( GLenum target, GLenum pname, GLint param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexParameteri( target, pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexParameteriv( GLenum target, GLenum pname, const GLint *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexParameteriv( target, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexGend( GLenum coord, GLenum pname, GLdouble param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexGend( coord, pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexGendv( GLenum coord, GLenum pname, const GLdouble *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexGendv( coord, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexGenf( GLenum coord, GLenum pname, GLfloat param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexGenf( coord, pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexGenfv( coord, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexGeni( GLenum coord, GLenum pname, GLint param )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexGeni( coord, pname, param );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexGeniv( GLenum coord, GLenum pname, const GLint *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexGeniv( coord, pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::GetIntegerv( GLenum pname, GLint *params )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncGetIntegerv( pname, params );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::PolygonOffset( GLfloat factor, GLfloat units )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncPolygonOffset( factor, units );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::Scissor( GLint nX, GLint nY, GLsizei nWidth, GLsizei nHeight )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ long nOutHeight;
+
+ if( mpOutDev->GetOutDevType() == OUTDEV_WINDOW )
+ nOutHeight = ( (Window*) mpOutDev )->mpFrameWindow->mnOutHeight;
+ else
+ nOutHeight = mpOutDev->mnOutHeight;
+
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncScissor( nX + mpOutDev->mnOutOffX,
+ nOutHeight - nY - nHeight - mpOutDev->mnOutOffY,
+ nWidth, nHeight );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::EnableClientState( GLenum array )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncEnableClientState( array );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::DisableClientState( GLenum array )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncDisableClientState( array );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::VertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncVertexPointer( size, type, stride, pointer );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::ColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncColorPointer( size, type, stride, pointer );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::IndexPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncIndexPointer( type, stride, pointer );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::NormalPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncNormalPointer( type, stride, pointer );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::TexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncTexCoordPointer( size, type, stride, pointer );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::EdgeFlagPointer( GLsizei stride, const GLvoid *pointer )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncEdgeFlagPointer( stride, pointer );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::ArrayElement( GLint i )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncArrayElement( i );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::DrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncDrawElements( mode, count, type, indices );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::DrawArrays( GLenum mode, GLint first, GLsizei count )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncDrawArrays( mode, first, count );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::InterleavedArrays( GLenum format, GLsizei stride, const GLvoid *pointer )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncInterleavedArrays( format, stride, pointer );
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::LoadIdentity( )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncLoadIdentity();
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+void OpenGL::BlendFunc( GLenum sfactor, GLenum dfactor )
+{
+#ifndef REMOTE_APPSERVER
+ if( OGL_INIT() )
+ {
+ mpOGL->OGLEntry( PGRAPHICS );
+ pImplOpenGLFncBlendFunc( sfactor, dfactor);
+ mpOGL->OGLExit( PGRAPHICS );
+ }
+#else
+#endif
+}
+
diff --git a/vcl/source/gdi/outdev.cxx b/vcl/source/gdi/outdev.cxx
new file mode 100644
index 000000000000..591ecf8c8f8d
--- /dev/null
+++ b/vcl/source/gdi/outdev.cxx
@@ -0,0 +1,1927 @@
+/*************************************************************************
+ *
+ * $RCSfile: outdev.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_OUTDEV_CXX
+#include <tools/ref.hxx>
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#endif
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+#ifndef _SV_SALPRN_HXX
+#include <salprn.hxx>
+#endif
+#else
+#ifndef _SV_RMOUTDEV_HXX
+#include <rmoutdev.hxx>
+#endif
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_POLY_H
+#include <poly.h>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_REGION_HXX
+#include <region.hxx>
+#endif
+#ifndef _SV_REGION_H
+#include <region.h>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_OUTDATA_HXX
+#include <outdata.hxx>
+#endif
+#ifndef _SV_PRINT_HXX
+#include <print.hxx>
+#endif
+#ifndef _SV_SALOTYPE_HXX
+#include <salotype.hxx>
+#endif
+#ifndef _SV_OPENGL_HXX
+#include <opengl.hxx>
+#endif
+#ifndef _VCL_IMPLNCVT_HXX
+#include <implncvt.hxx>
+#endif
+#ifndef _SV_OUTDEV3D_HXX
+#include <outdev3d.hxx>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _VCL_UNOWRAP_HXX
+#include <unowrap.hxx>
+#endif
+
+#include <com/sun/star/awt/XGraphics.hpp>
+
+DBG_NAME( OutputDevice );
+DBG_NAMEEX( Polygon );
+DBG_NAMEEX( PolyPolygon );
+DBG_NAMEEX( Region );
+
+// -----------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+const char* ImplDbgCheckOutputDevice( const void* pObj )
+{
+ DBG_TESTSOLARMUTEX();
+
+ const OutputDevice* pOutDev = (OutputDevice*)pObj;
+
+ if ( (pOutDev->GetOutDevType() != OUTDEV_DONTKNOW) &&
+ (pOutDev->GetOutDevType() != OUTDEV_WINDOW) &&
+ (pOutDev->GetOutDevType() != OUTDEV_PRINTER) &&
+ (pOutDev->GetOutDevType() != OUTDEV_VIRDEV) )
+ return "OutputDevice data overwrite";
+
+ return NULL;
+}
+#endif
+
+// =======================================================================
+
+#define OUTDEV_POLYPOLY_STACKBUF 32
+
+// =======================================================================
+
+struct ImplObjStack
+{
+ ImplObjStack* mpPrev;
+ MapMode* mpMapMode;
+ Region* mpClipRegion;
+ Color* mpLineColor;
+ Color* mpFillColor;
+ Font* mpFont;
+ Color* mpTextColor;
+ Color* mpTextFillColor;
+ Color* mpTextLineColor;
+ Point* mpRefPoint;
+ TextAlign meTextAlign;
+ RasterOp meRasterOp;
+ USHORT mnFlags;
+};
+
+// -----------------------------------------------------------------------
+
+static void ImplDeleteObjStack( ImplObjStack* pObjStack )
+{
+ if ( pObjStack->mnFlags & PUSH_LINECOLOR )
+ {
+ if ( pObjStack->mpLineColor )
+ delete pObjStack->mpLineColor;
+ }
+ if ( pObjStack->mnFlags & PUSH_FILLCOLOR )
+ {
+ if ( pObjStack->mpFillColor )
+ delete pObjStack->mpFillColor;
+ }
+ if ( pObjStack->mnFlags & PUSH_FONT )
+ delete pObjStack->mpFont;
+ if ( pObjStack->mnFlags & PUSH_TEXTCOLOR )
+ delete pObjStack->mpTextColor;
+ if ( pObjStack->mnFlags & PUSH_TEXTFILLCOLOR )
+ {
+ if ( pObjStack->mpTextFillColor )
+ delete pObjStack->mpTextFillColor;
+ }
+ if ( pObjStack->mnFlags & PUSH_TEXTLINECOLOR )
+ {
+ if ( pObjStack->mpTextLineColor )
+ delete pObjStack->mpTextLineColor;
+ }
+ if ( pObjStack->mnFlags & PUSH_MAPMODE )
+ {
+ if ( pObjStack->mpMapMode )
+ delete pObjStack->mpMapMode;
+ }
+ if ( pObjStack->mnFlags & PUSH_CLIPREGION )
+ {
+ if ( pObjStack->mpClipRegion )
+ delete pObjStack->mpClipRegion;
+ }
+ if ( pObjStack->mnFlags & PUSH_REFPOINT )
+ {
+ if ( pObjStack->mpRefPoint )
+ delete pObjStack->mpRefPoint;
+ }
+
+ delete pObjStack;
+}
+
+// -----------------------------------------------------------------------
+
+#ifndef REMOTE_APPSERVER
+
+BOOL OutputDevice::ImplSelectClipRegion( SalGraphics* pGraphics, const Region& rRegion )
+{
+ DBG_TESTSOLARMUTEX();
+
+ long nX;
+ long nY;
+ long nWidth;
+ long nHeight;
+ ULONG nRectCount;
+ ImplRegionInfo aInfo;
+ BOOL bRegionRect;
+ BOOL bClipRegion = TRUE;
+
+ nRectCount = rRegion.GetRectCount();
+ pGraphics->BeginSetClipRegion( nRectCount );
+ bRegionRect = rRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+ while ( bRegionRect )
+ {
+ if ( !pGraphics->UnionClipRegion( nX, nY, nWidth, nHeight ) )
+ bClipRegion = FALSE;
+ DBG_ASSERT( bClipRegion, "OutputDevice::ImplSelectClipRegion() - can't cerate region" );
+ bRegionRect = rRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+ }
+ pGraphics->EndSetClipRegion();
+ return bClipRegion;
+}
+
+#endif
+
+// =======================================================================
+
+OutputDevice::OutputDevice() :
+ maRegion( REGION_NULL ),
+ maSettings( Application::GetSettings() ),
+ maFillColor( COL_WHITE ),
+ maTextLineColor( COL_TRANSPARENT )
+{
+ DBG_CTOR( OutputDevice, ImplDbgCheckOutputDevice );
+
+ mpGraphics = NULL;
+ mpUnoGraphicsList = NULL;
+ mpPrevGraphics = NULL;
+ mpNextGraphics = NULL;
+ mpMetaFile = NULL;
+ mpFontEntry = NULL;
+ mpFontCache = NULL;
+ mpFontList = NULL;
+ mpGetDevFontList = NULL;
+ mpGetDevSizeList = NULL;
+ mpObjStack = NULL;
+ mpOutDevData = NULL;
+ mp3DContext = NULL;
+ mnOutOffX = 0;
+ mnOutOffY = 0;
+ mnOutWidth = 0;
+ mnOutHeight = 0;
+ mnDPIX = 0;
+ mnDPIY = 0;
+ mnTextOffX = 0;
+ mnTextOffY = 0;
+ mnDrawMode = 0;
+ meOutDevType = OUTDEV_DONTKNOW;
+ mbMap = FALSE;
+ mbClipRegion = FALSE;
+ mbBackground = FALSE;
+ mbOutput = TRUE;
+ mbDevOutput = FALSE;
+ mbOutputClipped = FALSE;
+ maTextColor = maFont.GetColor();
+ maTextFillColorDummy= maFont.GetFillColor();
+ meTextAlign = maFont.GetAlign();
+ meRasterOp = ROP_OVERPAINT;
+ mbLineColor = TRUE;
+ mbFillColor = TRUE;
+ mbInitLineColor = TRUE;
+ mbInitFillColor = TRUE;
+ mbInitFont = TRUE;
+ mbInitTextColor = TRUE;
+ mbInitClipRegion = TRUE;
+ mbClipRegionSet = FALSE;
+ mbKerning = FALSE;
+ mbNewFont = TRUE;
+ mbTextLines = FALSE;
+ mbTextSpecial = FALSE;
+ mbRefPoint = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+OutputDevice::~OutputDevice()
+{
+ DBG_DTOR( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( GetUnoGraphicsList() )
+ {
+ UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
+ if ( pWrapper )
+ pWrapper->ReleaseAllGraphics( this );
+ delete mpUnoGraphicsList;
+ mpUnoGraphicsList = NULL;
+ }
+
+ if ( mp3DContext )
+ mp3DContext->Destroy( this );
+
+ if ( mpOutDevData )
+ ImplDeInitOutDevData();
+
+ ImplObjStack* pData = mpObjStack;
+ if ( pData )
+ {
+ DBG_ERRORFILE( "OutputDevice::~OutputDevice(): OutputDevice::Push() calls != OutputDevice::Pop() calls" );
+ while ( pData )
+ {
+ ImplObjStack* pTemp = pData;
+ pData = pData->mpPrev;
+ ImplDeleteObjStack( pTemp );
+ }
+ }
+
+ if ( mpFontEntry )
+ mpFontCache->Release( mpFontEntry );
+ if ( mpGetDevFontList )
+ delete mpGetDevFontList;
+ if ( mpGetDevSizeList )
+ delete mpGetDevSizeList;
+}
+
+// -----------------------------------------------------------------------
+
+#ifndef REMOTE_APPSERVER
+
+int OutputDevice::ImplGetGraphics()
+{
+ DBG_TESTSOLARMUTEX();
+
+ if ( mpGraphics )
+ return TRUE;
+
+ mbInitLineColor = TRUE;
+ mbInitFillColor = TRUE;
+ mbInitFont = TRUE;
+ mbInitTextColor = TRUE;
+ mbInitClipRegion = TRUE;
+
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( meOutDevType == OUTDEV_WINDOW )
+ {
+ Window* pWindow = (Window*)this;
+
+ mpGraphics = pWindow->mpFrame->GetGraphics();
+ // Wenn wir keinen bekommen haben, versuchen wir uns einen zu klauen
+ if ( !mpGraphics )
+ {
+ OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics;
+ while ( pReleaseOutDev )
+ {
+ if ( ((Window*)pReleaseOutDev)->mpFrame == pWindow->mpFrame )
+ break;
+ pReleaseOutDev = pReleaseOutDev->mpPrevGraphics;
+ }
+
+ if ( pReleaseOutDev )
+ {
+ mpGraphics = pReleaseOutDev->mpGraphics;
+ pReleaseOutDev->ImplReleaseGraphics( FALSE );
+ }
+ else
+ {
+ while ( !mpGraphics )
+ {
+ if ( !pSVData->maGDIData.mpLastWinGraphics )
+ break;
+ pSVData->maGDIData.mpLastWinGraphics->ImplReleaseGraphics();
+ mpGraphics = pWindow->mpFrame->GetGraphics();
+ }
+ }
+ }
+
+ if ( mpGraphics )
+ {
+ mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics;
+ pSVData->maGDIData.mpFirstWinGraphics = this;
+ if ( mpNextGraphics )
+ mpNextGraphics->mpPrevGraphics = this;
+ if ( !pSVData->maGDIData.mpLastWinGraphics )
+ pSVData->maGDIData.mpLastWinGraphics = this;
+ }
+ }
+ else if ( meOutDevType == OUTDEV_VIRDEV )
+ {
+ VirtualDevice* pVirDev = (VirtualDevice*)this;
+
+ if ( pVirDev->mpVirDev )
+ {
+ mpGraphics = pVirDev->mpVirDev->GetGraphics();
+ while ( !mpGraphics )
+ {
+ if ( !pSVData->maGDIData.mpLastVirGraphics )
+ break;
+ pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
+ mpGraphics = pVirDev->mpVirDev->GetGraphics();
+ }
+ if ( mpGraphics )
+ {
+ mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
+ pSVData->maGDIData.mpFirstVirGraphics = this;
+ if ( mpNextGraphics )
+ mpNextGraphics->mpPrevGraphics = this;
+ if ( !pSVData->maGDIData.mpLastVirGraphics )
+ pSVData->maGDIData.mpLastVirGraphics = this;
+ }
+ }
+ }
+ else if ( meOutDevType == OUTDEV_PRINTER )
+ {
+ Printer* pPrinter = (Printer*)this;
+
+ if ( pPrinter->mpJobGraphics )
+ mpGraphics = pPrinter->mpJobGraphics;
+ else if ( pPrinter->mpDisplayDev )
+ {
+ VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
+ mpGraphics = pVirDev->mpVirDev->GetGraphics();
+ while ( !mpGraphics )
+ {
+ if ( !pSVData->maGDIData.mpLastVirGraphics )
+ break;
+ pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
+ mpGraphics = pVirDev->mpVirDev->GetGraphics();
+ }
+ if ( mpGraphics )
+ {
+ mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
+ pSVData->maGDIData.mpFirstVirGraphics = this;
+ if ( mpNextGraphics )
+ mpNextGraphics->mpPrevGraphics = this;
+ if ( !pSVData->maGDIData.mpLastVirGraphics )
+ pSVData->maGDIData.mpLastVirGraphics = this;
+ }
+ }
+ else
+ {
+ mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
+ while ( !mpGraphics )
+ {
+ if ( !pSVData->maGDIData.mpLastPrnGraphics )
+ break;
+ pSVData->maGDIData.mpLastPrnGraphics->ImplReleaseGraphics();
+ mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
+ }
+ if ( mpGraphics )
+ {
+ mpNextGraphics = pSVData->maGDIData.mpFirstPrnGraphics;
+ pSVData->maGDIData.mpFirstPrnGraphics = this;
+ if ( mpNextGraphics )
+ mpNextGraphics->mpPrevGraphics = this;
+ if ( !pSVData->maGDIData.mpLastPrnGraphics )
+ pSVData->maGDIData.mpLastPrnGraphics = this;
+ }
+ }
+ }
+
+ if ( mpGraphics )
+ {
+ mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp) );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplReleaseGraphics( BOOL bRelease )
+{
+ DBG_TESTSOLARMUTEX();
+
+ if ( !mpGraphics )
+ return;
+
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( meOutDevType == OUTDEV_WINDOW )
+ {
+ Window* pWindow = (Window*)this;
+
+ if ( bRelease )
+ pWindow->mpFrame->ReleaseGraphics( mpGraphics );
+ if ( mpPrevGraphics )
+ mpPrevGraphics->mpNextGraphics = mpNextGraphics;
+ else
+ pSVData->maGDIData.mpFirstWinGraphics = mpNextGraphics;
+ if ( mpNextGraphics )
+ mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
+ else
+ pSVData->maGDIData.mpLastWinGraphics = mpPrevGraphics;
+ }
+ else if ( meOutDevType == OUTDEV_VIRDEV )
+ {
+ VirtualDevice* pVirDev = (VirtualDevice*)this;
+
+ if ( bRelease )
+ pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
+ if ( mpPrevGraphics )
+ mpPrevGraphics->mpNextGraphics = mpNextGraphics;
+ else
+ pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
+ if ( mpNextGraphics )
+ mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
+ else
+ pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
+ }
+ else if ( meOutDevType == OUTDEV_PRINTER )
+ {
+ Printer* pPrinter = (Printer*)this;
+
+ if ( !pPrinter->mpJobGraphics )
+ {
+ if ( pPrinter->mpDisplayDev )
+ {
+ VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
+ if ( bRelease )
+ pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
+ if ( mpPrevGraphics )
+ mpPrevGraphics->mpNextGraphics = mpNextGraphics;
+ else
+ pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
+ if ( mpNextGraphics )
+ mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
+ else
+ pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
+ }
+ else
+ {
+ if ( bRelease )
+ pPrinter->mpInfoPrinter->ReleaseGraphics( mpGraphics );
+ if ( mpPrevGraphics )
+ mpPrevGraphics->mpNextGraphics = mpNextGraphics;
+ else
+ pSVData->maGDIData.mpFirstPrnGraphics = mpNextGraphics;
+ if ( mpNextGraphics )
+ mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
+ else
+ pSVData->maGDIData.mpLastPrnGraphics = mpPrevGraphics;
+ }
+ }
+ }
+
+ mpGraphics = NULL;
+ mpPrevGraphics = NULL;
+ mpNextGraphics = NULL;
+
+ if ( mpGetDevFontList )
+ {
+ delete mpGetDevFontList;
+ mpGetDevFontList = NULL;
+ }
+ if ( mpGetDevSizeList )
+ {
+ delete mpGetDevSizeList;
+ mpGetDevSizeList = NULL;
+ }
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplInitOutDevData()
+{
+ if ( !mpOutDevData )
+ {
+ mpOutDevData = new ImplOutDevData;
+ mpOutDevData->mpRotateDev = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDeInitOutDevData()
+{
+ if ( mpOutDevData )
+ {
+ if ( mpOutDevData->mpRotateDev )
+ delete mpOutDevData->mpRotateDev;
+ delete mpOutDevData;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplInitLineColor()
+{
+ DBG_TESTSOLARMUTEX();
+
+#ifndef REMOTE_APPSERVER
+ if( mbLineColor )
+ {
+ if( ROP_0 == meRasterOp )
+ mpGraphics->SetROPLineColor( SAL_ROP_0 );
+ else if( ROP_1 == meRasterOp )
+ mpGraphics->SetROPLineColor( SAL_ROP_1 );
+ else if( ROP_INVERT == meRasterOp )
+ mpGraphics->SetROPLineColor( SAL_ROP_INVERT );
+ else
+ mpGraphics->SetLineColor( ImplColorToSal( maLineColor ) );
+ }
+ else
+ mpGraphics->SetLineColor();
+#else
+ mpGraphics->SetLineColor( maLineColor );
+#endif
+
+ mbInitLineColor = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplInitFillColor()
+{
+ DBG_TESTSOLARMUTEX();
+
+#ifndef REMOTE_APPSERVER
+ if( mbFillColor )
+ {
+ if( ROP_0 == meRasterOp )
+ mpGraphics->SetROPFillColor( SAL_ROP_0 );
+ else if( ROP_1 == meRasterOp )
+ mpGraphics->SetROPFillColor( SAL_ROP_1 );
+ else if( ROP_INVERT == meRasterOp )
+ mpGraphics->SetROPFillColor( SAL_ROP_INVERT );
+ else
+ mpGraphics->SetFillColor( ImplColorToSal( maFillColor ) );
+ }
+ else
+ mpGraphics->SetFillColor();
+#else
+ mpGraphics->SetFillColor( maFillColor );
+#endif
+
+ mbInitFillColor = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplInitClipRegion()
+{
+ DBG_TESTSOLARMUTEX();
+
+ if ( GetOutDevType() == OUTDEV_WINDOW )
+ {
+ Window* pWindow = (Window*)this;
+ Region aRegion;
+ // Hintergrund-Sicherung zuruecksetzen
+ if ( pWindow->mpFrameData->mpFirstBackWin )
+ pWindow->ImplInvalidateAllOverlapBackgrounds();
+ if ( pWindow->mbInPaint )
+ aRegion = *(pWindow->mpPaintRegion);
+ else
+ aRegion = *(pWindow->ImplGetWinChildClipRegion());
+ if ( mbClipRegion )
+ aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) );
+ if ( aRegion.IsEmpty() )
+ mbOutputClipped = TRUE;
+ else
+ {
+ mbOutputClipped = FALSE;
+#ifndef REMOTE_APPSERVER
+ ImplSelectClipRegion( mpGraphics, aRegion );
+#else
+ mpGraphics->SetClipRegion( aRegion );
+#endif
+ }
+ mbClipRegionSet = TRUE;
+ }
+ else
+ {
+ if ( mbClipRegion )
+ {
+ if ( maRegion.IsEmpty() )
+ mbOutputClipped = TRUE;
+ else
+ {
+ mbOutputClipped = FALSE;
+#ifndef REMOTE_APPSERVER
+ ImplSelectClipRegion( mpGraphics, maRegion );
+#else
+ mpGraphics->SetClipRegion( maRegion );
+#endif
+ }
+
+ mbClipRegionSet = TRUE;
+ }
+ else
+ {
+ if ( mbClipRegionSet )
+ {
+#ifndef REMOTE_APPSERVER
+ mpGraphics->ResetClipRegion();
+#else
+ mpGraphics->SetClipRegion();
+#endif
+ mbClipRegionSet = FALSE;
+ }
+
+ mbOutputClipped = FALSE;
+ }
+ }
+
+ mbInitClipRegion = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplSetClipRegion( const Region* pRegion )
+{
+ DBG_TESTSOLARMUTEX();
+
+ if ( !pRegion )
+ {
+ if ( mbClipRegion )
+ {
+ maRegion = Region( REGION_NULL );
+ mbClipRegion = FALSE;
+ mbInitClipRegion = TRUE;
+ }
+ }
+ else
+ {
+ maRegion = *pRegion;
+ mbClipRegion = TRUE;
+ mbInitClipRegion = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetClipRegion()
+{
+ DBG_TRACE( "OutputDevice::SetClipRegion()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaClipRegionAction( Region(), FALSE ) );
+
+ ImplSetClipRegion( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetClipRegion( const Region& rRegion )
+{
+ DBG_TRACE( "OutputDevice::SetClipRegion( rRegion )" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaClipRegionAction( rRegion, TRUE ) );
+
+ if ( rRegion.GetType() == REGION_NULL )
+ ImplSetClipRegion( NULL );
+ else
+ {
+ Region aRegion = LogicToPixel( rRegion );
+ ImplSetClipRegion( &aRegion );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Region OutputDevice::GetClipRegion() const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ return PixelToLogic( maRegion );
+}
+
+// -----------------------------------------------------------------------
+
+Region OutputDevice::GetActiveClipRegion() const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( GetOutDevType() == OUTDEV_WINDOW )
+ {
+ Region aRegion( REGION_NULL );
+ Window* pWindow = (Window*)this;
+ if ( pWindow->mbInPaint )
+ {
+ aRegion = *(pWindow->mpPaintRegion);
+ aRegion.Move( -mnOutOffX, -mnOutOffY );
+ }
+ if ( mbClipRegion )
+ aRegion.Intersect( maRegion );
+ return PixelToLogic( aRegion );
+ }
+ else
+ return GetClipRegion();
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::MoveClipRegion( long nHorzMove, long nVertMove )
+{
+ DBG_TRACE( "OutputDevice::MoveClipRegion()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mbClipRegion )
+ {
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaMoveClipRegionAction( nHorzMove, nVertMove ) );
+
+ maRegion.Move( ImplLogicWidthToDevicePixel( nHorzMove ),
+ ImplLogicHeightToDevicePixel( nVertMove ) );
+ mbInitClipRegion = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::IntersectClipRegion( const Rectangle& rRect )
+{
+ DBG_TRACE( "OutputDevice::IntersectClipRegion( rRect )" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaISectRectClipRegionAction( rRect ) );
+
+ Rectangle aRect = LogicToPixel( rRect );
+ maRegion.Intersect( aRect );
+ mbClipRegion = TRUE;
+ mbInitClipRegion = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::IntersectClipRegion( const Region& rRegion )
+{
+ DBG_TRACE( "OutputDevice::IntersectClipRegion( rRegion )" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
+
+ RegionType eType = rRegion.GetType();
+
+ if ( eType != REGION_NULL )
+ {
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaISectRegionClipRegionAction( rRegion ) );
+
+ Region aRegion = LogicToPixel( rRegion );
+ maRegion.Intersect( aRegion );
+ mbClipRegion = TRUE;
+ mbInitClipRegion = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetDrawMode( ULONG nDrawMode )
+{
+ DBG_TRACE1( "OutputDevice::SetDrawMode( %lx )", nDrawMode );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ mnDrawMode = nDrawMode;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetRasterOp( RasterOp eRasterOp )
+{
+ DBG_TRACE1( "OutputDevice::SetRasterOp( %d )", (int)eRasterOp );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) );
+
+ if ( meRasterOp != eRasterOp )
+ {
+ meRasterOp = eRasterOp;
+ mbInitLineColor = mbInitFillColor = TRUE;
+
+#ifndef REMOTE_APPSERVER
+ if( mpGraphics || ImplGetGraphics() )
+ mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp) );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if( pGraphics )
+ pGraphics->SetRasterOp( eRasterOp );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetLineColor()
+{
+ DBG_TRACE( "OutputDevice::SetLineColor()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaLineColorAction( Color(), FALSE ) );
+
+ if ( mbLineColor )
+ {
+ mbInitLineColor = TRUE;
+ mbLineColor = FALSE;
+ maLineColor = Color( COL_TRANSPARENT );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetLineColor( const Color& rColor )
+{
+ DBG_TRACE1( "OutputDevice::SetLineColor( %lx )", rColor.GetColor() );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Color aColor( rColor );
+
+ if( mnDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE |
+ DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE ) )
+ {
+ if( !ImplIsColorTransparent( aColor ) )
+ {
+ if( mnDrawMode & DRAWMODE_BLACKLINE )
+ {
+ aColor = Color( COL_BLACK );
+ }
+ else if( mnDrawMode & DRAWMODE_WHITELINE )
+ {
+ aColor = Color( COL_WHITE );
+ }
+ else if( mnDrawMode & DRAWMODE_GRAYLINE )
+ {
+ const UINT8 cLum = aColor.GetLuminance();
+ aColor = Color( cLum, cLum, cLum );
+ }
+
+ if( mnDrawMode & DRAWMODE_GHOSTEDLINE )
+ {
+ aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
+ ( aColor.GetGreen() >> 1 ) | 0x80,
+ ( aColor.GetBlue() >> 1 ) | 0x80);
+ }
+ }
+ }
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaLineColorAction( aColor, TRUE ) );
+
+ if( ImplIsColorTransparent( aColor ) )
+ {
+ if ( mbLineColor )
+ {
+ mbInitLineColor = TRUE;
+ mbLineColor = FALSE;
+ maLineColor = Color( COL_TRANSPARENT );
+ }
+ }
+ else
+ {
+ if( maLineColor != aColor )
+ {
+ mbInitLineColor = TRUE;
+ mbLineColor = TRUE;
+ maLineColor = aColor;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetFillColor()
+{
+ DBG_TRACE( "OutputDevice::SetFillColor()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaFillColorAction( Color(), FALSE ) );
+
+ if ( mbFillColor )
+ {
+ mbInitFillColor = TRUE;
+ mbFillColor = FALSE;
+ maFillColor = Color( COL_TRANSPARENT );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetFillColor( const Color& rColor )
+{
+ DBG_TRACE1( "OutputDevice::SetFillColor( %lx )", rColor.GetColor() );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Color aColor( rColor );
+
+ if( mnDrawMode & ( DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL |
+ DRAWMODE_GRAYFILL | DRAWMODE_NOFILL |
+ DRAWMODE_GHOSTEDFILL ) )
+ {
+ if( !ImplIsColorTransparent( aColor ) )
+ {
+ if( mnDrawMode & DRAWMODE_BLACKFILL )
+ {
+ aColor = Color( COL_BLACK );
+ }
+ else if( mnDrawMode & DRAWMODE_WHITEFILL )
+ {
+ aColor = Color( COL_WHITE );
+ }
+ else if( mnDrawMode & DRAWMODE_GRAYFILL )
+ {
+ const UINT8 cLum = aColor.GetLuminance();
+ aColor = Color( cLum, cLum, cLum );
+ }
+ else if( mnDrawMode & DRAWMODE_NOFILL )
+ {
+ aColor = Color( COL_TRANSPARENT );
+ }
+
+ if( mnDrawMode & DRAWMODE_GHOSTEDFILL )
+ {
+ aColor = Color( (aColor.GetRed() >> 1) | 0x80,
+ (aColor.GetGreen() >> 1) | 0x80,
+ (aColor.GetBlue() >> 1) | 0x80);
+ }
+ }
+ }
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaFillColorAction( aColor, TRUE ) );
+
+ if ( ImplIsColorTransparent( aColor ) )
+ {
+ if ( mbFillColor )
+ {
+ mbInitFillColor = TRUE;
+ mbFillColor = FALSE;
+ maFillColor = Color( COL_TRANSPARENT );
+ }
+ }
+ else
+ {
+ if ( maFillColor != aColor )
+ {
+ mbInitFillColor = TRUE;
+ mbFillColor = TRUE;
+ maFillColor = aColor;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetBackground()
+{
+ DBG_TRACE( "OutputDevice::SetBackground()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ maBackground = Wallpaper();
+ mbBackground = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetBackground( const Wallpaper& rBackground )
+{
+ DBG_TRACE( "OutputDevice::SetBackground( rBackground )" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ maBackground = rBackground;
+
+ if( rBackground.GetStyle() == WALLPAPER_NULL )
+ mbBackground = FALSE;
+ else
+ mbBackground = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetRefPoint()
+{
+ DBG_TRACE( "OutputDevice::SetRefPoint()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaRefPointAction( Point(), FALSE ) );
+
+ mbRefPoint = FALSE;
+ maRefPoint.X() = maRefPoint.Y() = 0L;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetRefPoint( const Point& rRefPoint )
+{
+ DBG_TRACE( "OutputDevice::SetRefPoint( rRefPoint )" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaRefPointAction( rRefPoint, TRUE ) );
+
+ mbRefPoint = TRUE;
+ maRefPoint = rRefPoint;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
+{
+ DBG_TRACE( "OutputDevice::DrawLine()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt ) );
+
+ if ( !IsDeviceOutputNecessary() || !mbLineColor )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ Point aStartPt = ImplLogicToDevicePixel( rStartPt );
+ Point aEndPt = ImplLogicToDevicePixel( rEndPt );
+
+ mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y() );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ pGraphics->DrawLine( ImplLogicToDevicePixel( rStartPt ),
+ ImplLogicToDevicePixel( rEndPt ) );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
+ const LineInfo& rLineInfo )
+{
+ DBG_TRACE( "OutputDevice::DrawLine()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( rLineInfo.IsDefault() )
+ {
+ DrawLine( rStartPt, rEndPt );
+ return;
+ }
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) );
+
+ if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LINE_NONE == rLineInfo.GetStyle() ) )
+ return;
+
+#ifndef REMOTE_APPSERVER
+
+ if( !mpGraphics && !ImplGetGraphics() )
+ return;
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if ( mbOutputClipped )
+ return;
+
+ const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
+
+ if( ( aInfo.GetWidth() > 1L ) || ( LINE_DASH == aInfo.GetStyle() ) )
+ {
+ Polygon aPoly( 2 ); aPoly[ 0 ] = rStartPt; aPoly[ 1 ] = rEndPt;
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ ImplLineConverter aLineCvt( ImplLogicToDevicePixel( aPoly ), aInfo, ( mbRefPoint ) ? &maRefPoint : NULL );
+
+ mpMetaFile = NULL;
+
+ if ( aInfo.GetWidth() > 1 )
+ {
+ const Color aOldLineColor( maLineColor );
+ const Color aOldFillColor( maFillColor );
+
+ SetLineColor();
+ ImplInitLineColor();
+ SetFillColor( aOldLineColor );
+ ImplInitFillColor();
+
+ for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
+ mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->ImplGetConstPointAry() );
+
+ SetFillColor( aOldFillColor );
+ SetLineColor( aOldLineColor );
+ }
+ else
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ for ( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
+ mpGraphics->DrawLine( (*pPoly)[ 0 ].X(), (*pPoly)[ 0 ].Y(), (*pPoly)[ 1 ].X(), (*pPoly)[ 1 ].Y() );
+ }
+ mpMetaFile = pOldMetaFile;
+ }
+ else
+ {
+ const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) );
+ const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) );
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y() );
+ }
+
+#else
+
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
+
+ if( ( aInfo.GetWidth() > 1L ) || ( LINE_DASH == aInfo.GetStyle() ) )
+ {
+ Polygon aPoly( 2 ); aPoly[ 0 ] = rStartPt; aPoly[ 1 ] = rEndPt;
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ ImplLineConverter aLineCvt( ImplLogicToDevicePixel( aPoly ), aInfo, ( mbRefPoint ) ? &maRefPoint : NULL );
+
+ mpMetaFile = NULL;
+
+ if ( aInfo.GetWidth() > 1 )
+ {
+ const Color aOldLineColor( maLineColor );
+ const Color aOldFillColor( maFillColor );
+
+ SetLineColor();
+ ImplInitLineColor();
+ SetFillColor( aOldLineColor );
+ ImplInitFillColor();
+
+ for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
+ pGraphics->DrawPolygon( *pPoly );
+
+ SetLineColor( aOldLineColor );
+ SetFillColor( aOldFillColor );
+ }
+ else
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ for ( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() ) {
+ Point xPoint((*pPoly)[ 0 ].X(), (*pPoly)[ 0 ].Y());
+ Point yPoint((*pPoly)[ 1 ].X(), (*pPoly)[ 1 ].Y());
+ mpGraphics->DrawLine( xPoint, yPoint );
+ }
+ }
+ mpMetaFile = pOldMetaFile;
+ }
+ else
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ pGraphics->DrawLine( ImplLogicToDevicePixel( rStartPt ), ImplLogicToDevicePixel( rEndPt ) );
+ }
+ }
+
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawRect( const Rectangle& rRect )
+{
+ DBG_TRACE( "OutputDevice::DrawRect()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaRectAction( rRect ) );
+
+ if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) )
+ return;
+
+ Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+
+ if ( aRect.IsEmpty() )
+ return;
+ aRect.Justify();
+
+#ifndef REMOTE_APPSERVER
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+
+ mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight() );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ pGraphics->DrawRect( aRect );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawPolyLine( const Polygon& rPoly )
+{
+ DBG_TRACE( "OutputDevice::DrawPolyLine()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rPoly, Polygon, NULL );
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) );
+
+ USHORT nPoints = rPoly.GetSize();
+
+ if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ Polygon aPoly = ImplLogicToDevicePixel( rPoly );
+
+ const SalPoint* pPtAry = (const SalPoint*)aPoly.ImplGetConstPointAry();
+ mpGraphics->DrawPolyLine( nPoints, pPtAry );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ pGraphics->DrawPolyLine( ImplLogicToDevicePixel( rPoly ) );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo )
+{
+ DBG_TRACE( "OutputDevice::DrawPolyLine()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rPoly, Polygon, NULL );
+
+ if ( rLineInfo.IsDefault() )
+ {
+ DrawPolyLine( rPoly );
+ return;
+ }
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) );
+
+ USHORT nPoints = rPoly.GetSize();
+
+ if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics && !ImplGetGraphics() )
+ return;
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if ( mbOutputClipped )
+ return;
+
+ const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
+
+ if( aInfo.GetWidth() > 1L )
+ {
+ const Color aOldLineColor( maLineColor );
+ const Color aOldFillColor( maFillColor );
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ ImplLineConverter aLineCvt( ImplLogicToDevicePixel( rPoly ), aInfo, ( mbRefPoint ) ? &maRefPoint : NULL );
+
+ mpMetaFile = NULL;
+ SetLineColor();
+ ImplInitLineColor();
+ SetFillColor( aOldLineColor );
+ ImplInitFillColor();
+
+ for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
+ mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->ImplGetConstPointAry() );
+
+ SetLineColor( aOldLineColor );
+ SetFillColor( aOldFillColor );
+ mpMetaFile = pOldMetaFile;
+ }
+ else
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( LINE_DASH == aInfo.GetStyle() )
+ {
+ ImplLineConverter aLineCvt( ImplLogicToDevicePixel( rPoly ), aInfo, ( mbRefPoint ) ? &maRefPoint : NULL );
+ for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
+ mpGraphics->DrawPolyLine( pPoly->GetSize(), (const SalPoint*)pPoly->ImplGetConstPointAry() );
+ }
+ else
+ mpGraphics->DrawPolyLine( nPoints, (const SalPoint*) ImplLogicToDevicePixel( rPoly ).ImplGetConstPointAry() );
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+
+ if ( pGraphics )
+ {
+ const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
+
+ if( aInfo.GetWidth() > 1L )
+ {
+ const Color aOldLineColor( maLineColor );
+ const Color aOldFillColor( maFillColor );
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ ImplLineConverter aLineCvt( ImplLogicToDevicePixel( rPoly ), aInfo, ( mbRefPoint ) ? &maRefPoint : NULL );
+
+ mpMetaFile = NULL;
+ SetLineColor();
+ ImplInitLineColor();
+ SetFillColor( aOldLineColor );
+ ImplInitFillColor();
+
+ for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
+ pGraphics->DrawPolygon( *pPoly );
+
+ SetLineColor( aOldLineColor );
+ SetFillColor( aOldFillColor );
+ mpMetaFile = pOldMetaFile;
+ }
+ else
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( LINE_DASH == aInfo.GetStyle() )
+ {
+ ImplLineConverter aLineCvt( ImplLogicToDevicePixel( rPoly ), aInfo, ( mbRefPoint ) ? &maRefPoint : NULL );
+ for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
+ pGraphics->DrawPolyLine( *pPoly );
+ }
+ else
+ pGraphics->DrawPolyLine( ImplLogicToDevicePixel( rPoly ) );
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawPolygon( const Polygon& rPoly )
+{
+ DBG_TRACE( "OutputDevice::DrawPolygon()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rPoly, Polygon, NULL );
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
+
+ USHORT nPoints = rPoly.GetSize();
+
+ if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+
+ Polygon aPoly = ImplLogicToDevicePixel( rPoly );
+
+ const SalPoint* pPtAry = (const SalPoint*)aPoly.ImplGetConstPointAry();
+ mpGraphics->DrawPolygon( nPoints, pPtAry );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ pGraphics->DrawPolygon( ImplLogicToDevicePixel( rPoly ) );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
+{
+ DBG_TRACE( "OutputDevice::DrawPolyPolygon()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
+
+ USHORT nPoly = rPolyPoly.Count();
+
+ if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+
+ if ( nPoly == 1 )
+ {
+ Polygon aPoly = ImplLogicToDevicePixel( rPolyPoly.GetObject( 0 ) );
+ USHORT nSize = aPoly.GetSize();
+ if ( nSize >= 2 )
+ {
+ const SalPoint* pPtAry = (const SalPoint*)aPoly.ImplGetConstPointAry();
+ mpGraphics->DrawPolygon( nSize, pPtAry );
+ }
+ }
+ else
+ {
+ PolyPolygon aPolyPoly = ImplLogicToDevicePixel( rPolyPoly );
+ ULONG aStackAry1[OUTDEV_POLYPOLY_STACKBUF];
+ PCONSTSALPOINT aStackAry2[OUTDEV_POLYPOLY_STACKBUF];
+ ULONG* pPointAry;
+ PCONSTSALPOINT* pPointAryAry;
+ USHORT i = 0;
+ if ( nPoly > OUTDEV_POLYPOLY_STACKBUF )
+ {
+ pPointAry = new ULONG[nPoly];
+ pPointAryAry = new PCONSTSALPOINT[nPoly];
+ }
+ else
+ {
+ pPointAry = aStackAry1;
+ pPointAryAry = aStackAry2;
+ }
+ do
+ {
+ const Polygon& rPoly = aPolyPoly.GetObject( i );
+ USHORT nSize = rPoly.GetSize();
+ if ( nSize )
+ {
+ pPointAry[i] = nSize;
+ pPointAryAry[i] = (PCONSTSALPOINT)rPoly.ImplGetConstPointAry();
+ i++;
+ }
+ else
+ nPoly--;
+ }
+ while ( i < nPoly );
+
+ if ( nPoly == 1 )
+ mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry );
+ else
+ mpGraphics->DrawPolyPolygon( nPoly, pPointAry, pPointAryAry );
+
+ if ( pPointAry != aStackAry1 )
+ {
+ delete pPointAry;
+ delete pPointAryAry;
+ }
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ if ( nPoly == 1 )
+ {
+ Polygon aPoly = ImplLogicToDevicePixel( rPolyPoly.GetObject( 0 ) );
+ USHORT nSize = aPoly.GetSize();
+ if ( nSize >= 2 )
+ pGraphics->DrawPolygon( aPoly );
+ }
+ else
+ pGraphics->DrawPolyPolygon( ImplLogicToDevicePixel( rPolyPoly ) );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::Push( USHORT nFlags )
+{
+ DBG_TRACE( "OutputDevice::Push()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPushAction( nFlags ) );
+
+ ImplObjStack* pData = new ImplObjStack;
+ pData->mpPrev = mpObjStack;
+ mpObjStack = pData;
+
+ pData->mnFlags = nFlags;
+
+ if ( nFlags & PUSH_LINECOLOR )
+ {
+ if ( mbLineColor )
+ pData->mpLineColor = new Color( maLineColor );
+ else
+ pData->mpLineColor = NULL;
+ }
+ if ( nFlags & PUSH_FILLCOLOR )
+ {
+ if ( mbFillColor )
+ pData->mpFillColor = new Color( maFillColor );
+ else
+ pData->mpFillColor = NULL;
+ }
+ if ( nFlags & PUSH_FONT )
+ pData->mpFont = new Font( maFont );
+ if ( nFlags & PUSH_TEXTCOLOR )
+ pData->mpTextColor = new Color( GetTextColor() );
+ if ( nFlags & PUSH_TEXTFILLCOLOR )
+ {
+ if ( IsTextFillColor() )
+ pData->mpTextFillColor = new Color( GetTextFillColor() );
+ else
+ pData->mpTextFillColor = NULL;
+ }
+ if ( nFlags & PUSH_TEXTLINECOLOR )
+ {
+ if ( IsTextLineColor() )
+ pData->mpTextLineColor = new Color( GetTextLineColor() );
+ else
+ pData->mpTextLineColor = NULL;
+ }
+ if ( nFlags & PUSH_TEXTALIGN )
+ pData->meTextAlign = GetTextAlign();
+ if ( nFlags & PUSH_RASTEROP )
+ pData->meRasterOp = GetRasterOp();
+ if ( nFlags & PUSH_MAPMODE )
+ {
+ if ( mbMap )
+ pData->mpMapMode = new MapMode( maMapMode );
+ else
+ pData->mpMapMode = NULL;
+ }
+ if ( nFlags & PUSH_CLIPREGION )
+ {
+ if ( mbClipRegion )
+ pData->mpClipRegion = new Region( maRegion );
+ else
+ pData->mpClipRegion = NULL;
+ }
+ if ( nFlags & PUSH_REFPOINT )
+ {
+ if ( mbRefPoint )
+ pData->mpRefPoint = new Point( maRefPoint );
+ else
+ pData->mpRefPoint = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::Pop()
+{
+ DBG_TRACE( "OutputDevice::Pop()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPopAction() );
+
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ ImplObjStack* pData = mpObjStack;
+ mpMetaFile = NULL;
+
+ if ( !pData )
+ {
+ DBG_ERRORFILE( "OutputDevice::Pop() without OutputDevice::Push()" );
+ return;
+ }
+
+ mpObjStack = pData->mpPrev;
+
+ if ( pData->mnFlags & PUSH_LINECOLOR )
+ {
+ if ( pData->mpLineColor )
+ SetLineColor( *pData->mpLineColor );
+ else
+ SetLineColor();
+ }
+ if ( pData->mnFlags & PUSH_FILLCOLOR )
+ {
+ if ( pData->mpFillColor )
+ SetFillColor( *pData->mpFillColor );
+ else
+ SetFillColor();
+ }
+ if ( pData->mnFlags & PUSH_FONT )
+ SetFont( *pData->mpFont );
+ if ( pData->mnFlags & PUSH_TEXTCOLOR )
+ SetTextColor( *pData->mpTextColor );
+ if ( pData->mnFlags & PUSH_TEXTFILLCOLOR )
+ {
+ if ( pData->mpTextFillColor )
+ SetTextFillColor( *pData->mpTextFillColor );
+ else
+ SetTextFillColor();
+ }
+ if ( pData->mnFlags & PUSH_TEXTLINECOLOR )
+ {
+ if ( pData->mpTextLineColor )
+ SetTextLineColor( *pData->mpTextLineColor );
+ else
+ SetTextLineColor();
+ }
+ if ( pData->mnFlags & PUSH_TEXTALIGN )
+ SetTextAlign( pData->meTextAlign );
+ if ( pData->mnFlags & PUSH_RASTEROP )
+ SetRasterOp( pData->meRasterOp );
+ if ( pData->mnFlags & PUSH_MAPMODE )
+ {
+ if ( pData->mpMapMode )
+ SetMapMode( *pData->mpMapMode );
+ else
+ SetMapMode();
+ }
+ if ( pData->mnFlags & PUSH_CLIPREGION )
+ ImplSetClipRegion( pData->mpClipRegion );
+ if ( pData->mnFlags & PUSH_REFPOINT )
+ {
+ if ( pData->mpRefPoint )
+ SetRefPoint( *pData->mpRefPoint );
+ else
+ SetRefPoint();
+ }
+
+ ImplDeleteObjStack( pData );
+
+ mpMetaFile = pOldMetaFile;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT OutputDevice::GetBitCount() const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( meOutDevType == OUTDEV_VIRDEV )
+ return ((VirtualDevice*)this)->mnBitCount;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !((OutputDevice*)this)->ImplGetGraphics() )
+ return 0;
+ }
+#endif
+
+ return (USHORT)mpGraphics->GetBitCount();
+}
+
+// -----------------------------------------------------------------------
+
+ULONG OutputDevice::GetColorCount() const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ const USHORT nBitCount = GetBitCount();
+ return( ( nBitCount > 31 ) ? ULONG_MAX : ( ( (ULONG) 1 ) << nBitCount) );
+}
+
+// -----------------------------------------------------------------------
+
+OpenGL* OutputDevice::GetOpenGL()
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+#ifndef REMOTE_APPSERVER
+ OpenGL* pOGL;
+
+ if( OUTDEV_PRINTER != meOutDevType )
+ {
+ pOGL = new OpenGL( this );
+
+ if( !pOGL->IsValid() )
+ {
+ delete pOGL;
+ pOGL = NULL;
+ }
+ }
+ else
+ pOGL = NULL;
+
+ return pOGL;
+#else
+ return NULL;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > OutputDevice::CreateUnoGraphics()
+{
+ UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
+ return pWrapper ? pWrapper->CreateGraphics( this ) : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >();
+}
diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx
new file mode 100644
index 000000000000..b454fe3632ff
--- /dev/null
+++ b/vcl/source/gdi/outdev2.cxx
@@ -0,0 +1,1928 @@
+/*************************************************************************
+ *
+ * $RCSfile: outdev2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_OUTDEV2_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_IMPBMP_HXX
+#include <impbmp.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_BITMAPEX_HXX
+#include <bitmapex.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_OUTDATA_HXX
+#include <outdata.hxx>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_REGION_H
+#include <region.h>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifdef REMOTE_APPSERVER
+#include <rmoutdev.hxx>
+#endif
+
+#define BAND_MAX_SIZE 512000
+
+// =======================================================================
+
+DBG_NAMEEX( OutputDevice );
+
+// =======================================================================
+
+// -----------
+// - Defines -
+// -----------
+
+#ifndef REMOTE_APPSERVER
+
+#define OUTDEV_INIT() \
+{ \
+ if ( !IsDeviceOutputNecessary() ) \
+ return; \
+ \
+ if ( !mpGraphics ) \
+ if ( !ImplGetGraphics() ) \
+ return; \
+ \
+ if ( mbInitClipRegion ) \
+ ImplInitClipRegion(); \
+ \
+ if ( mbOutputClipped ) \
+ return; \
+}
+
+#else // !REMOTE_APPSERVER
+
+#define OUTDEV_INIT() \
+{ \
+ if ( !IsDeviceOutputNecessary() ) \
+ return; \
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics(); \
+ if ( !pGraphics ) \
+ return; \
+}
+
+#endif // REMOTE_APPSERVER
+
+#ifndef REMOTE_APPSERVER
+#define TwoRect SalTwoRect
+#else
+#define TwoRect RemoteTwoRect
+#endif
+
+// -------------
+// - externals -
+// -------------
+
+extern ULONG nVCLRLut[ 6 ];
+extern ULONG nVCLGLut[ 6 ];
+extern ULONG nVCLBLut[ 6 ];
+extern ULONG nVCLDitherLut[ 256 ];
+extern ULONG nVCLLut[ 256 ];
+
+// =======================================================================
+
+ULONG ImplAdjustTwoRect( TwoRect& rTwoRect, const Size& rSizePix )
+{
+ ULONG nMirrFlags = 0;
+
+ if ( rTwoRect.mnDestWidth < 0 )
+ {
+ rTwoRect.mnSrcX = rSizePix.Width() - rTwoRect.mnSrcX - rTwoRect.mnSrcWidth;
+ rTwoRect.mnDestWidth = -rTwoRect.mnDestWidth;
+ rTwoRect.mnDestX -= rTwoRect.mnDestWidth-1;
+ nMirrFlags |= BMP_MIRROR_HORZ;
+ }
+
+ if ( rTwoRect.mnDestHeight < 0 )
+ {
+ rTwoRect.mnSrcY = rSizePix.Height() - rTwoRect.mnSrcY - rTwoRect.mnSrcHeight;
+ rTwoRect.mnDestHeight = -rTwoRect.mnDestHeight;
+ rTwoRect.mnDestY -= rTwoRect.mnDestHeight-1;
+ nMirrFlags |= BMP_MIRROR_VERT;
+ }
+
+ return nMirrFlags;
+}
+
+// =======================================================================
+
+void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pVoidPosAry )
+{
+ TwoRect* pPosAry = (TwoRect*)pVoidPosAry;
+#ifndef REMOTE_APPSERVER
+ SalGraphics* pGraphics2;
+#else
+ ImplServerGraphics* pGraphics2;
+#endif
+
+ if ( pPosAry->mnSrcWidth && pPosAry->mnSrcHeight && pPosAry->mnDestWidth && pPosAry->mnDestHeight )
+ {
+ if ( this == pSrcDev )
+ pGraphics2 = NULL;
+ else
+ {
+ if ( (GetOutDevType() != pSrcDev->GetOutDevType()) ||
+ (GetOutDevType() != OUTDEV_WINDOW) )
+ {
+#ifndef REMOTE_APPSERVER
+ if ( !pSrcDev->mpGraphics )
+ {
+ if ( !((OutputDevice*)pSrcDev)->ImplGetGraphics() )
+ return;
+ }
+#endif
+ pGraphics2 = pSrcDev->mpGraphics;
+ }
+ else
+ {
+ if ( ((Window*)this)->mpFrameWindow == ((Window*)pSrcDev)->mpFrameWindow )
+ pGraphics2 = NULL;
+ else
+ {
+#ifndef REMOTE_APPSERVER
+ if ( !pSrcDev->mpGraphics )
+ {
+ if ( !((OutputDevice*)pSrcDev)->ImplGetGraphics() )
+ return;
+ }
+#endif
+ pGraphics2 = pSrcDev->mpGraphics;
+
+#ifndef REMOTE_APPSERVER
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+ DBG_ASSERT( mpGraphics && pSrcDev->mpGraphics,
+ "OutputDevice::DrawOutDev(): We need more than one Graphics" );
+#endif
+ }
+ }
+ }
+
+ Rectangle aSrcOutRect( Point( pSrcDev->mnOutOffX, pSrcDev->mnOutOffY ),
+ Size( pSrcDev->mnOutWidth, pSrcDev->mnOutHeight ) );
+ Rectangle aSrcRect( Point( pPosAry->mnSrcX, pPosAry->mnSrcY ),
+ Size( pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ) );
+ const long nOldRight = aSrcRect.Right();
+ const long nOldBottom = aSrcRect.Bottom();
+
+ if ( !aSrcRect.Intersection( aSrcOutRect ).IsEmpty() )
+ {
+ if ( (pPosAry->mnSrcX+pPosAry->mnSrcWidth-1) > aSrcOutRect.Right() )
+ {
+ const long nOldWidth = pPosAry->mnSrcWidth;
+ pPosAry->mnSrcWidth -= (nOldRight - aSrcRect.Right());
+ pPosAry->mnDestWidth = pPosAry->mnDestWidth * pPosAry->mnSrcWidth / nOldWidth;
+ }
+
+ if ( (pPosAry->mnSrcY+pPosAry->mnSrcHeight-1) > aSrcOutRect.Bottom() )
+ {
+ const long nOldHeight = pPosAry->mnSrcHeight;
+ pPosAry->mnSrcHeight -= (nOldBottom - aSrcRect.Bottom());
+ pPosAry->mnDestHeight = pPosAry->mnDestHeight * pPosAry->mnSrcHeight / nOldHeight;
+ }
+
+ mpGraphics->CopyBits( pPosAry, pGraphics2 );
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPt, const Size& rSrcSize )
+{
+ DBG_TRACE( "OutputDevice::DrawOutDev()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_ASSERT( meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );
+
+ if ( meOutDevType == OUTDEV_PRINTER )
+ return;
+
+ if ( ROP_INVERT == meRasterOp )
+ {
+ DrawRect( Rectangle( rDestPt, rDestSize ) );
+ return;
+ }
+
+ if ( mpMetaFile )
+ {
+ const Bitmap aBmp( GetBitmap( rSrcPt, rSrcSize ) );
+ mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
+ }
+
+ OUTDEV_INIT();
+
+ TwoRect aPosAry;
+ aPosAry.mnSrcWidth = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
+ aPosAry.mnSrcHeight = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
+ aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
+ aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
+
+ if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
+ {
+ aPosAry.mnSrcX = ImplLogicXToDevicePixel( rSrcPt.X() );
+ aPosAry.mnSrcY = ImplLogicYToDevicePixel( rSrcPt.Y() );
+ aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
+ aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
+
+ Rectangle aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
+ Size( mnOutWidth, mnOutHeight ) );
+ Rectangle aSrcRect( Point( aPosAry.mnSrcX, aPosAry.mnSrcY ),
+ Size( aPosAry.mnSrcWidth, aPosAry.mnSrcHeight ) );
+ long nOldRight = aSrcRect.Right();
+ long nOldBottom = aSrcRect.Bottom();
+
+ if ( !aSrcRect.Intersection( aSrcOutRect ).IsEmpty() )
+ {
+ if ( (aPosAry.mnSrcX+aPosAry.mnSrcWidth-1) > aSrcOutRect.Right() )
+ {
+ long nOldWidth = aPosAry.mnSrcWidth;
+ aPosAry.mnSrcWidth -= nOldRight-aSrcRect.Right();
+ aPosAry.mnDestWidth = aPosAry.mnDestWidth*aPosAry.mnSrcWidth/nOldWidth;
+ }
+
+ if ( (aPosAry.mnSrcY+aPosAry.mnSrcHeight-1) > aSrcOutRect.Bottom() )
+ {
+ long nOldHeight = aPosAry.mnSrcHeight;
+ aPosAry.mnSrcHeight -= nOldBottom-aSrcRect.Bottom();
+ aPosAry.mnDestHeight = aPosAry.mnDestHeight*aPosAry.mnSrcHeight/nOldHeight;
+ }
+
+ mpGraphics->CopyBits( &aPosAry, NULL );
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPt, const Size& rSrcSize,
+ const OutputDevice& rOutDev )
+{
+ DBG_TRACE( "OutputDevice::DrawOutDev()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rOutDev, OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_ASSERT( meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );
+ DBG_ASSERT( rOutDev.meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );
+
+ if ( (meOutDevType == OUTDEV_PRINTER) || (rOutDev.meOutDevType == OUTDEV_PRINTER) )
+ return;
+
+ if ( ROP_INVERT == meRasterOp )
+ {
+ DrawRect( Rectangle( rDestPt, rDestSize ) );
+ return;
+ }
+
+ if ( mpMetaFile )
+ {
+ const Bitmap aBmp( rOutDev.GetBitmap( rSrcPt, rSrcSize ) );
+ mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
+ }
+
+ OUTDEV_INIT();
+
+ TwoRect aPosAry;
+ aPosAry.mnSrcX = rOutDev.ImplLogicXToDevicePixel( rSrcPt.X() );
+ aPosAry.mnSrcY = rOutDev.ImplLogicYToDevicePixel( rSrcPt.Y() );
+ aPosAry.mnSrcWidth = rOutDev.ImplLogicWidthToDevicePixel( rSrcSize.Width() );
+ aPosAry.mnSrcHeight = rOutDev.ImplLogicHeightToDevicePixel( rSrcSize.Height() );
+ aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
+ aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
+ aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
+ aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
+
+ ImplDrawOutDevDirect( &rOutDev, &aPosAry );
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::CopyArea( const Point& rDestPt,
+ const Point& rSrcPt, const Size& rSrcSize,
+ USHORT nFlags )
+{
+ DBG_TRACE( "OutputDevice::CopyArea()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_ASSERT( meOutDevType != OUTDEV_PRINTER, "Don't use OutputDevice::CopyArea(...) with printer devices!" );
+
+ if ( meOutDevType == OUTDEV_PRINTER )
+ return;
+
+ RasterOp eOldRop = GetRasterOp();
+ SetRasterOp( ROP_OVERPAINT );
+
+ OUTDEV_INIT();
+
+ TwoRect aPosAry;
+ aPosAry.mnSrcWidth = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
+ aPosAry.mnSrcHeight = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
+
+ if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight )
+ {
+ aPosAry.mnSrcX = ImplLogicXToDevicePixel( rSrcPt.X() );
+ aPosAry.mnSrcY = ImplLogicYToDevicePixel( rSrcPt.Y() );
+ aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
+ aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
+
+ Rectangle aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
+ Size( mnOutWidth, mnOutHeight ) );
+ Rectangle aSrcRect( Point( aPosAry.mnSrcX, aPosAry.mnSrcY ),
+ Size( aPosAry.mnSrcWidth, aPosAry.mnSrcHeight ) );
+ long nOldRight = aSrcRect.Right();
+ long nOldBottom = aSrcRect.Bottom();
+
+ if ( !aSrcRect.Intersection( aSrcOutRect ).IsEmpty() )
+ {
+ if ( (aPosAry.mnSrcX+aPosAry.mnSrcWidth-1) > aSrcOutRect.Right() )
+ aPosAry.mnSrcWidth -= nOldRight-aSrcRect.Right();
+
+ if ( (aPosAry.mnSrcY+aPosAry.mnSrcHeight-1) > aSrcOutRect.Bottom() )
+ aPosAry.mnSrcHeight -= nOldBottom-aSrcRect.Bottom();
+
+ if ( (meOutDevType == OUTDEV_WINDOW) && (nFlags & COPYAREA_WINDOWINVALIDATE) )
+ {
+ ((Window*)this)->ImplMoveAllInvalidateRegions( aSrcRect,
+ aPosAry.mnDestX-aPosAry.mnSrcX,
+ aPosAry.mnDestY-aPosAry.mnSrcY,
+ FALSE );
+
+#ifndef REMOTE_APPSERVER
+ mpGraphics->CopyArea( aPosAry.mnDestX, aPosAry.mnDestY,
+ aPosAry.mnSrcX, aPosAry.mnSrcY,
+ aPosAry.mnSrcWidth, aPosAry.mnSrcHeight,
+ SAL_COPYAREA_WINDOWINVALIDATE );
+#else
+ mpGraphics->CopyArea( aPosAry.mnDestX, aPosAry.mnDestY,
+ aPosAry.mnSrcX, aPosAry.mnSrcY,
+ aPosAry.mnSrcWidth, aPosAry.mnSrcHeight,
+ COPYAREA_WINDOWINVALIDATE );
+#endif
+ }
+ else
+ {
+ aPosAry.mnDestWidth = aPosAry.mnSrcWidth;
+ aPosAry.mnDestHeight = aPosAry.mnSrcHeight;
+ mpGraphics->CopyBits( &aPosAry, NULL );
+ }
+ }
+ }
+
+ SetRasterOp( eOldRop );
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::ImplDrawFrameDev( const Point& rPt, const Point& rDevPt, const Size& rDevSize,
+ const OutputDevice& rOutDev, const Region& rRegion )
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ BOOL bOldMap = mbMap;
+ RasterOp eOldROP = GetRasterOp();
+ mpMetaFile = NULL;
+ mbMap = FALSE;
+ SetRasterOp( ROP_OVERPAINT );
+
+#ifndef REMOTE_APPSERVER
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+#else
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+#endif
+
+ // ClipRegion zuruecksetzen
+#ifndef REMOTE_APPSERVER
+ if ( rRegion.IsNull() )
+ mpGraphics->ResetClipRegion();
+ else
+ ImplSelectClipRegion( mpGraphics, rRegion );
+#else
+ if ( rRegion.IsNull() )
+ mpGraphics->SetClipRegion();
+ else
+ mpGraphics->SetClipRegion( rRegion );
+#endif
+
+ TwoRect aPosAry;
+ aPosAry.mnSrcX = rDevPt.X();
+ aPosAry.mnSrcY = rDevPt.Y();
+ aPosAry.mnSrcWidth = rDevSize.Width();
+ aPosAry.mnSrcHeight = rDevSize.Height();
+ aPosAry.mnDestX = rPt.X();
+ aPosAry.mnDestY = rPt.Y();
+ aPosAry.mnDestWidth = rDevSize.Width();
+ aPosAry.mnDestHeight = rDevSize.Height();
+ ImplDrawOutDevDirect( &rOutDev, &aPosAry );
+
+ // Dafuer sorgen, das ClipRegion neu berechnet und gesetzt wird
+ mbInitClipRegion = TRUE;
+
+ SetRasterOp( eOldROP );
+ mbMap = bOldMap;
+ mpMetaFile = pOldMetaFile;
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::ImplGetFrameDev( const Point& rPt, const Point& rDevPt, const Size& rDevSize,
+ OutputDevice& rDev )
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ BOOL bOldMap = mbMap;
+ mbMap = FALSE;
+ rDev.DrawOutDev( rDevPt, rDevSize, rPt, rDevSize, *this );
+ mbMap = bOldMap;
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawBitmap( const Point& rDestPt, const Bitmap& rBitmap )
+{
+ DBG_TRACE( "OutputDevice::DrawBitmap()" );
+ const Size aSizePix( rBitmap.GetSizePixel() );
+ ImplDrawBitmap( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmap, META_BMP_ACTION );
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize, const Bitmap& rBitmap )
+{
+ DBG_TRACE( "OutputDevice::DrawBitmap( Size )" );
+ ImplDrawBitmap( rDestPt, rDestSize, Point(), rBitmap.GetSizePixel(), rBitmap, META_BMPSCALE_ACTION );
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel,
+ const Bitmap& rBitmap )
+{
+ DBG_TRACE( "OutputDevice::DrawBitmap( Point, Size )" );
+ ImplDrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmap, META_BMPSCALEPART_ACTION );
+}
+
+// -----------------------------------------------------------------------------
+
+void OutputDevice::ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel,
+ const Bitmap& rBitmap, const ULONG nAction )
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Bitmap aBmp( rBitmap );
+
+ if ( ( mnDrawMode & DRAWMODE_NOBITMAP ) )
+ return;
+ else if ( ROP_INVERT == meRasterOp )
+ {
+ DrawRect( Rectangle( rDestPt, rDestSize ) );
+ return;
+ }
+ else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP |
+ DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) )
+ {
+ if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) )
+ {
+ BYTE cCmpVal;
+
+ if ( mnDrawMode & DRAWMODE_BLACKBITMAP )
+ cCmpVal = ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP ) ? 0x80 : 0;
+ else
+ cCmpVal = 255;
+
+ Color aCol( cCmpVal, cCmpVal, cCmpVal );
+ Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ SetLineColor( aCol );
+ SetFillColor( aCol );
+ DrawRect( Rectangle( rDestPt, rDestSize ) );
+ Pop();
+ return;
+ }
+ else if( !!aBmp )
+ {
+ if ( mnDrawMode & DRAWMODE_GRAYBITMAP )
+ aBmp.Convert( BMP_CONVERSION_8BIT_GREYS );
+
+ if ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP )
+ aBmp.Convert( BMP_CONVERSION_GHOSTED );
+ }
+ }
+
+ if ( mpMetaFile )
+ {
+ switch( nAction )
+ {
+ case( META_BMP_ACTION ):
+ mpMetaFile->AddAction( new MetaBmpAction( rDestPt, aBmp ) );
+ break;
+
+ case( META_BMPSCALE_ACTION ):
+ mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
+ break;
+
+ case( META_BMPSCALEPART_ACTION ):
+ mpMetaFile->AddAction( new MetaBmpScalePartAction(
+ rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, aBmp ) );
+ break;
+ }
+ }
+
+ OUTDEV_INIT();
+
+ if( ( OUTDEV_PRINTER == meOutDevType ) && mbClipRegion && ( REGION_COMPLEX == maRegion.GetType() ) )
+ {
+ Bitmap aMask;
+ ImplPrintTransparent( aBmp, aMask, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
+ return;
+ }
+
+ if ( !( !aBmp ) )
+ {
+ TwoRect aPosAry;
+
+ aPosAry.mnSrcX = rSrcPtPixel.X();
+ aPosAry.mnSrcY = rSrcPtPixel.Y();
+ aPosAry.mnSrcWidth = rSrcSizePixel.Width();
+ aPosAry.mnSrcHeight = rSrcSizePixel.Height();
+ aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
+ aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
+ aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
+ aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
+
+ const ULONG nMirrFlags = ImplAdjustTwoRect( aPosAry, aBmp.GetSizePixel() );
+
+ if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
+ {
+ if ( nMirrFlags )
+ aBmp.Mirror( nMirrFlags );
+
+#ifndef REMOTE_APPSERVER
+ mpGraphics->DrawBitmap( &aPosAry, *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap() );
+#else
+ aBmp.ImplDrawRemote( this,
+ Point( aPosAry.mnSrcX, aPosAry.mnSrcY ),
+ Size( aPosAry.mnSrcWidth, aPosAry.mnSrcHeight ),
+ Point( aPosAry.mnDestX, aPosAry.mnDestY ),
+ Size( aPosAry.mnDestWidth, aPosAry.mnDestHeight ) );
+#endif
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawBitmapEx( const Point& rDestPt,
+ const BitmapEx& rBitmapEx )
+{
+ DBG_TRACE( "OutputDevice::DrawBitmapEx()" );
+
+ if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
+ DrawBitmap( rDestPt, rBitmapEx.GetBitmap() );
+ else
+ {
+ const Size aSizePix( rBitmapEx.GetSizePixel() );
+ ImplDrawBitmapEx( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmapEx, META_BMPEX_ACTION );
+ }
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
+ const BitmapEx& rBitmapEx )
+{
+ DBG_TRACE( "OutputDevice::DrawBitmapEx( Size )" );
+
+ if ( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
+ DrawBitmap( rDestPt, rDestSize, rBitmapEx.GetBitmap() );
+ else
+ ImplDrawBitmapEx( rDestPt, rDestSize, Point(), rBitmapEx.GetSizePixel(), rBitmapEx, META_BMPEXSCALE_ACTION );
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel,
+ const BitmapEx& rBitmapEx )
+{
+ DBG_TRACE( "OutputDevice::DrawBitmapEx( Point, Size )" );
+
+ if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() )
+ DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx.GetBitmap() );
+ else
+ ImplDrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx, META_BMPEXSCALEPART_ACTION );
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel,
+ const BitmapEx& rBitmapEx, const ULONG nAction )
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ BitmapEx aBmpEx( rBitmapEx );
+
+ if ( mnDrawMode & DRAWMODE_NOBITMAP )
+ return;
+ else if ( ROP_INVERT == meRasterOp )
+ {
+ DrawRect( Rectangle( rDestPt, rDestSize ) );
+ return;
+ }
+ else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP |
+ DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) )
+ {
+ if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) )
+ {
+ Bitmap aColorBmp( aBmpEx.GetSizePixel(), ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP ) ? 4 : 1 );
+ BYTE cCmpVal;
+
+ if ( mnDrawMode & DRAWMODE_BLACKBITMAP )
+ cCmpVal = ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP ) ? 0x80 : 0;
+ else
+ cCmpVal = 255;
+
+ aColorBmp.Erase( Color( cCmpVal, cCmpVal, cCmpVal ) );
+
+ if( aBmpEx.IsAlpha() )
+ aBmpEx = BitmapEx( aColorBmp, aBmpEx.GetAlpha() );
+ else
+ aBmpEx = BitmapEx( aColorBmp, aBmpEx.GetMask() );
+ }
+ else if( !!aBmpEx )
+ {
+ if ( mnDrawMode & DRAWMODE_GRAYBITMAP )
+ aBmpEx.Convert( BMP_CONVERSION_8BIT_GREYS );
+
+ if ( mnDrawMode & DRAWMODE_GHOSTEDBITMAP )
+ aBmpEx.Convert( BMP_CONVERSION_GHOSTED );
+ }
+ }
+
+ if ( mpMetaFile )
+ {
+ switch( nAction )
+ {
+ case( META_BMPEX_ACTION ):
+ mpMetaFile->AddAction( new MetaBmpExAction( rDestPt, aBmpEx ) );
+ break;
+
+ case( META_BMPEXSCALE_ACTION ):
+ mpMetaFile->AddAction( new MetaBmpExScaleAction( rDestPt, rDestSize, aBmpEx ) );
+ break;
+
+ case( META_BMPEXSCALEPART_ACTION ):
+ mpMetaFile->AddAction( new MetaBmpExScalePartAction( rDestPt, rDestSize,
+ rSrcPtPixel, rSrcSizePixel, aBmpEx ) );
+ break;
+ }
+ }
+
+ OUTDEV_INIT();
+
+ if( OUTDEV_PRINTER == meOutDevType )
+ {
+ Bitmap aBmp( aBmpEx.GetBitmap() ), aMask( aBmpEx.GetMask() );
+ aBmp.Replace( aMask, Color( COL_WHITE ) );
+ ImplPrintTransparent( aBmp, aMask, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
+ return;
+ }
+#ifndef REMOTE_APPSERVER
+ else if( rBitmapEx.IsAlpha() )
+ {
+ ImplDrawAlpha( aBmpEx.GetBitmap(), aBmpEx.GetAlpha(), rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
+ return;
+ }
+#endif
+
+ if( !( !aBmpEx ) )
+ {
+ TwoRect aPosAry;
+
+ aPosAry.mnSrcX = rSrcPtPixel.X();
+ aPosAry.mnSrcY = rSrcPtPixel.Y();
+ aPosAry.mnSrcWidth = rSrcSizePixel.Width();
+ aPosAry.mnSrcHeight = rSrcSizePixel.Height();
+ aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
+ aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
+ aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
+ aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
+
+ const ULONG nMirrFlags = ImplAdjustTwoRect( aPosAry, aBmpEx.GetSizePixel() );
+
+ if( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
+ {
+#ifndef REMOTE_APPSERVER
+
+ if( nMirrFlags )
+ aBmpEx.Mirror( nMirrFlags );
+
+ const ImpBitmap* pImpBmp = aBmpEx.ImplGetBitmapImpBitmap();
+ const ImpBitmap* pMaskBmp = aBmpEx.ImplGetMaskImpBitmap();
+
+ if ( pMaskBmp )
+ mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap(), *pMaskBmp->ImplGetSalBitmap() );
+ else
+ mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap() );
+
+#else
+
+ if( nMirrFlags )
+ aBmpEx.Mirror( nMirrFlags );
+
+ aBmpEx.ImplDrawRemote( this,
+ Point( aPosAry.mnSrcX, aPosAry.mnSrcY ),
+ Size( aPosAry.mnSrcWidth, aPosAry.mnSrcHeight ),
+ Point( aPosAry.mnDestX, aPosAry.mnDestY ),
+ Size( aPosAry.mnDestWidth, aPosAry.mnDestHeight ) );
+
+#endif
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawMask( const Point& rDestPt,
+ const Bitmap& rBitmap, const Color& rMaskColor )
+{
+ DBG_TRACE( "OutputDevice::DrawMask()" );
+ const Size aSizePix( rBitmap.GetSizePixel() );
+ ImplDrawMask( rDestPt, PixelToLogic( aSizePix ), Point(), aSizePix, rBitmap, rMaskColor, META_MASK_ACTION );
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawMask( const Point& rDestPt, const Size& rDestSize,
+ const Bitmap& rBitmap, const Color& rMaskColor )
+{
+ DBG_TRACE( "OutputDevice::DrawMask( Size )" );
+ ImplDrawMask( rDestPt, rDestSize, Point(), rBitmap.GetSizePixel(), rBitmap, rMaskColor, META_MASKSCALE_ACTION );
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::DrawMask( const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel,
+ const Bitmap& rBitmap, const Color& rMaskColor )
+{
+ DBG_TRACE( "OutputDevice::DrawMask( Point, Size )" );
+ ImplDrawMask( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmap, rMaskColor, META_MASKSCALEPART_ACTION );
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::ImplDrawMask( const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel,
+ const Bitmap& rBitmap, const Color& rMaskColor,
+ const ULONG nAction )
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if( ROP_INVERT == meRasterOp )
+ {
+ DrawRect( Rectangle( rDestPt, rDestSize ) );
+ return;
+ }
+
+ if ( mpMetaFile )
+ {
+ switch( nAction )
+ {
+ case( META_MASK_ACTION ):
+ mpMetaFile->AddAction( new MetaMaskAction( rDestPt,
+ rBitmap, rMaskColor ) );
+ break;
+
+ case( META_MASKSCALE_ACTION ):
+ mpMetaFile->AddAction( new MetaMaskScaleAction( rDestPt,
+ rDestSize, rBitmap, rMaskColor ) );
+ break;
+
+ case( META_MASKSCALEPART_ACTION ):
+ mpMetaFile->AddAction( new MetaMaskScalePartAction( rDestPt, rDestSize,
+ rSrcPtPixel, rSrcSizePixel, rBitmap, rMaskColor ) );
+ break;
+ }
+ }
+
+ OUTDEV_INIT();
+
+#ifndef REMOTE_APPSERVER
+ if ( OUTDEV_PRINTER == meOutDevType )
+ {
+ ImplPrintMask( rBitmap, rMaskColor, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
+ return;
+ }
+#endif
+
+ const ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap();
+
+ if ( pImpBmp )
+ {
+ TwoRect aPosAry;
+
+ aPosAry.mnSrcX = rSrcPtPixel.X();
+ aPosAry.mnSrcY = rSrcPtPixel.Y();
+ aPosAry.mnSrcWidth = rSrcSizePixel.Width();
+ aPosAry.mnSrcHeight = rSrcSizePixel.Height();
+ aPosAry.mnDestX = ImplLogicXToDevicePixel( rDestPt.X() );
+ aPosAry.mnDestY = ImplLogicYToDevicePixel( rDestPt.Y() );
+ aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
+ aPosAry.mnDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
+
+ // spiegeln via Koordinaten wollen wir nicht
+ const ULONG nMirrFlags = ImplAdjustTwoRect( aPosAry, pImpBmp->ImplGetSize() );
+
+ // check if output is necessary
+ if( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
+ {
+#ifndef REMOTE_APPSERVER
+
+ if( nMirrFlags )
+ {
+ Bitmap aTmp( rBitmap );
+ aTmp.Mirror( nMirrFlags );
+ mpGraphics->DrawMask( &aPosAry, *aTmp.ImplGetImpBitmap()->ImplGetSalBitmap(),
+ ImplColorToSal( rMaskColor ) );
+ }
+ else
+ mpGraphics->DrawMask( &aPosAry, *pImpBmp->ImplGetSalBitmap(),
+ ImplColorToSal( rMaskColor ) );
+
+#else
+
+ if( nMirrFlags )
+ {
+ Bitmap aTmp( rBitmap );
+ aTmp.Mirror( nMirrFlags );
+ aTmp.ImplDrawRemoteMask( this,
+ Point( aPosAry.mnSrcX, aPosAry.mnSrcY ),
+ Size( aPosAry.mnSrcWidth, aPosAry.mnSrcHeight ),
+ Point( aPosAry.mnDestX, aPosAry.mnDestY ),
+ Size( aPosAry.mnDestWidth, aPosAry.mnDestHeight ),
+ rMaskColor );
+ }
+ else
+ rBitmap.ImplDrawRemoteMask( this,
+ Point( aPosAry.mnSrcX, aPosAry.mnSrcY ),
+ Size( aPosAry.mnSrcWidth, aPosAry.mnSrcHeight ),
+ Point( aPosAry.mnDestX, aPosAry.mnDestY ),
+ Size( aPosAry.mnDestWidth, aPosAry.mnDestHeight ),
+ rMaskColor );
+
+#endif
+ }
+ }
+}
+
+// ------------------------------------------------------------------
+
+Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Bitmap aBmp;
+ long nX = ImplLogicXToDevicePixel( rSrcPt.X() );
+ long nY = ImplLogicYToDevicePixel( rSrcPt.Y() );
+ long nWidth = ImplLogicWidthToDevicePixel( rSize.Width() );
+ long nHeight = ImplLogicHeightToDevicePixel( rSize.Height() );
+
+#ifndef REMOTE_APPSERVER
+ if ( mpGraphics || ( (OutputDevice*) this )->ImplGetGraphics() )
+#endif
+ {
+ if ( nWidth && nHeight )
+ {
+#ifndef REMOTE_APPSERVER
+ Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
+ BOOL bClipped = FALSE;
+
+ // X-Koordinate ausserhalb des Bereichs?
+ if ( nX < mnOutOffX )
+ {
+ nWidth -= ( mnOutOffX - nX );
+ nX = mnOutOffX;
+ bClipped = TRUE;
+ }
+
+ // Y-Koordinate ausserhalb des Bereichs?
+ if ( nY < mnOutOffY )
+ {
+ nHeight -= ( mnOutOffY - nY );
+ nY = mnOutOffY;
+ bClipped = TRUE;
+ }
+
+ // Breite ausserhalb des Bereichs?
+ if ( (nWidth + nX) > (mnOutWidth + mnOutOffX) )
+ {
+ nWidth = mnOutOffX + mnOutWidth - nX;
+ bClipped = TRUE;
+ }
+
+ // Hoehe ausserhalb des Bereichs?
+ if ( (nHeight + nY) > (mnOutHeight + mnOutOffY) )
+ {
+ nHeight = mnOutOffY + mnOutHeight - nY;
+ bClipped = TRUE;
+ }
+
+ if ( bClipped )
+ {
+ // Falls auf den sichtbaren Bereich geclipped wurde,
+ // muessen wir eine Bitmap in der rchtigen Groesse
+ // erzeugen, in die die geclippte Bitmap an die angepasste
+ // Position kopiert wird
+ VirtualDevice aVDev( *this );
+
+ if ( aVDev.SetOutputSizePixel( aRect.GetSize() ) )
+ {
+ if ( ((OutputDevice*)&aVDev)->mpGraphics || ((OutputDevice*)&aVDev)->ImplGetGraphics() )
+ {
+ TwoRect aPosAry;
+
+ aPosAry.mnSrcX = nX;
+ aPosAry.mnSrcY = nY;
+ aPosAry.mnSrcWidth = nWidth;
+ aPosAry.mnSrcHeight = nHeight;
+ aPosAry.mnDestX = ( aRect.Left() < mnOutOffX ) ? ( mnOutOffX - aRect.Left() ) : 0L;
+ aPosAry.mnDestY = ( aRect.Top() < mnOutOffY ) ? ( mnOutOffY - aRect.Top() ) : 0L;
+ aPosAry.mnDestWidth = nWidth;
+ aPosAry.mnDestHeight = nHeight;
+
+ if ( (nWidth > 0) && (nHeight > 0) )
+ (((OutputDevice*)&aVDev)->mpGraphics)->CopyBits( &aPosAry, mpGraphics );
+
+ aBmp = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
+ }
+ else
+ bClipped = FALSE;
+ }
+ else
+ bClipped = FALSE;
+ }
+
+ if ( !bClipped )
+ {
+ SalBitmap* pSalBmp = mpGraphics->GetBitmap( nX, nY, nWidth, nHeight );
+
+ if( pSalBmp )
+ {
+ ImpBitmap* pImpBmp = new ImpBitmap;
+ pImpBmp->ImplSetSalBitmap( pSalBmp );
+ aBmp.ImplSetImpBitmap( pImpBmp );
+ }
+ }
+#else
+ aBmp.ImplGetRemoteBmp( (OutputDevice*) this, Point( nX, nY ), Size( nWidth, nHeight ) );
+#endif
+ }
+ }
+
+ return aBmp;
+}
+
+// ------------------------------------------------------------------
+
+void OutputDevice::ImplGetFrameBitmap( const Point& rDestPt, const Size& rSize,
+ Bitmap& rBitmap ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ BOOL bOldMap = mbMap;
+ ((OutputDevice*)this)->mbMap = FALSE;
+ rBitmap = GetBitmap( rDestPt, rSize );
+ ((OutputDevice*)this)->mbMap = bOldMap;
+}
+
+// ------------------------------------------------------------------
+
+Color OutputDevice::GetPixel( const Point& rPt ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Color aColor;
+
+#ifndef REMOTE_APPSERVER
+ if ( mpGraphics || ((OutputDevice*)this)->ImplGetGraphics() )
+ {
+ if ( mbInitClipRegion )
+ ((OutputDevice*)this)->ImplInitClipRegion();
+
+ if ( !mbOutputClipped )
+ {
+ const long nX = ImplLogicXToDevicePixel( rPt.X() );
+ const long nY = ImplLogicYToDevicePixel( rPt.Y() );
+ const SalColor aSalCol = mpGraphics->GetPixel( nX, nY );
+ aColor.SetRed( SALCOLOR_RED( aSalCol ) );
+ aColor.SetGreen( SALCOLOR_GREEN( aSalCol ) );
+ aColor.SetBlue( SALCOLOR_BLUE( aSalCol ) );
+ }
+ }
+#else // REMOTE_APPSERVER
+ ImplServerGraphics* pGraphics = ( (OutputDevice*) this )->ImplGetServerGraphics();
+ if( pGraphics )
+ {
+ const long nX = ImplLogicXToDevicePixel( rPt.X() );
+ const long nY = ImplLogicYToDevicePixel( rPt.Y() );
+ aColor = pGraphics->GetPixel( Point( nX, nY ) );
+ }
+#endif // REMOTE_APPSERVER
+
+ return aColor;
+}
+
+// ------------------------------------------------------------------
+
+Color* OutputDevice::GetPixel( const Polygon& rPts ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Color* pColors = NULL;
+ const USHORT nSize = rPts.GetSize();
+
+ if( nSize )
+ {
+#ifndef REMOTE_APPSERVER
+ if ( mpGraphics || ((OutputDevice*)this)->ImplGetGraphics() )
+ {
+ if ( mbInitClipRegion )
+ ((OutputDevice*)this)->ImplInitClipRegion();
+
+ if ( !mbOutputClipped )
+ {
+ pColors = new Color[ nSize ];
+
+ for( USHORT i = 0; i < nSize; i++ )
+ {
+ Color& rCol = pColors[ i ];
+ const Point& rPt = rPts[ i ];
+ const SalColor aSalCol( mpGraphics->GetPixel( ImplLogicXToDevicePixel( rPt.X() ),
+ ImplLogicYToDevicePixel( rPt.Y() ) ) );
+
+ rCol.SetRed( SALCOLOR_RED( aSalCol ) );
+ rCol.SetGreen( SALCOLOR_GREEN( aSalCol ) );
+ rCol.SetBlue( SALCOLOR_BLUE( aSalCol ) );
+ }
+ }
+ }
+#else // REMOTE_APPSERVER
+ ImplServerGraphics* pGraphics = ( (OutputDevice*) this )->ImplGetServerGraphics();
+ if( pGraphics )
+ {
+ pColors = pGraphics->GetPixel( ImplLogicToDevicePixel( rPts ) );
+ }
+#endif // REMOTE_APPSERVER
+ }
+
+ return pColors;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawPixel( const Point& rPt )
+{
+ DBG_TRACE( "OutputDevice::DrawPixel()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPointAction( rPt ) );
+
+ if ( !IsDeviceOutputNecessary() || !mbLineColor )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ Point aPt = ImplLogicToDevicePixel( rPt );
+
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ mpGraphics->DrawPixel( aPt.X(), aPt.Y() );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ pGraphics->DrawPixel( ImplLogicToDevicePixel( rPt ) );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawPixel( const Point& rPt, const Color& rColor )
+{
+ DBG_TRACE( "OutputDevice::DrawPixel()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Color aColor( rColor );
+
+ if( mnDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE |
+ DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE ) )
+ {
+ if( !ImplIsColorTransparent( aColor ) )
+ {
+ if( mnDrawMode & DRAWMODE_BLACKLINE )
+ {
+ aColor = Color( COL_BLACK );
+ }
+ else if( mnDrawMode & DRAWMODE_WHITELINE )
+ {
+ aColor = Color( COL_WHITE );
+ }
+ else if( mnDrawMode & DRAWMODE_GRAYLINE )
+ {
+ const UINT8 cLum = aColor.GetLuminance();
+ aColor = Color( cLum, cLum, cLum );
+ }
+
+ if( mnDrawMode & DRAWMODE_GHOSTEDLINE )
+ {
+ aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
+ ( aColor.GetGreen() >> 1 ) | 0x80,
+ ( aColor.GetBlue() >> 1 ) | 0x80 );
+ }
+ }
+ }
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPixelAction( rPt, aColor ) );
+
+ if ( !IsDeviceOutputNecessary() || ImplIsColorTransparent( aColor ) )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ Point aPt = ImplLogicToDevicePixel( rPt );
+
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ mpGraphics->DrawPixel( aPt.X(), aPt.Y(), ImplColorToSal( aColor ) );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ pGraphics->DrawPixel( ImplLogicToDevicePixel( rPt ), aColor );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawPixel( const Polygon& rPts, const Color* pColors )
+{
+ if ( !pColors )
+ DrawPixel( rPts, GetLineColor() );
+ else
+ {
+ DBG_TRACE( "OutputDevice::DrawPixel()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_ASSERT( pColors, "OutputDevice::DrawPixel: No color array specified" );
+
+ const USHORT nSize = rPts.GetSize();
+
+ if ( nSize )
+ {
+ if ( mpMetaFile )
+ for ( USHORT i = 0; i < nSize; i++ )
+ mpMetaFile->AddAction( new MetaPixelAction( rPts[ i ], pColors[ i ] ) );
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( mpGraphics || ImplGetGraphics() )
+ {
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if ( mbOutputClipped )
+ return;
+
+ for ( USHORT i = 0; i < nSize; i++ )
+ {
+ const Point aPt( ImplLogicToDevicePixel( rPts[ i ] ) );
+ mpGraphics->DrawPixel( aPt.X(), aPt.Y(), ImplColorToSal( pColors[ i ] ) );
+ }
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ pGraphics->DrawPixel( ImplLogicToDevicePixel( rPts ), pColors );
+ }
+#endif
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawPixel( const Polygon& rPts, const Color& rColor )
+{
+ if( rColor != COL_TRANSPARENT )
+ {
+ const USHORT nSize = rPts.GetSize();
+ Color* pColArray = new Color[ nSize ];
+
+ for( USHORT i = 0; i < nSize; i++ )
+ pColArray[ i ] = rColor;
+
+ DrawPixel( rPts, pColArray );
+ delete[] pColArray;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha,
+ const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel )
+{
+ Point aPt;
+ Point aOutPt( LogicToPixel( rDestPt ) );
+ Size aOutSz( LogicToPixel( rDestSize ) );
+ Rectangle aDstRect( aPt, GetOutputSizePixel() );
+ const BOOL bHMirr = aOutSz.Width() < 0, bVMirr = aOutSz.Height() < 0;
+
+ if( OUTDEV_WINDOW == meOutDevType )
+ {
+ const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
+
+ if( !aPaintRgn.IsNull() )
+ aDstRect.Intersection( LogicToPixel( aPaintRgn.GetBoundRect() ) );
+ }
+
+ if( bHMirr )
+ {
+ aOutSz.Width() = -aOutSz.Width();
+ aOutPt.X() -= ( aOutSz.Width() - 1L );
+ }
+
+ if( bVMirr )
+ {
+ aOutSz.Height() = -aOutSz.Height();
+ aOutPt.Y() -= ( aOutSz.Height() - 1L );
+ }
+
+ if( !aDstRect.Intersection( Rectangle( aOutPt, aOutSz ) ).IsEmpty() )
+ {
+ Rectangle aBmpRect( aPt, rBmp.GetSizePixel() );
+
+ if( !aBmpRect.Intersection( Rectangle( rSrcPtPixel, rSrcSizePixel ) ).IsEmpty() )
+ {
+ GDIMetaFile* pOldMetaFile = mpMetaFile; mpMetaFile = NULL;
+ const BOOL bOldMap = mbMap; mbMap = FALSE;
+ Bitmap aBmp( GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );
+ BitmapColor aDstCol;
+ const long nSrcWidth = aBmpRect.GetWidth(), nSrcHeight = aBmpRect.GetHeight();
+ const long nDstWidth = aDstRect.GetWidth(), nDstHeight = aDstRect.GetHeight();
+ const long nOutWidth = aOutSz.Width(), nOutHeight = aOutSz.Height();
+ const long nOffX = aDstRect.Left() - aOutPt.X(), nOffY = aDstRect.Top() - aOutPt.Y();
+ long nX, nOutX, nY, nOutY, nMirrOffX, nMirrOffY;
+ long* pMapX = new long[ nDstWidth ];
+ long* pMapY = new long[ nDstHeight ];
+
+ // create horizontal mapping table
+ if( bHMirr )
+ nMirrOffX = ( aBmpRect.Left() << 1 ) + nSrcWidth - 1;
+
+ for( nX = 0L, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
+ {
+ pMapX[ nX ] = aBmpRect.Left() + nOutX * nSrcWidth / nOutWidth;
+
+ if( bHMirr )
+ pMapX[ nX ] = nMirrOffX - pMapX[ nX ];
+ }
+
+ // create vertical mapping table
+ if( bVMirr )
+ nMirrOffY = ( aBmpRect.Top() << 1 ) + nSrcHeight - 1;
+
+ for( nY = 0L, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
+ {
+ pMapY[ nY ] = aBmpRect.Top() + nOutY * nSrcHeight / nOutHeight;
+
+ if( bVMirr )
+ pMapY[ nY ] = nMirrOffY - pMapY[ nY ];
+ }
+
+ if( GetBitCount() <= 8 )
+ {
+ Bitmap aDither( aBmp.GetSizePixel(), 8 );
+ BitmapColor aIndex( 0 );
+ BitmapReadAccess* pP = ( (Bitmap&) rBmp ).AcquireReadAccess();
+ BitmapReadAccess* pA = ( (AlphaMask&) rAlpha ).AcquireReadAccess();
+ BitmapReadAccess* pB = aBmp.AcquireReadAccess();
+ BitmapWriteAccess* pW = aDither.AcquireWriteAccess();
+
+ if( pB && pP && pA && pW )
+ {
+ for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
+ {
+ const long nMapY = pMapY[ nY ];
+ const long nModY = ( nOutY & 0x0FL ) << 4L;
+
+ for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
+ {
+ const long nMapX = pMapX[ nX ];
+ const ULONG nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ];
+
+ aDstCol = pB->GetColor( nY, nX );
+ aDstCol.Merge( pP->GetColor( nMapY, nMapX ), (BYTE) pA->GetPixel( nMapY, nMapX ) );
+ aIndex.SetIndex( (BYTE) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] +
+ nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] +
+ nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) );
+ pW->SetPixel( nY, nX, aIndex );
+ }
+ }
+ }
+
+ ( (Bitmap&) rBmp ).ReleaseAccess( pP );
+ ( (AlphaMask&) rAlpha ).ReleaseAccess( pA );
+ aBmp.ReleaseAccess( pB );
+ aDither.ReleaseAccess( pW );
+ DrawBitmap( aDstRect.TopLeft(), aDither );
+ }
+ else
+ {
+ BitmapReadAccess* pP = ( (Bitmap&) rBmp ).AcquireReadAccess();
+ BitmapReadAccess* pA = ( (AlphaMask&) rAlpha ).AcquireReadAccess();
+ BitmapWriteAccess* pB = aBmp.AcquireWriteAccess();
+
+ if( pP && pA && pB )
+ {
+ if( pA->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ switch( pP->GetScanlineFormat() )
+ {
+ case( BMP_FORMAT_8BIT_PAL ):
+ {
+ for( nY = 0; nY < nDstHeight; nY++ )
+ {
+ const long nMapY = pMapY[ nY ];
+ Scanline pPScan = pP->GetScanline( nMapY );
+ Scanline pAScan = pA->GetScanline( nMapY );
+
+ for( nX = 0; nX < nDstWidth; nX++ )
+ {
+ const long nMapX = pMapX[ nX ];
+ aDstCol = pB->GetPixel( nY, nX );
+ pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetPaletteColor( pPScan[ nMapX ] ),
+ pAScan[ nMapX ] ) );
+ }
+ }
+ }
+ break;
+
+ case( BMP_FORMAT_24BIT_TC_BGR ):
+ {
+ for( nY = 0; nY < nDstHeight; nY++ )
+ {
+ const long nMapY = pMapY[ nY ];
+ Scanline pPScan = pP->GetScanline( nMapY );
+ Scanline pAScan = pA->GetScanline( nMapY );
+
+ for( nX = 0; nX < nDstWidth; nX++ )
+ {
+ const long nMapX = pMapX[ nX ];
+ Scanline pTmp = pPScan + nMapX * 3;
+
+ aDstCol = pB->GetPixel( nY, nX );
+ pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 2 ], pTmp[ 1 ], pTmp[ 0 ],
+ pAScan[ nMapX ] ) );
+ }
+ }
+ }
+ break;
+
+ case( BMP_FORMAT_24BIT_TC_RGB ):
+ {
+ for( nY = 0; nY < nDstHeight; nY++ )
+ {
+ const long nMapY = pMapY[ nY ];
+ Scanline pPScan = pP->GetScanline( nMapY );
+ Scanline pAScan = pA->GetScanline( nMapY );
+
+ for( nX = 0; nX < nDstWidth; nX++ )
+ {
+ const long nMapX = pMapX[ nX ];
+ Scanline pTmp = pPScan + nMapX * 3;
+
+ aDstCol = pB->GetPixel( nY, nX );
+ pB->SetPixel( nY, nX, aDstCol.Merge( pTmp[ 0 ], pTmp[ 1 ], pTmp[ 2 ],
+ pAScan[ nMapX ] ) );
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ for( nY = 0; nY < nDstHeight; nY++ )
+ {
+ const long nMapY = pMapY[ nY ];
+ Scanline pAScan = pA->GetScanline( nMapY );
+
+ for( nX = 0; nX < nDstWidth; nX++ )
+ {
+ const long nMapX = pMapX[ nX ];
+ aDstCol = pB->GetPixel( nY, nX );
+ pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetColor( nMapY, nMapX ),
+ pAScan[ nMapX ] ) );
+ }
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ for( nY = 0; nY < nDstHeight; nY++ )
+ {
+ const long nMapY = pMapY[ nY ];
+
+ for( nX = 0; nX < nDstWidth; nX++ )
+ {
+ const long nMapX = pMapX[ nX ];
+ aDstCol = pB->GetPixel( nY, nX );
+ pB->SetPixel( nY, nX, aDstCol.Merge( pP->GetColor( nMapY, nMapX ),
+ (BYTE) pA->GetPixel( nMapY, nMapX ) ) );
+ }
+ }
+ }
+ }
+
+ ( (Bitmap&) rBmp ).ReleaseAccess( pP );
+ ( (AlphaMask&) rAlpha ).ReleaseAccess( pA );
+ aBmp.ReleaseAccess( pB );
+ DrawBitmap( aDstRect.TopLeft(), aBmp );
+ }
+
+ delete[] pMapX;
+ delete[] pMapY;
+ mbMap = bOldMap;
+ mpMetaFile = pOldMetaFile;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+static Pair* ImplGetMap( long nFromSize, long nToSize )
+{
+ DBG_ASSERT( nFromSize && nToSize, "ImplGetMap(): Invalid size!" );
+
+ Pair* pMap = new Pair[ nFromSize ];
+ const double fSize = (double) nToSize / nFromSize;
+ double fRealSum = 0.0;
+ const long nLastToPos = nToSize - 1L;
+ long nErrSum = 0L, nPos = 0L, nSize = 0L;
+
+ for( long i = 0L; i < nFromSize; i++ )
+ {
+ nPos = nPos + nSize;
+ nSize = Max( FRound( fSize - ( nErrSum - fRealSum ) ), 0L );
+
+ nErrSum += nSize;
+ fRealSum += fSize;
+
+ pMap[ i ].A() = nPos = Min( nPos, nLastToPos );
+ pMap[ i ].B() = Min( nPos + Max( nSize, 1L ) - 1L, nLastToPos );
+ }
+
+ return pMap;
+}
+
+// ------------------------------------------------------------------------
+
+static BOOL ImplCreateBandBitmaps( BitmapReadAccess* pPAcc, BitmapReadAccess* pMAcc,
+ long* pMapX, long* pMapY,
+ long nDstWidth, long nDstY1, long nDstY2,
+ Bitmap& rPaint, Bitmap& rMask )
+{
+ const Size aSz( nDstWidth, nDstY2 - nDstY1 + 1 );
+ BOOL bRet = FALSE;
+
+ rPaint = Bitmap( aSz, pPAcc->GetBitCount(), pPAcc->HasPalette() ? &pPAcc->GetPalette() : NULL );
+ rMask = Bitmap( aSz, pMAcc->GetBitCount(), pMAcc->HasPalette() ? &pMAcc->GetPalette() : NULL );
+
+ BitmapWriteAccess* pWPAcc = rPaint.AcquireWriteAccess();
+ BitmapWriteAccess* pWMAcc = rMask.AcquireWriteAccess();
+
+ if( pWPAcc && pWMAcc )
+ {
+ const long nWidth = pWPAcc->Width();
+ const long nHeight = pWPAcc->Width();
+ const long nPScanSize = pWPAcc->GetScanlineSize();
+ const long nMScanSize = pWMAcc->GetScanlineSize();
+ long nY = 0, nScanY = nDstY1;
+
+ while( nScanY <= nDstY2 )
+ {
+ const long nMapY = pMapY[ nScanY ];
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ const long nMapX = pMapX[ nX ];
+ pWPAcc->SetPixel( nY, nX, pPAcc->GetPixel( nMapY, nMapX ) );
+ pWMAcc->SetPixel( nY, nX, pMAcc->GetPixel( nMapY, nMapX ) );
+ }
+
+ while( ( nScanY < nDstY2 ) && ( pMapY[ nScanY + 1 ] == nMapY ) )
+ {
+ HMEMCPY( pWPAcc->GetScanline( nY + 1L ), pWPAcc->GetScanline( nY ), nPScanSize );
+ HMEMCPY( pWMAcc->GetScanline( nY + 1L ), pWMAcc->GetScanline( nY ), nMScanSize );
+ nY++, nScanY++;
+ }
+
+ nY++, nScanY++;
+ }
+
+ bRet = TRUE;
+ }
+
+ if( pWPAcc )
+ rPaint.ReleaseAccess( pWPAcc );
+
+ if( pWMAcc )
+ rMask.ReleaseAccess( pWMAcc );
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void OutputDevice::ImplPrintTransparent( const Bitmap& rBmp, const Bitmap& rMask,
+ const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel )
+{
+ Point aPt;
+ Point aDestPt( LogicToPixel( rDestPt ) );
+ Size aDestSz( LogicToPixel( rDestSize ) );
+ Rectangle aSrcRect( rSrcPtPixel, rSrcSizePixel );
+
+ aSrcRect.Justify();
+
+ if( !!rBmp && aSrcRect.GetWidth() && aSrcRect.GetHeight() && aDestSz.Width() && aDestSz.Height() )
+ {
+ ULONG nMirrFlags = 0UL;
+ Bitmap aPaint( rBmp );
+ Bitmap aMask( rMask );
+ Region aDstRgn;
+ BOOL bMask = !!aMask;
+
+ if( bMask && ( aMask.GetBitCount() > 1 ) )
+ aMask.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
+
+ // mirrored horizontically
+ if( aDestSz.Width() < 0L )
+ {
+ aDestSz.Width() = -aDestSz.Width();
+ aDestPt.X() -= ( aDestSz.Width() - 1L );
+ nMirrFlags |= BMP_MIRROR_HORZ;
+ }
+
+ // mirrored vertically
+ if( aDestSz.Height() < 0L )
+ {
+ aDestSz.Height() = -aDestSz.Height();
+ aDestPt.Y() -= ( aDestSz.Height() - 1L );
+ nMirrFlags |= BMP_MIRROR_VERT;
+ }
+
+ // source cropped?
+ if( aSrcRect != Rectangle( aPt, aPaint.GetSizePixel() ) )
+ {
+ aPaint.Crop( aSrcRect );
+ if( bMask )
+ aMask.Crop( aSrcRect );
+ }
+
+ // destination mirrored
+ if( nMirrFlags )
+ {
+ aPaint.Mirror( nMirrFlags );
+ if( bMask )
+ aMask.Mirror( nMirrFlags );
+ }
+
+ const Rectangle aDstRect( aDestPt, aDestSz );
+
+ // create destination region
+ if( mbClipRegion && !maRegion.IsEmpty() )
+ {
+ aDstRgn = maRegion;
+ aDstRgn.Intersect( aDstRect );
+ }
+ else
+ aDstRgn = aDstRect;
+
+ aDstRgn.Move( -aDstRect.Left(), -aDstRect.Top() );
+
+ // we always want to have a mask
+ if( !bMask )
+ {
+ aMask = Bitmap( aSrcRect.GetSize(), 1 );
+ aMask.Erase( Color( COL_BLACK ) );
+ }
+
+ BitmapReadAccess* pPAcc = aPaint.AcquireReadAccess();
+ BitmapReadAccess* pMAcc = aMask.AcquireReadAccess();
+
+ if( pPAcc && pMAcc )
+ {
+ const long nWidth = aDestSz.Width();
+ const long nHeight = aDestSz.Height();
+ const long nWidth1 = nWidth - 1;
+ const long nHeight1 = nHeight - 1;
+ const long nOldWidth1 = aSrcRect.GetWidth() - 1;
+ const long nOldHeight1 = aSrcRect.GetHeight() - 1;
+ const long nScanByteCount = Max( nWidth * aPaint.GetBitCount() / 8L, 1L );
+ const long nBandHeight = BAND_MAX_SIZE / nScanByteCount + 1;
+ long* pMapX = new long[ nWidth ];
+ long* pMapY = new long[ nHeight ];
+ long nX, nY;
+ long nBandY1, nBandY2;
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ const BOOL bOldMap = mbMap;
+
+ mpMetaFile = NULL;
+ Push( PUSH_CLIPREGION );
+ SetClipRegion();
+ mbMap = FALSE;
+
+ // create mapping tables
+ for( nX = 0L; nX < nWidth; nX++ )
+ pMapX[ nX ] = nWidth1 ? ( nX * nOldWidth1 / nWidth1 ) : 0;
+
+ for( nY = 0L; nY < nHeight; nY++ )
+ pMapY[ nY ] = nHeight1 ? ( nY * nOldHeight1 / nHeight1 ) : 0;
+
+ // process bands
+ for( nBandY1 = 0, nBandY2 = nBandHeight; nBandY1 < nHeight; nBandY1 += nBandHeight, nBandY2 += nBandHeight )
+ {
+ Bitmap aWorkPaint, aWorkMask;
+
+ // don't walk over bounds
+ if( nBandY2 > nHeight1 )
+ nBandY2 = nHeight1;
+
+ if( ImplCreateBandBitmaps( pPAcc, pMAcc, pMapX, pMapY, nWidth, nBandY1, nBandY2, aWorkPaint, aWorkMask ) )
+ {
+ Region aWorkRgn( aDstRgn );
+ aWorkRgn.Move( 0, -nBandY1 );
+ aWorkRgn.Intersect( aWorkMask.CreateRegion( COL_BLACK, Rectangle( aPt, aWorkMask.GetSizePixel() ) ) );
+
+ ImplRegionInfo aInfo;
+ long nWorkX, nWorkY, nWorkWidth, nWorkHeight;
+ BOOL bRgnRect = aWorkRgn.ImplGetFirstRect( aInfo, nWorkX, nWorkY,
+ nWorkWidth, nWorkHeight );
+
+ while( bRgnRect )
+ {
+ Bitmap aCropBmp( aWorkPaint );
+ const Point aOutPt( nWorkX + aDestPt.X(), nWorkY + nBandY1 + aDestPt.Y() );
+ const Size aOutSz( nWorkWidth, nWorkHeight );
+ const Size aOutSz1( nWorkWidth + 1, nWorkHeight + 1 );
+
+ aCropBmp.Crop( Rectangle( Point( nWorkX, nWorkY ), aOutSz ) );
+ ImplDrawBitmap( aOutPt, aOutSz1, Point(), aOutSz, aCropBmp, META_BMPSCALE_ACTION );
+ bRgnRect = aWorkRgn.ImplGetNextRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
+ }
+ }
+ }
+
+ delete[] pMapX;
+ delete[] pMapY;
+ mbMap = bOldMap;
+ Pop();
+ mpMetaFile = pOldMetaFile;
+ }
+
+ if( pPAcc )
+ aPaint.ReleaseAccess( pPAcc );
+
+ if( pMAcc )
+ aMask.ReleaseAccess( pMAcc );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void OutputDevice::ImplPrintMask( const Bitmap& rMask, const Color& rMaskColor,
+ const Point& rDestPt, const Size& rDestSize,
+ const Point& rSrcPtPixel, const Size& rSrcSizePixel )
+{
+#ifndef REMOTE_APPSERVER
+
+ Point aPt;
+ Point aDestPt( LogicToPixel( rDestPt ) );
+ Size aDestSz( LogicToPixel( rDestSize ) );
+ Rectangle aSrcRect( rSrcPtPixel, rSrcSizePixel );
+
+ aSrcRect.Justify();
+
+ if( !!rMask &&
+ aSrcRect.GetWidth() && aSrcRect.GetHeight() &&
+ aDestSz.Width() && aDestSz.Height() )
+ {
+ ULONG nMirrFlags = 0UL;
+ Bitmap aMask( rMask );
+ Region aRegion;
+
+ if( aMask.GetBitCount() > 1 )
+ aMask.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
+
+ if( aDestSz.Width() < 0L )
+ {
+ aDestSz.Width() = -aDestSz.Width();
+ aDestPt.X() -= ( aDestSz.Width() - 1L );
+ nMirrFlags |= BMP_MIRROR_HORZ;
+ }
+
+ if( aDestSz.Height() < 0L )
+ {
+ aDestSz.Height() = -aDestSz.Height();
+ aDestPt.Y() -= ( aDestSz.Height() - 1L );
+ nMirrFlags |= BMP_MIRROR_VERT;
+ }
+
+ // source cropped?
+ if( aSrcRect != Rectangle( aPt, aMask.GetSizePixel() ) )
+ aMask.Crop( aSrcRect );
+
+ // destination mirrored
+ if( nMirrFlags )
+ aMask.Mirror( nMirrFlags );
+
+ aRegion = aMask.CreateRegion( COL_BLACK, Rectangle( Point(), aMask.GetSizePixel() ) );
+
+ ImplRegionInfo aInfo;
+ const Size aSrcSz( aMask.GetSizePixel() );
+ long nSrcX, nSrcY, nSrcWidth, nSrcHeight;
+ long nDstX, nDstY, nDstWidth, nDstHeight;
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ Pair* pMapX = ImplGetMap( aSrcSz.Width(), aDestSz.Width() );
+ Pair* pMapY = ImplGetMap( aSrcSz.Height(), aDestSz.Height() );
+ BOOL bOldMap = mbMap;
+ BOOL bRegionRect = aRegion.ImplGetFirstRect( aInfo, nSrcX, nSrcY, nSrcWidth, nSrcHeight );
+
+ mpMetaFile = NULL;
+ mbMap = FALSE;
+ Push( PUSH_FILLCOLOR | PUSH_LINECOLOR );
+ SetLineColor( rMaskColor );
+ SetFillColor( rMaskColor );
+ ImplInitLineColor();
+ ImplInitFillColor();
+
+ while( bRegionRect )
+ {
+ nDstX = pMapX[ nSrcX ].A();
+ nDstY = pMapY[ nSrcY ].A();
+ nDstWidth = pMapX[ nSrcX + nSrcWidth - 1L ].B() - nDstX + 1L;
+ nDstHeight = pMapY[ nSrcY + nSrcHeight - 1L ].B() - nDstY + 1L;
+ mpGraphics->DrawRect( nDstX + aDestPt.X(), nDstY + aDestPt.Y(), nDstWidth, nDstHeight );
+ bRegionRect = aRegion.ImplGetNextRect( aInfo, nSrcX, nSrcY, nSrcWidth, nSrcHeight );
+ }
+
+ Pop();
+ delete[] pMapX;
+ delete[] pMapY;
+ mbMap = bOldMap;
+ mpMetaFile = pOldMetaFile;
+ }
+
+#endif
+}
diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
new file mode 100644
index 000000000000..4dbd5935f2ae
--- /dev/null
+++ b/vcl/source/gdi/outdev3.cxx
@@ -0,0 +1,6326 @@
+/*************************************************************************
+ *
+ * $RCSfile: outdev3.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <math.h>
+#include <string.h>
+
+#define _SV_OUTDEV_CXX
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#endif
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#else
+#ifndef _SV_RMOUTDEV_HXX
+#include <rmoutdev.hxx>
+#endif
+#endif
+
+#ifndef _RTL_TENCINFO_H
+#include <rtl/tencinfo.h>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_METRIC_HXX
+#include <metric.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_OUTDATA_HXX
+#include <outdata.hxx>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_PRINT_HXX
+#include <print.hxx>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_EDIT_HXX
+#include <edit.hxx>
+#endif
+
+#include <unohelp.hxx>
+
+#ifndef _COM_SUN_STAR_TEXT_XBREAKITERATOR_HPP_
+#include <com/sun/star/text/XBreakIterator.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TEXT_WORDTYPE_HPP_
+#include <com/sun/star/text/WordType.hpp>
+#endif
+
+#if defined UNX
+#define GLYPH_FONT_HEIGHT 128
+#elif defined OS2
+#define GLYPH_FONT_HEIGHT 176
+#else
+#define GLYPH_FONT_HEIGHT 256
+#endif
+
+#define WSstrcmp strcmp
+
+// =======================================================================
+
+DBG_NAMEEX( OutputDevice );
+DBG_NAMEEX( Font );
+
+// =======================================================================
+
+#define OUTDEV_CHARCONVERT_REPLACE FALSE
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+
+
+// =======================================================================
+
+#define MAX_DX_WORDS 120
+#define TEXT_DRAW_ELLIPSIS (TEXT_DRAW_ENDELLIPSIS | TEXT_DRAW_PATHELLIPSIS | TEXT_DRAW_NEWSELLIPSIS)
+
+// =======================================================================
+
+#define UNDERLINE_LAST UNDERLINE_BOLDWAVE
+#define STRIKEOUT_LAST STRIKEOUT_X
+
+// =======================================================================
+
+void OutputDevice::ImplUpdateFontData( BOOL bNewFontLists )
+{
+ if ( mpFontEntry )
+ {
+ mpFontCache->Release( mpFontEntry );
+ mpFontEntry = NULL;
+ }
+ if ( bNewFontLists )
+ {
+ if ( mpGetDevFontList )
+ {
+ delete mpGetDevFontList;
+ mpGetDevFontList = NULL;
+ }
+ if ( mpGetDevSizeList )
+ {
+ delete mpGetDevSizeList;
+ mpGetDevSizeList = NULL;
+ }
+ }
+
+ if ( GetOutDevType() == OUTDEV_PRINTER )
+ {
+ mpFontCache->Clear();
+
+ if ( bNewFontLists )
+ {
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( ImplGetGraphics() )
+#endif
+ {
+ mpFontList->Clear();
+ mpGraphics->GetDevFontList( mpFontList );
+ mpFontList->InitStdFonts();
+ }
+ }
+ }
+
+ mbInitFont = TRUE;
+ mbNewFont = TRUE;
+
+ // Bei Fenstern auch alle Child-Fenster mit updaten
+ if ( GetOutDevType() == OUTDEV_WINDOW )
+ {
+ Window* pChild = ((Window*)this)->mpFirstChild;
+ while ( pChild )
+ {
+ pChild->ImplUpdateFontData( TRUE );
+ pChild = pChild->mpNext;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplUpdateAllFontData( BOOL bNewFontLists )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Alle Fenster updaten
+ Window* pFrame = pSVData->maWinData.mpFirstFrame;
+ while ( pFrame )
+ {
+ pFrame->ImplUpdateFontData( bNewFontLists );
+
+ Window* pSysWin = pFrame->mpFrameData->mpFirstOverlap;
+ while ( pSysWin )
+ {
+ pSysWin->ImplUpdateFontData( bNewFontLists );
+ pSysWin = pSysWin->mpNextOverlap;
+ }
+
+ pFrame = pFrame->mpFrameData->mpNextFrame;
+ }
+
+ // Alle VirDev's updaten
+ VirtualDevice* pVirDev = pSVData->maGDIData.mpFirstVirDev;
+ while ( pVirDev )
+ {
+ pVirDev->ImplUpdateFontData( bNewFontLists );
+ pVirDev = pVirDev->mpNext;
+ }
+
+ // Alle Printer updaten
+ Printer* pPrinter = pSVData->maGDIData.mpFirstPrinter;
+ while ( pPrinter )
+ {
+ pPrinter->ImplUpdateFontData( bNewFontLists );
+ pPrinter = pPrinter->mpNext;
+ }
+
+ // Globale Fontlisten leeren, damit diese geupdatet werden
+ pSVData->maGDIData.mpScreenFontCache->Clear();
+ if ( bNewFontLists )
+ {
+ pSVData->maGDIData.mpScreenFontList->Clear();
+ pFrame = pSVData->maWinData.mpFirstFrame;
+ if ( pFrame )
+ {
+#ifndef REMOTE_APPSERVER
+ if ( pFrame->ImplGetGraphics() )
+#endif
+ {
+ pFrame->mpGraphics->GetDevFontList( pFrame->mpFrameData->mpFontList );
+ pFrame->mpFrameData->mpFontList->InitStdFonts();
+ }
+ }
+ }
+}
+
+// =======================================================================
+
+struct ImplFontSubstEntry
+{
+ XubString maName;
+ XubString maReplaceName;
+ XubString maMatchName;
+ XubString maMatchReplaceName;
+ USHORT mnFlags;
+ ImplFontSubstEntry* mpNext;
+};
+
+// =======================================================================
+
+static void ImplStrEraseAllSymbols( XubString& rStr )
+{
+ xub_StrLen i = 0;
+ xub_Unicode c = rStr.GetChar( i );
+ while ( c )
+ {
+ // Alle Zeichen kleiner 0 zwischen 9-A, Z-a und z-127 loeschen
+ if ( (c < 48) || ((c > 57) && (c < 65)) || ((c > 90) && (c < 97)) ||
+ ((c > 122) && (c <= 127)) )
+ rStr.Erase( i, 1 );
+ else
+ i++;
+ c = rStr.GetChar( i );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static xub_StrLen ImplStrMatch( const XubString& rStr1, const XubString& rStr2 )
+{
+ xub_StrLen nMatch = 0;
+ const xub_Unicode* pStr1 = rStr1.GetBuffer();
+ const xub_Unicode* pStr2 = rStr2.GetBuffer();
+ while ( (*pStr1 == *pStr2) && *pStr1 )
+ {
+ pStr1++;
+ pStr2++;
+ nMatch++;
+ }
+ return nMatch;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplStrFullMatch( const XubString& rStr1, const char* pStr2 )
+{
+ const xub_Unicode* pStr1 = rStr1.GetBuffer();
+ while ( (*pStr1 == (xub_Unicode)(unsigned char)*pStr2) && *pStr1 )
+ {
+ pStr1++;
+ pStr2++;
+ }
+ return !(*pStr1);
+}
+
+// =======================================================================
+
+#if 0
+
+#define FONT_ATTR_SYMBOL ((ULONG)0x00000001)
+#define FONT_ATTR_FIXED ((ULONG)0x00000002)
+#define FONT_ATTR_ITALIC ((ULONG)0x00000004)
+#define FONT_ATTR_NORMAL ((ULONG)0x00000008)
+#define FONT_ATTR_STANDARD ((ULONG)0x00000010)
+#define FONT_ATTR_SPECIAL ((ULONG)0x00000020)
+#define FONT_ATTR_TITLING ((ULONG)0x00000040)
+#define FONT_ATTR_SERIF ((ULONG)0x00000080)
+#define FONT_ATTR_NONSERIF ((ULONG)0x00000100)
+#define FONT_ATTR_ROUNDED ((ULONG)0x00000200)
+#define FONT_ATTR_OUTLINE ((ULONG)0x00000400)
+#define FONT_ATTR_SHADOW ((ULONG)0x00000800)
+#define FONT_ATTR_SCRIPT ((ULONG)0x00001000)
+#define FONT_ATTR_HANDWRITING ((ULONG)0x00002000)
+#define FONT_ATTR_DECORATION ((ULONG)0x00004000)
+#define FONT_ATTR_CHARSCRIPT ((ULONG)0x00008000)
+#define FONT_ATTR_CHANCERY ((ULONG)0x00010000)
+#define FONT_ATTR_OLDSTYLE ((ULONG)0x00020000)
+#define FONT_ATTR_FAVOR1 ((ULONG)0x01000000)
+#define FONT_ATTR_FAVOR2 ((ULONG)0x02000000)
+#define FONT_ATTR_FAVOR3 ((ULONG)0x04000000)
+#define FONT_ATTR_FAVOR4 ((ULONG)0x08000000)
+#define FONT_ATTR_FOUND ((ULONG)0x80000000)
+
+struct ImplFontAttrWidthSearchData
+{
+ const char* mpStr;
+ FontWidth meWidth;
+};
+
+static ImplFontAttrWidthSearchData const aImplWidthAttrSearchList[] =
+{
+{ "narrow", WIDTH_CONDENSED },
+{ "semicondensed", WIDTH_SEMI_CONDENSED },
+{ "ultracondensed", WIDTH_ULTRA_CONDENSED },
+{ "semiexpanded", WIDTH_SEMI_EXPANDED },
+{ "ultraexpanded", WIDTH_ULTRA_EXPANDED },
+{ "expanded", WIDTH_EXPANDED },
+{ "wide", WIDTH_ULTRA_EXPANDED },
+{ "condensed", WIDTH_CONDENSED },
+{ "cond", WIDTH_CONDENSED },
+{ "cn", WIDTH_CONDENSED },
+{ NULL, WIDTH_DONTKNOW },
+};
+
+struct ImplFontAttrWeightSearchData
+{
+ const char* mpStr;
+ FontWeight meWeight;
+};
+
+static ImplFontAttrWeightSearchData const aImplWeightAttrSearchList[] =
+{
+{ "extrablack", WEIGHT_BLACK },
+{ "ultrablack", WEIGHT_BLACK },
+{ "black", WEIGHT_BLACK },
+{ "heavy", WEIGHT_BLACK },
+{ "ultrabold", WEIGHT_ULTRABOLD },
+{ "semibold", WEIGHT_SEMIBOLD },
+{ "bold", WEIGHT_BOLD },
+{ "ultralight", WEIGHT_ULTRALIGHT },
+{ "semilight", WEIGHT_SEMILIGHT },
+{ "light", WEIGHT_LIGHT },
+{ "demi", WEIGHT_SEMIBOLD },
+{ "medium", WEIGHT_MEDIUM },
+{ NULL, WEIGHT_DONTKNOW },
+};
+
+struct ImplFontAttrTypeSearchData
+{
+ const char* mpStr;
+ ULONG mnType;
+};
+
+static ImplFontAttrTypeSearchData const aImplTypeAttrSearchList[] =
+{
+{ "titling", FONT_ATTR_TITLING },
+{ "outline", FONT_ATTR_OUTLINE },
+{ "shadow", FONT_ATTR_SHADOW },
+{ NULL, 0 },
+};
+
+// =======================================================================
+
+struct ImplFontNameAttr
+{
+ const char* mpName;
+ FontFamily meFamily;
+ FontWeight meWeight;
+ FontWidth meWidth;
+ ULONG mnType;
+};
+
+static const ImplFontNameAttr aImplFullList[] =
+{
+{ "Bookman", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_NORMAL | FONT_ATTR_STANDARD | FONT_ATTR_SERIF },
+{ NULL, FAMILY_DONTKNOW,WEIGHT_DONTKNOW,WIDTH_DONTKNOW, 0 }
+};
+
+static const ImplFontNameAttr aImplMatchList[] =
+{
+{ "bookman", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_NORMAL | FONT_ATTR_STANDARD | FONT_ATTR_SERIF },
+{ "comicsansms", FAMILY_SCRIPT, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_NONSERIF | FONT_ATTR_SCRIPT | FONT_ATTR_CHARSCRIPT | FONT_ATTR_FAVOR3 },
+{ "kristenitc", FAMILY_SCRIPT, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_NONSERIF | FONT_ATTR_SCRIPT | FONT_ATTR_CHARSCRIPT | FONT_ATTR_FAVOR3 },
+{ "maiandragd", FAMILY_SCRIPT, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_NONSERIF | FONT_ATTR_SCRIPT | FONT_ATTR_CHARSCRIPT | FONT_ATTR_FAVOR3 },
+{ "arioso", FAMILY_SCRIPT, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_NONSERIF | FONT_ATTR_SCRIPT | FONT_ATTR_ITALIC | FONT_ATTR_DECORATION | FONT_ATTR_OLDSTYLE | FONT_ATTR_FAVOR3 },
+{ "tempussansitc", FAMILY_SCRIPT, WEIGHT_LIGHT, WIDTH_NORMAL, FONT_ATTR_NONSERIF | FONT_ATTR_SCRIPT | FONT_ATTR_CHARSCRIPT },
+{ "papyrus", FAMILY_SCRIPT, WEIGHT_LIGHT, WIDTH_NORMAL, FONT_ATTR_NONSERIF | FONT_ATTR_SCRIPT | FONT_ATTR_CHARSCRIPT },
+{ "lucidashadowtitling", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_SERIF | FONT_ATTR_TITLING | FONT_ATTR_OUTLINE | FONT_ATTR_SHADOW },
+{ "lucidaopenboldtitling",FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_SERIF | FONT_ATTR_TITLING | FONT_ATTR_OUTLINE },
+{ "lucidaopentitling", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_SERIF | FONT_ATTR_TITLING | FONT_ATTR_OUTLINE },
+{ "lucidaopen", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_SERIF | FONT_ATTR_OUTLINE },
+{ "lucidashadow", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_SERIF | FONT_ATTR_OUTLINE | FONT_ATTR_SHADOW },
+{ "chevara", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_EXPANDED, FONT_ATTR_SERIF | FONT_ATTR_TITLING | FONT_ATTR_OUTLINE },
+{ "colonnamt", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_SERIF | FONT_ATTR_SPECIAL | FONT_ATTR_OUTLINE },
+{ "imprintmtshadow", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_SERIF | FONT_ATTR_OUTLINE | FONT_ATTR_SHADOW },
+{ "castellar", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_SERIF | FONT_ATTR_TITLING | FONT_ATTR_OUTLINE },
+{ "algerian", FAMILY_ROMAN, WEIGHT_NORMAL, WIDTH_NORMAL, FONT_ATTR_SERIF | FONT_ATTR_SPECIAL | FONT_ATTR_TITLING | FONT_ATTR_OUTLINE | FONT_ATTR_SHADOW | FONT_ATTR_OLDSTYLE },
+{ NULL, FAMILY_DONTKNOW,WEIGHT_DONTKNOW,WIDTH_DONTKNOW, 0 }
+};
+
+#endif
+
+static const char* aImplSwissMatchList[] =
+{
+ "arial",
+ "avantgarde",
+ "cgomega",
+ "centurygothic",
+ "charcoal",
+ "chicago",
+ "frutiger",
+ "geneva",
+ "haettenschweiler",
+ "helmet",
+ "helv",
+ "lucida",
+ "impact",
+ "tahoma",
+ "univers",
+ "vagrounded",
+ "verdana",
+ NULL
+};
+
+static const char* aImplSwissSearchList[] =
+{
+ "sansserif",
+ "swiss",
+ NULL
+};
+
+static const char* aImplRomanMatchList[] =
+{
+ "algerian",
+ "antiqua",
+ "caliso",
+ "clarendon",
+ "colonna",
+ "garamond",
+ "newyork",
+ "palatino",
+ "timmons",
+ NULL
+};
+
+static const char* aImplRomanSearchList[] =
+{
+ "book",
+ "times",
+ "roman",
+ "bright",
+ NULL
+};
+
+static const char* aImplFixedMatchList[] =
+{
+ "lineprinter",
+ "monaco",
+ "typewriter",
+ NULL
+};
+
+static const char* aImplFixedSearchList[] =
+{
+ "console",
+ "courier",
+ "fixed",
+ "letter",
+ "monospace",
+ "terminal",
+ NULL
+};
+
+static const char* aImplScriptMatchList[] =
+{
+ "arioso",
+ "coronet",
+ "cursive",
+ "marigold",
+ "zapfchancery",
+ NULL
+};
+
+static const char* aImplScriptSearchList[] =
+{
+ "script",
+ "signet",
+ "handwriting",
+ "calligraphy",
+ NULL
+};
+
+static const char* aImplSymbolMatchList[] =
+{
+ "marlett",
+ "monotypesorts",
+ "msoutlook",
+ NULL
+};
+
+static const char* aImplSymbolSearchList[] =
+{
+ "symbol",
+ "bats",
+ "dings",
+ "math",
+ NULL
+};
+
+static const char* aImplTypeList[] =
+{
+ "black",
+ "bold",
+ "condensed",
+ "expanded",
+ "narrow",
+ "outline",
+ NULL
+};
+
+// =======================================================================
+
+static const char* aImplSearchScriptList[] =
+{
+ "ce",
+ "we",
+ "cyr",
+ "tur",
+ "wt",
+ "greek",
+ "wl",
+ NULL
+};
+
+// -----------------------------------------------------------------------
+
+struct ImplScriptSearchList
+{
+ const char* mpScript;
+ rtl_Script meScript;
+};
+
+static void ImplCutScriptAndSpaces( XubString& rName )
+{
+ rName.EraseLeadingAndTrailingChars( ' ' );
+
+ USHORT nLen = rName.Len();
+ if ( nLen < 3 )
+ return;
+
+ // Scriptname must be the last part of the fontname and
+ // looks like "fontname (scriptname)". So there can only be a
+ // script name at the and of the fontname, when the last char is
+ // ')'.
+ if ( rName.GetChar( nLen-1 ) == ')' )
+ {
+ int nOpen = 1;
+ nLen -= 2;
+ while ( nLen )
+ {
+ if ( rName.GetChar( nLen ) == '(' )
+ {
+ nOpen--;
+ if ( !nOpen && nLen && (rName.GetChar( nLen-1 ) == ' ') )
+ {
+ XubString aScript = rName.Copy( nLen+1, rName.Len()-1-nLen-1 );
+ rName.Erase( nLen-1 );
+ return;
+ }
+ }
+ if ( rName.GetChar( nLen ) == ')' )
+ nOpen++;
+ nLen--;
+ }
+ }
+
+ // For compatibility with older version we must search for a
+ // script name at the end of a fontname without brakets
+ USHORT nSpacePos = rName.SearchBackward( ' ' );
+ if ( nSpacePos && (nSpacePos != STRING_NOTFOUND) )
+ {
+ XubString aScript = rName.Copy( nSpacePos+1 );
+ const char** pScript = aImplSearchScriptList;
+ while ( *pScript )
+ {
+ if ( aScript.EqualsAscii( *pScript ) )
+ {
+ rName.Erase( nSpacePos );
+ break;
+ }
+ pScript++;
+ }
+ }
+}
+
+// =======================================================================
+
+#if 0
+
+static const ImplFontNameAttr* ImplFindFontAttr( const XubString& rFontName )
+{
+ const ImplFontNameAttr* pList;
+
+ pList = aImplFullList;
+ while ( pList->mpName )
+ {
+ if ( rFontName.EqualsAscii( pList->mpName ) )
+ return pList;
+ pList++;
+ }
+
+ pList = aImplMatchList;
+ while ( pList->mpName )
+ {
+ if ( ImplStrFullMatch( rFontName, pList->mpName ) )
+ return pList;
+ pList++;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetFontAttr( const XubString& rFontName,
+ FontFamily& rFamily, CharSet& rCharSet,
+ FontPitch& rPitch )
+{
+ if ( (rFamily == FAMILY_DONTKNOW) || (rPitch == PITCH_DONTKNOW) ||
+ (rCharSet == CHARSET_DONTKNOW) )
+ {
+ }
+}
+
+#endif
+
+// =======================================================================
+
+BOOL ImplTestFontName( const XubString& rName,
+ const sal_Char** pMatchList,
+ const sal_Char** pSearchList )
+{
+ const char** pAlias;
+
+ pAlias = pMatchList;
+ while ( *pAlias )
+ {
+ if ( ImplStrFullMatch( rName, *pAlias ) )
+ return TRUE;
+ pAlias++;
+ }
+
+ pAlias = pSearchList;
+ while ( *pAlias )
+ {
+ if ( rName.SearchAscii( *pAlias ) != STRING_NOTFOUND )
+ return TRUE;
+ pAlias++;
+ }
+
+ return FALSE;
+}
+
+// =======================================================================
+
+static void ImplFontAttrFromName( const XubString& rFontName,
+ FontFamily& rFamily, CharSet& rCharSet,
+ FontPitch& rPitch )
+{
+ if ( rFamily == FAMILY_DONTKNOW )
+ {
+ if ( ImplTestFontName( rFontName, aImplRomanMatchList, aImplRomanSearchList ) )
+ rFamily = FAMILY_ROMAN;
+ else if ( ImplTestFontName( rFontName, aImplSwissMatchList, aImplSwissSearchList ) )
+ rFamily = FAMILY_SWISS;
+ else if ( ImplTestFontName( rFontName, aImplScriptMatchList, aImplScriptSearchList ) )
+ rFamily = FAMILY_SCRIPT;
+ }
+
+ if ( rPitch == PITCH_DONTKNOW )
+ {
+ if ( ImplTestFontName( rFontName, aImplFixedMatchList, aImplFixedSearchList ) )
+ rPitch = PITCH_FIXED;
+ }
+
+ if ( rCharSet == RTL_TEXTENCODING_DONTKNOW )
+ {
+ if ( ImplTestFontName( rFontName, aImplSymbolMatchList, aImplSymbolSearchList ) )
+ rCharSet = RTL_TEXTENCODING_SYMBOL;
+ }
+}
+
+// =======================================================================
+
+static const char* aImplStdSwissList[] =
+{
+ "helvetica",
+ "arial",
+ "lucida sans",
+ "lucidasans",
+ "lucida",
+ "geneva",
+ "helmet",
+ NULL
+};
+
+static const char* aImplStdRomanList[] =
+{
+ "times",
+ "times new roman",
+ "timesnewroman",
+ "roman",
+ "lucida serif",
+ "lucidaserif",
+ "lucida bright",
+ "lucidabright",
+ "bookman",
+ "garamond",
+ "timmons",
+ NULL
+};
+
+static const char* aImplStdFixedList[] =
+{
+ "courier",
+ "courier new",
+ "lucida typewriter",
+ "lucidatypewriter",
+ "lucida sans typewriter",
+ "lucidasanstypewriter",
+ NULL
+};
+
+static const char* aImplStdScriptList[] =
+{
+ "zapf chancery",
+ "zapfchancery",
+ "lucida calligraphy",
+ "lucidacalligraphy",
+ "lucida handwriting",
+ "lucidahandwriting",
+ "arioso",
+ "script",
+ "marigold",
+ NULL
+};
+
+static const char* aImplStdSymbolList[] =
+{
+ "starbats",
+ "symbol",
+ "zapf dingbats",
+ "zapfdingbats",
+ "wingdings",
+ "lucida dingbats",
+ "lucidadingbats",
+ "lucida sans dingbats",
+ "lucidasansdingbats",
+ NULL
+};
+
+// =======================================================================
+
+void ImplFreeOutDevFontData()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplFontSubstEntry* pEntry = pSVData->maGDIData.mpFirstFontSubst;
+ while ( pEntry )
+ {
+ ImplFontSubstEntry* pNext = pEntry->mpNext;
+ delete pEntry;
+ pEntry = pNext;
+ }
+}
+
+// =======================================================================
+
+static ImplFontData* ImplFindScript( ImplDevFontListData* pData,
+ rtl_Script eScript )
+{
+ // Testen, ob ein Font mit einem entsprechendem
+ // Script vorhanden ist
+ ImplFontData* pCurFontData = pData->mpFirst;
+ while ( pCurFontData )
+ {
+ // Detect Unicode Font !!!
+ if ( pData->maMatchName.EqualsAscii( "arial unicode ms" ) )
+ return pCurFontData;
+ if ( eScript == pCurFontData->meScript )
+ return pCurFontData;
+ pCurFontData = pCurFontData->mpNext;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+/* !!! UNICODE - Duerfte nicht mehr gebraucht werden !!!
+static rtl_TextEncoding ImplGetFakeEncoding( rtl_TextEncoding eEncoding )
+{
+ rtl_TextEncoding eSystemEncoding = GetSystemCharSet();
+ // MS_1252 und 8859_1 sind kompatible
+ if ( ((eEncoding == RTL_TEXTENCODING_MS_1252) ||
+ (eEncoding == RTL_TEXTENCODING_ISO_8859_1)) &&
+ ((eSystemEncoding == RTL_TEXTENCODING_MS_1252) ||
+ (eSystemEncoding == RTL_TEXTENCODING_ISO_8859_1)) )
+ return eEncoding;
+ else
+ {
+ // Wir testen, ob beide Zeichensaetze dem gleichem Script
+ // entsprechen, um so der Applikation das gleiche Encoding
+ // vorzugaukeln. Dies ist beispielsweise bei Russisch wichtig
+ // da hier Fonts mit unterschiedlichem Encoding auftauchen
+ // koennen.
+ rtl_Script eSrcScript;
+ rtl_Script eSystemScript;
+ rtl_TextEncodingInfo aTEncInfo;
+ aTEncInfo.StructSize = sizeof( aTEncInfo );
+ aTEncInfo.Script = SCRIPT_DONTKNOW;
+ if ( !rtl_getTextEncodingInfo( eEncoding, &aTEncInfo ) )
+ return eEncoding;
+ else
+ eSrcScript = aTEncInfo.Script;
+ aTEncInfo.Script = SCRIPT_DONTKNOW;
+ if ( !rtl_getTextEncodingInfo( eSystemEncoding, &aTEncInfo ) )
+ return eEncoding;
+ else
+ eSystemScript = aTEncInfo.Script;
+ if ( eSrcScript == eSystemScript )
+ eEncoding = eSystemEncoding;
+ }
+
+ return eEncoding;
+}
+*/
+
+// =======================================================================
+
+void OutputDevice::BeginFontSubstitution()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->maGDIData.mbFontSubChanged = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::EndFontSubstitution()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maGDIData.mbFontSubChanged )
+ {
+ ImplUpdateAllFontData( FALSE );
+
+ Application* pApp = GetpApp();
+ DataChangedEvent aDCEvt( DATACHANGED_FONTSUBSTITUTION );
+ pApp->DataChanged( aDCEvt );
+ pApp->NotifyAllWindows( aDCEvt );
+ pSVData->maGDIData.mbFontSubChanged = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::AddFontSubstitute( const XubString& rFontName,
+ const XubString& rReplaceFontName,
+ USHORT nFlags )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplFontSubstEntry* pEntry = new ImplFontSubstEntry;
+
+ pEntry->maName = rFontName;
+ pEntry->maReplaceName = rReplaceFontName;
+ pEntry->maMatchName = rFontName;
+ pEntry->maMatchReplaceName = rReplaceFontName;
+ pEntry->mnFlags = nFlags;
+ pEntry->mpNext = pSVData->maGDIData.mpFirstFontSubst;
+ pEntry->maMatchName.ToLowerAscii();
+ pEntry->maMatchReplaceName.ToLowerAscii();
+ ImplCutScriptAndSpaces( pEntry->maMatchName );
+ ImplCutScriptAndSpaces( pEntry->maMatchReplaceName );
+ pSVData->maGDIData.mpFirstFontSubst = pEntry;
+ pSVData->maGDIData.mbFontSubChanged = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::RemoveFontSubstitute( USHORT n )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplFontSubstEntry* pEntry = pSVData->maGDIData.mpFirstFontSubst;
+ ImplFontSubstEntry* pPrev = NULL;
+ USHORT nCount = 0;
+ while ( pEntry )
+ {
+ if ( nCount == n )
+ {
+ pSVData->maGDIData.mbFontSubChanged = TRUE;
+ if ( pPrev )
+ pPrev->mpNext = pEntry->mpNext;
+ else
+ pSVData->maGDIData.mpFirstFontSubst = pEntry->mpNext;
+ delete pEntry;
+ break;
+ }
+
+ nCount++;
+ pPrev = pEntry;
+ pEntry = pEntry->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT OutputDevice::GetFontSubstituteCount()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplFontSubstEntry* pEntry = pSVData->maGDIData.mpFirstFontSubst;
+ USHORT nCount = 0;
+ while ( pEntry )
+ {
+ nCount++;
+ pEntry = pEntry->mpNext;
+ }
+
+ return nCount;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::GetFontSubstitute( USHORT n,
+ XubString& rFontName,
+ XubString& rReplaceFontName,
+ USHORT& rFlags )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplFontSubstEntry* pEntry = pSVData->maGDIData.mpFirstFontSubst;
+ USHORT nCount = 0;
+ while ( pEntry )
+ {
+ if ( nCount == n )
+ {
+ rFontName = pEntry->maName;
+ rReplaceFontName = pEntry->maReplaceName;
+ rFlags = pEntry->mnFlags;
+ break;
+ }
+
+ nCount++;
+ pEntry = pEntry->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplFontSubstitute( XubString& rFontName,
+ USHORT nFlags1, USHORT nFlags2 )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplFontSubstEntry* pEntry = pSVData->maGDIData.mpFirstFontSubst;
+ while ( pEntry )
+ {
+ if ( ((pEntry->mnFlags & nFlags1) == nFlags2) &&
+ (pEntry->maMatchName == rFontName) )
+ {
+ rFontName = pEntry->maMatchReplaceName;
+ return TRUE;
+ }
+
+ pEntry = pEntry->mpNext;
+ }
+
+ return FALSE;
+}
+
+// =======================================================================
+
+ImplDevFontList::ImplDevFontList() :
+ List( CONTAINER_MAXBLOCKSIZE, 96, 32 )
+{
+#if 0
+ mbIsInitMatchData = FALSE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+ImplDevFontList::~ImplDevFontList()
+{
+ // Alle Eintraege loeschen
+ ImplDevFontListData* pEntry = First();
+ while ( pEntry )
+ {
+ // Liste der Font loeschen
+ ImplFontData* pFontData = pEntry->mpFirst;
+ do
+ {
+ ImplFontData* pTempFontData = pFontData;
+ pFontData = pFontData->mpNext;
+ delete pTempFontData;
+ }
+ while ( pFontData );
+ // Entry loeschen
+ delete pEntry;
+
+ pEntry = Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static StringCompare ImplCompareFontDataWithoutSize( const ImplFontData* pEntry1,
+ const ImplFontData* pEntry2 )
+{
+ // Vergleichen nach CharSet, Groesse, Breite, Weight, Italic, StyleName
+ if ( pEntry1->meCharSet < pEntry2->meCharSet )
+ return COMPARE_LESS;
+ else if ( pEntry1->meCharSet > pEntry2->meCharSet )
+ return COMPARE_GREATER;
+
+ if ( pEntry1->meWidthType < pEntry2->meWidthType )
+ return COMPARE_LESS;
+ else if ( pEntry1->meWidthType > pEntry2->meWidthType )
+ return COMPARE_GREATER;
+
+ if ( pEntry1->meWeight < pEntry2->meWeight )
+ return COMPARE_LESS;
+ else if ( pEntry1->meWeight > pEntry2->meWeight )
+ return COMPARE_GREATER;
+
+ if ( pEntry1->meItalic < pEntry2->meItalic )
+ return COMPARE_LESS;
+ else if ( pEntry1->meItalic > pEntry2->meItalic )
+ return COMPARE_GREATER;
+
+ return pEntry1->maStyleName.CompareTo( pEntry2->maStyleName );
+}
+
+// -----------------------------------------------------------------------
+
+static StringCompare ImplCompareFontData( const ImplFontData* pEntry1,
+ const ImplFontData* pEntry2 )
+{
+ StringCompare eComp = ImplCompareFontDataWithoutSize( pEntry1, pEntry2 );
+ if ( eComp != COMPARE_EQUAL )
+ return eComp;
+
+ if ( pEntry1->mnHeight < pEntry2->mnHeight )
+ return COMPARE_LESS;
+ else if ( pEntry1->mnHeight > pEntry2->mnHeight )
+ return COMPARE_GREATER;
+
+ if ( pEntry1->mnWidth < pEntry2->mnWidth )
+ return COMPARE_LESS;
+ else if ( pEntry1->mnWidth > pEntry2->mnWidth )
+ return COMPARE_GREATER;
+
+ return COMPARE_EQUAL;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDevFontList::Add( ImplFontData* pNewData )
+{
+ XubString aSearchName = pNewData->maName;
+ aSearchName.ToLowerAscii();
+
+ // Query Script for FontTest
+ rtl_TextEncodingInfo aTEncInfo;
+ aTEncInfo.StructSize = sizeof( aTEncInfo );
+ aTEncInfo.Script = SCRIPT_DONTKNOW;
+ rtl_getTextEncodingInfo( pNewData->meCharSet, &aTEncInfo );
+ pNewData->meScript = aTEncInfo.Script;
+
+ // Add Font
+ ULONG nIndex;
+ ImplDevFontListData* pFoundData = ImplFind( aSearchName, &nIndex );
+ BOOL bDelete = FALSE;
+
+ if ( !pFoundData )
+ {
+ pFoundData = new ImplDevFontListData;
+ pFoundData->maName = pNewData->maName;
+ pFoundData->maMatchName = aSearchName;
+ pFoundData->maMatchName2 = aSearchName;
+ pFoundData->mpFirst = pNewData;
+#if 0
+ pFoundData->mbScalable = FALSE;
+ ImplStrEraseAllSymbols( pFoundData->maMatchName2 );
+/*
+ pFoundData->meMatchFamily = pNewData->meFamily;
+ pFoundData->meMatchPitch = pNewData->mePitch;
+ CharSet eCharSet = pNewData->meCharSet;
+ ImplFontAttrFromName( pFoundData->maMatchName2, pFoundData->meMatchFamily,
+ eCharSet, pFoundData->meMatchPitch );
+ pFoundData->mbSymbol = eCharSet == RTL_TEXTENCODING_SYMBOL;
+*/
+#else
+ pFoundData->meMatchFamily = pNewData->meFamily;
+ pFoundData->meMatchPitch = pNewData->mePitch;
+ pFoundData->mnMatch = 0;
+ CharSet eCharSet = pNewData->meCharSet;
+ ImplStrEraseAllSymbols( pFoundData->maMatchName2 );
+ ImplFontAttrFromName( pFoundData->maMatchName2, pFoundData->meMatchFamily,
+ eCharSet, pFoundData->meMatchPitch );
+ pFoundData->mbSymbol = eCharSet == RTL_TEXTENCODING_SYMBOL;
+#endif
+
+ pNewData->mpNext = NULL;
+ Insert( pFoundData, nIndex );
+ }
+ else
+ {
+ // Name ersetzen (spart Speicherplatz)
+ pNewData->maName = pFoundData->maName;
+
+ BOOL bInsert = TRUE;
+ ImplFontData* pPrev = NULL;
+ ImplFontData* pTemp = pFoundData->mpFirst;
+ do
+ {
+ StringCompare eComp = ImplCompareFontData( pNewData, pTemp );
+ if ( eComp != COMPARE_GREATER )
+ {
+ // Wenn Font gleich ist, nehmen wir einen Devicefont,
+ // oder ignorieren den Font
+ if ( eComp == COMPARE_EQUAL )
+ {
+ // Wir nehmen den Font mit der besseren Quality,
+ // ansonsten ziehen wir den Device-Font vor
+ if ( (pNewData->mnQuality > pTemp->mnQuality) ||
+ ((pNewData->mnQuality == pTemp->mnQuality) &&
+ (pNewData->mbDevice && !pTemp->mbDevice)) )
+ {
+ pNewData->mpNext = pTemp->mpNext;
+ if ( pPrev )
+ pPrev->mpNext = pNewData;
+ else
+ pFoundData->mpFirst = pNewData;
+ delete pTemp;
+ }
+ else
+ {
+ bDelete = TRUE;
+ delete pNewData;
+ }
+
+ bInsert = FALSE;
+ }
+ break;
+ }
+
+ pPrev = pTemp;
+ pTemp = pTemp->mpNext;
+ }
+ while ( pTemp );
+
+ if ( bInsert )
+ {
+ pNewData->mpNext = pTemp;
+ if ( pPrev )
+ pPrev->mpNext = pNewData;
+ else
+ pFoundData->mpFirst = pNewData;
+ }
+ }
+
+ // Match zusammenzaehlen
+ if ( !bDelete )
+ {
+#if 0
+ if ( (pNewData->meType == TYPE_SCALABLE) && (pNewData->mnHeight == 0) )
+ pFoundData->mbScalable = TRUE;
+#else
+ if ( (pNewData->meType == TYPE_SCALABLE) && (pNewData->mnHeight == 0) )
+ {
+ if ( pNewData->meWidthType == WIDTH_NORMAL )
+ pFoundData->mnMatch += 30;
+ else
+ pFoundData->mnMatch += 3;
+ if ( pNewData->meItalic == ITALIC_NONE )
+ pFoundData->mnMatch += 20;
+ else
+ pFoundData->mnMatch += 2;
+ if ( (pNewData->meWeight == WEIGHT_NORMAL) || (pNewData->meWeight == WEIGHT_MEDIUM) )
+ pFoundData->mnMatch += 10;
+ else
+ pFoundData->mnMatch += 1;
+ }
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ImplDevFontListData* ImplDevFontList::ImplFind( const XubString& rFontName, ULONG* pIndex ) const
+{
+ ULONG nCount = Count();
+ if ( !nCount )
+ {
+ if ( pIndex )
+ *pIndex = LIST_APPEND;
+ return NULL;
+ }
+
+ // Fonts in der Liste suchen
+ ImplDevFontListData* pCompareData;
+ ImplDevFontListData* pFoundData = NULL;
+ ULONG nLow = 0;
+ ULONG nHigh = nCount-1;
+ ULONG nMid;
+ StringCompare eCompare;
+
+ do
+ {
+ nMid = (nLow + nHigh) / 2;
+ pCompareData = Get( nMid );
+ eCompare = rFontName.CompareTo( pCompareData->maMatchName );
+ if ( eCompare == COMPARE_LESS )
+ {
+ if ( !nMid )
+ break;
+ nHigh = nMid-1;
+ }
+ else
+ {
+ if ( eCompare == COMPARE_GREATER )
+ nLow = nMid + 1;
+ else
+ {
+ pFoundData = pCompareData;
+ break;
+ }
+ }
+ }
+ while ( nLow <= nHigh );
+
+ if ( pIndex )
+ {
+ eCompare = rFontName.CompareTo( pCompareData->maMatchName );
+ if ( eCompare == COMPARE_GREATER )
+ *pIndex = (nMid+1);
+ else
+ *pIndex = nMid;
+ }
+
+ return pFoundData;
+}
+
+// -----------------------------------------------------------------------
+
+ImplDevFontListData* ImplDevFontList::FindFont( const XubString& rFontName ) const
+{
+ XubString aName = rFontName;
+ aName.ToLowerAscii();
+ ImplCutScriptAndSpaces( aName );
+ return ImplFind( aName );
+}
+
+// -----------------------------------------------------------------------
+
+ImplDevFontListData* ImplDevFontList::FindStdFont( const sal_Char** pStdFontNames,
+ rtl_Script eScript ) const
+{
+ // We want a scalable font with a system script
+ ImplDevFontListData* pRasterFoundData = NULL;
+ ImplDevFontListData* pWrongScriptRasterData = NULL;
+ ImplDevFontListData* pWrongScriptData = NULL;
+ while ( *pStdFontNames )
+ {
+ XubString aStdName( *pStdFontNames, RTL_TEXTENCODING_ASCII_US );
+ ImplDevFontListData* pFoundData = ImplFind( aStdName );
+ if ( pFoundData )
+ {
+ if ( (eScript == SCRIPT_SYMBOL) ||
+ ImplFindScript( pFoundData, eScript ) )
+ {
+ if ( pFoundData->mpFirst->meType != TYPE_RASTER )
+ return pFoundData;
+ else if ( !pRasterFoundData )
+ pRasterFoundData = pFoundData;
+ }
+ else
+ {
+ if ( pFoundData->mpFirst->meType != TYPE_RASTER )
+ {
+ if ( !pWrongScriptData )
+ pWrongScriptData = pFoundData;
+ }
+ else
+ {
+ if ( !pWrongScriptRasterData )
+ pWrongScriptRasterData = pFoundData;
+ }
+ }
+ }
+ pStdFontNames++;
+ }
+
+ // Wenn keine passende Schrift, dann die Reihenfolge:
+ // - passender Zeichensatz
+ // - Skalierbar
+ // - eine passende Schrift die nicht skalierbar und den
+ // falschen Zeichensatz hat
+ // - keine
+ if ( pRasterFoundData )
+ return pRasterFoundData;
+ else if ( pWrongScriptData )
+ return pWrongScriptData;
+ else
+ return pWrongScriptRasterData;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDevFontList::Clear()
+{
+ // Alle Eintraege loeschen
+ ImplDevFontListData* pEntry = First();
+ while ( pEntry )
+ {
+ // Liste der Font loeschen
+ ImplFontData* pFontData = pEntry->mpFirst;
+ do
+ {
+ ImplFontData* pTempFontData = pFontData;
+ pFontData = pFontData->mpNext;
+ delete pTempFontData;
+ }
+ while ( pFontData );
+ // Entry loeschen
+ delete pEntry;
+
+ pEntry = Next();
+ }
+ List::Clear();
+
+ // Standard-Fonts loeschen
+ for ( USHORT i = 0; i < IMPL_STDFONT_COUNT; i++ )
+ mpStdFontAry[i] = NULL;
+#if 0
+ mbIsInitMatchData = FALSE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+#if 0
+void ImplDevFontList::InitMatchData()
+{
+ if ( mbIsInitMatchData )
+ return;
+ mbIsInitMatchData = TRUE;
+/*
+ // Fuer alle Eintraege die Matchdaten ermitteln
+ ImplDevFontListData* pEntry = First();
+ while ( pEntry )
+ {
+ ImplFontData* pFontData = pEntry->mpFirst;
+
+ pEntry = Next();
+ }
+*/
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+void ImplDevFontList::InitStdFonts()
+{
+ rtl_Script eSystemScript;
+ rtl_TextEncodingInfo aTextEncInfo;
+ aTextEncInfo.StructSize = sizeof( aTextEncInfo );
+ aTextEncInfo.Script = SCRIPT_DONTKNOW;
+ rtl_getTextEncodingInfo( gsl_getSystemTextEncoding(), &aTextEncInfo );
+ eSystemScript = aTextEncInfo.Script;
+
+ mpStdFontAry[IMPL_STDFONT_SWISS] = FindStdFont( aImplStdSwissList, eSystemScript );
+ mpStdFontAry[IMPL_STDFONT_ROMAN] = FindStdFont( aImplStdRomanList, eSystemScript );
+ mpStdFontAry[IMPL_STDFONT_FIXED] = FindStdFont( aImplStdFixedList, eSystemScript );
+ mpStdFontAry[IMPL_STDFONT_SCRIPT] = FindStdFont( aImplStdScriptList, eSystemScript );
+ mpStdFontAry[IMPL_STDFONT_SYMBOL] = FindStdFont( aImplStdSymbolList, SCRIPT_SYMBOL );
+}
+
+// =======================================================================
+
+void ImplGetDevSizeList::Add( long nNewHeight )
+{
+ ULONG n = Count();
+ if ( !n || (nNewHeight > Get( n-1 )) )
+ Insert( (void*)nNewHeight, LIST_APPEND );
+ else
+ {
+ for ( ULONG i=0 ; i < n; i++ )
+ {
+ long nHeight = Get( i );
+
+ if ( nNewHeight <= nHeight )
+ {
+ if ( nNewHeight != nHeight )
+ Insert( (void*)nNewHeight, i );
+ break;
+ }
+ }
+ }
+}
+
+// =======================================================================
+
+ImplFontEntry::~ImplFontEntry()
+{
+ if ( mpWidthAry )
+ delete mpWidthAry;
+
+ if ( mpKernPairs )
+ delete mpKernPairs;
+
+ if ( mpKernInfo )
+ delete mpKernInfo;
+}
+
+// =======================================================================
+
+ImplFontCache::ImplFontCache( BOOL bPrinter )
+{
+ mpFirstEntry = NULL;
+ mnRef0Count = 0;
+ mbPrinter = bPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontCache::~ImplFontCache()
+{
+ // Alle Eintraege loeschen
+ ImplFontEntry* pTemp;
+ ImplFontEntry* pEntry = mpFirstEntry;
+ while ( pEntry )
+ {
+ pTemp = pEntry->mpNext;
+ delete pEntry;
+ pEntry = pTemp;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontEntry* ImplFontCache::Get( ImplDevFontList* pFontList,
+ const Font& rFont, const Size& rSize )
+{
+ const XubString& rName = rFont.GetName();
+ const XubString& rStyleName = rFont.GetStyleName();
+ long nWidth = rSize.Width();
+ long nHeight = rSize.Height();
+ FontFamily eFamily = rFont.GetFamily();
+ CharSet eCharSet = rFont.GetCharSet();
+ FontWeight eWeight = rFont.GetWeight();
+ FontItalic eItalic = rFont.GetItalic();
+ FontPitch ePitch = rFont.GetPitch();
+ short nOrientation = (short)(rFont.GetOrientation() % 3600);
+ BOOL bShadow = rFont.IsShadow();
+ BOOL bOutline = rFont.IsOutline();
+
+ // Groesse anpassen
+ if ( nHeight < 0 )
+ nHeight = -nHeight;
+ if ( nWidth < 0 )
+ nWidth = -nWidth;
+
+ // Eintrag suchen
+ ImplFontEntry* pPrevEntry = NULL;
+ ImplFontEntry* pEntry = mpFirstEntry;
+ while ( pEntry )
+ {
+ ImplFontSelectData* pFontSelData = &(pEntry->maFontSelData);
+ if ( (nHeight == pFontSelData->mnHeight) &&
+ (eWeight == pFontSelData->meWeight) &&
+ (eItalic == pFontSelData->meItalic) &&
+ (rName == pFontSelData->maName) &&
+ (rStyleName == pFontSelData->maStyleName) &&
+ (eCharSet == pFontSelData->meCharSet) &&
+ (eFamily == pFontSelData->meFamily) &&
+ (ePitch == pFontSelData->mePitch) &&
+ (nWidth == pFontSelData->mnWidth) &&
+ (nOrientation == pFontSelData->mnOrientation) )
+ {
+ if ( !pEntry->mnRefCount )
+ mnRef0Count--;
+
+ pEntry->mnRefCount++;
+
+ // Entry nach vorne bringen
+ if ( pPrevEntry )
+ {
+ pPrevEntry->mpNext = pEntry->mpNext;
+ pEntry->mpNext = mpFirstEntry;
+ mpFirstEntry = pEntry;
+ }
+
+ return pEntry;
+ }
+
+ pPrevEntry = pEntry;
+ pEntry = pEntry->mpNext;
+ }
+
+ // Wir suchen zuerst ueber den Namen den passenden Font
+ XubString aLowerFontName = rName;
+ XubString aFirstName;
+ XubString aTempName;
+ XubString aTempName2;
+ ImplDevFontListData* pFoundData;
+ ImplDevFontListData* pTempFoundData;
+ xub_StrLen nFirstNameIndex = 0;
+ xub_StrLen nIndex = 0;
+ USHORT nSubstFlags1 = FONT_SUBSTITUTE_ALWAYS;
+ USHORT nSubstFlags2 = FONT_SUBSTITUTE_ALWAYS;
+ rtl_Script eScript = SCRIPT_DONTKNOW;
+ rtl_Script eCharSetScript;
+ rtl_TextEncodingInfo aTextEncInfo;
+ aTextEncInfo.StructSize = sizeof( aTextEncInfo );
+ aTextEncInfo.Script = SCRIPT_DONTKNOW;
+ rtl_getTextEncodingInfo( eCharSet, &aTextEncInfo );
+ eCharSetScript = aTextEncInfo.Script;
+ if ( mbPrinter )
+ nSubstFlags1 |= FONT_SUBSTITUTE_SCREENONLY;
+ aLowerFontName.ToLowerAscii();
+ pTempFoundData = NULL;
+ do
+ {
+ aTempName = aLowerFontName.GetToken( 0, ';', nIndex );
+ ImplCutScriptAndSpaces( aTempName );
+ if ( !aFirstName.Len() )
+ {
+ aFirstName = aTempName;
+ nFirstNameIndex = nIndex;
+ }
+ ImplFontSubstitute( aTempName, nSubstFlags1, nSubstFlags2 );
+ pFoundData = pFontList->ImplFind( aTempName );
+ if ( pFoundData )
+ {
+ if ( eCharSetScript != SCRIPT_DONTKNOW )
+ {
+ if ( !pTempFoundData )
+ {
+ aTempName2 = aTempName;
+ pTempFoundData = pFoundData;
+ }
+
+ // Testen, ob ein Font mit einem entsprechendem
+ // Script vorhanden ist
+ if ( ImplFindScript( pFoundData, eCharSetScript ) )
+ {
+ aLowerFontName = aTempName;
+ break;
+ }
+ else
+ pFoundData = NULL;
+ }
+ else
+ {
+ aLowerFontName = aTempName;
+ break;
+ }
+ }
+ }
+ while ( nIndex != STRING_NOTFOUND );
+ if ( !pFoundData && pTempFoundData )
+ {
+ pFoundData = pTempFoundData;
+ aLowerFontName = aTempName2;
+ }
+
+ // Danach versuchen wir es nocheinmal unter Beruecksichtigung
+ // der gloablen Fontersetzungstabelle, wobei wir jetzt auch
+ // die Fonts nehmen, die ersetzt werden sollen, wenn sie
+ // nicht vorhanden sind
+ if ( !pFoundData )
+ {
+ nSubstFlags1 &= ~FONT_SUBSTITUTE_ALWAYS;
+ nSubstFlags2 &= ~FONT_SUBSTITUTE_ALWAYS;
+ nIndex = 0;
+ do
+ {
+ aTempName = aLowerFontName.GetToken( 0, ';', nIndex );
+ ImplCutScriptAndSpaces( aTempName );
+ if ( ImplFontSubstitute( aTempName, nSubstFlags1, nSubstFlags2 ) )
+ {
+ pFoundData = pFontList->ImplFind( aTempName );
+ if ( pFoundData )
+ {
+ aLowerFontName = aTempName;
+ break;
+ }
+ }
+ }
+ while ( nIndex != STRING_NOTFOUND );
+ }
+
+ // Wenn kein Font mit dem entsprechenden Namen existiert, versuchen
+ // wir ueber den Namen und die Attribute einen passenden Font zu
+ // finden
+ ULONG nFontCount = pFontList->Count();
+ if ( !pFoundData && nFontCount )
+ {
+#if 0
+ pFontList->InitMatchData();
+
+ // 1. Token vom Fontnamen nehmen und Sonderzeichen entfernen
+ XubString aNoSymbolName = aFirstName;
+ ImplCutScriptAndSpaces( aNoSymbolName );
+ ImplStrEraseAllSymbols( aNoSymbolName );
+
+ // Script evtl. aus CharSet gewinnen, wenn nicht ueber den Fontnamen
+ // ermittelt werden konnte
+ if ( eScript == SCRIPT_DONTKNOW )
+ eScript = eCharSetScript;
+
+ // wir versuchen zuerst einen Font zu finden, der ueber den Namen
+ // matched
+ ULONG nTestMatch;
+ ULONG nBestMatch = 0;
+ for ( ULONG i = 0; i < nFontCount; i++ )
+ {
+ ImplDevFontListData* pData = pFontList->Get( i );
+
+ nTestMatch = 0;
+
+ // Wir wollen schon Zeichen erkennen
+ if ( eScript != SCRIPT_DONTKNOW )
+ {
+ if ( ImplFindScript( pData, eScript ) )
+ nTestMatch += 1000000000;
+ }
+
+ // skalierbare Schriften haben schon einen echten Vorteil
+ // gegenueber nicht skalierbaren Schriften
+ if ( pData->mbScalable )
+ nTestMatch += 500000000;
+
+/*
+ // Wir gehen davon aus, wenn der Name groesstenteils matcht,
+ // das er schon zur richtigen Familie gehoert
+
+
+ // Beim matchen ignorieren wir alle Sonderzeichen
+ ULONG nTestMatch = ImplStrMatch( aNoSymbolName, pData->maMatchName2 );
+ if ( nTestMatch >= nBestMatch )
+ {
+ // Match nur erlaubt, wenn auch die Attribute uebereinstimmen
+ BOOL bTestFamily = pData->meMatchFamily != FAMILY_DONTKNOW;
+ BOOL bTestSymbol = pData->mbSymbol;
+ BOOL bTestFixed = pData->meMatchPitch == PITCH_FIXED;
+ if ( (bFixed == bTestFixed) && (bSymbol == bTestSymbol) &&
+ (!bFamily || !bTestFamily || (eSearchFamily == pData->meMatchFamily)) )
+ {
+ xub_StrLen nAttrMatch = 0;
+ // Die Anzahl der uebereinstimmenden Attribute zaehlen
+ const char** pTypeList = aImplTypeList;
+ while ( *pTypeList )
+ {
+ if ( (aNoSymbolName.Search( *pTypeList ) != STRING_NOTFOUND) &&
+ (pData->maMatchName2.Search( *pTypeList ) != STRING_NOTFOUND) )
+ nAttrMatch++;
+ pTypeList++;
+ }
+
+ // Wenn beide Matches gleich gut sind,
+ // entscheiden die uebereinstimmenden Attribute
+ if ( nBestMatch == nTestMatch )
+ {
+ if ( (nAttrMatch > nBestAttrMatch) ||
+ ((nAttrMatch == nBestAttrMatch) &&
+ (pData->maMatchName2.Len() < nBestStrLen)) )
+ {
+ pFoundData = pData;
+ nBestMatch = nTestMatch;
+ nBestAttrMatch = nAttrMatch;
+ nBestStrLen = pData->maMatchName2.Len();
+ }
+ }
+ else
+ {
+ pFoundData = pData;
+ nBestMatch = nTestMatch;
+ nBestAttrMatch = nAttrMatch;
+ nBestStrLen = pData->maMatchName2.Len();
+ }
+ }
+ }
+*/
+
+ if ( nTestMatch > nBestMatch )
+ {
+ pFoundData = pData;
+ nBestMatch = nTestMatch;
+ }
+ }
+
+ if ( !pFoundData )
+ {
+ pFoundData = pFontList->GetStandardFont( IMPL_STDFONT_ROMAN );
+ // Wenn alles nichts hilft, nehmen wir den ersten
+ if ( !pFoundData )
+ pFontList->Get( 0 );
+ }
+#else
+ // 1. Token vom Fontnamen nehmen und Sonderzeichen entfernen
+ XubString aNoSymbolName = aFirstName;
+ ImplStrEraseAllSymbols( aNoSymbolName );
+
+ // Suchattribute ermitteln
+ BOOL bFamily;
+ BOOL bSymbol;
+ BOOL bFixed;
+ FontFamily eSearchFamily = eFamily;
+ CharSet eSearchCharSet = eCharSet;
+ FontPitch eSearchPitch = ePitch;
+ ImplFontAttrFromName( aNoSymbolName, eSearchFamily, eSearchCharSet, eSearchPitch );
+ bFamily = eSearchFamily != FAMILY_DONTKNOW;
+ bSymbol = eSearchCharSet == RTL_TEXTENCODING_SYMBOL;
+ bFixed = eSearchPitch == PITCH_FIXED;
+ // Solange in der Namesliste suchen, bis wir auswertbare
+ // Attribute gefunden haben
+ xub_StrLen nTempIndex = nFirstNameIndex;
+ while ( (nTempIndex != STRING_NOTFOUND) && !bFamily && !bFixed && !bSymbol )
+ {
+ aTempName = aLowerFontName.GetToken( 0, ';', nTempIndex );
+ ImplCutScriptAndSpaces( aTempName );
+ if ( !aTempName.Len() )
+ break;
+ ImplStrEraseAllSymbols( aTempName );
+ ImplFontAttrFromName( aTempName, eSearchFamily, eSearchCharSet, eSearchPitch );
+ bFamily = eSearchFamily != FAMILY_DONTKNOW;
+ bSymbol = eSearchCharSet == RTL_TEXTENCODING_SYMBOL;
+ bFixed = eSearchPitch == PITCH_FIXED;
+ }
+ aLowerFontName = aFirstName;
+
+ // wir versuchen zuerst einen Font zu finden, der ueber den Namen
+ // matched
+ ULONG i;
+ xub_StrLen nBestMatch = 5;
+ xub_StrLen nBestAttrMatch = 0;
+ xub_StrLen nBestStrLen = 0xFFFF;
+ for ( i = 0; i < nFontCount; i++ )
+ {
+ ImplDevFontListData* pData = pFontList->Get( i );
+ // Beim matchen ignorieren wir alle Sonderzeichen
+ xub_StrLen nTestMatch = ImplStrMatch( aNoSymbolName, pData->maMatchName2 );
+ if ( nTestMatch >= nBestMatch )
+ {
+ // Match nur erlaubt, wenn auch die Attribute uebereinstimmen
+ BOOL bTestFamily = pData->meMatchFamily != FAMILY_DONTKNOW;
+ BOOL bTestSymbol = pData->mbSymbol;
+ BOOL bTestFixed = pData->meMatchPitch == PITCH_FIXED;
+ if ( (bFixed == bTestFixed) && (bSymbol == bTestSymbol) &&
+ (!bFamily || !bTestFamily || (eSearchFamily == pData->meMatchFamily)) )
+ {
+ xub_StrLen nAttrMatch = 0;
+ // Die Anzahl der uebereinstimmenden Attribute zaehlen
+ const char** pTypeList = aImplTypeList;
+ while ( *pTypeList )
+ {
+ if ( (aNoSymbolName.SearchAscii( *pTypeList ) != STRING_NOTFOUND) &&
+ (pData->maMatchName2.SearchAscii( *pTypeList ) != STRING_NOTFOUND) )
+ nAttrMatch++;
+ pTypeList++;
+ }
+
+ // Wenn beide Matches gleich gut sind,
+ // entscheiden die uebereinstimmenden Attribute
+ if ( nBestMatch == nTestMatch )
+ {
+ if ( (nAttrMatch > nBestAttrMatch) ||
+ ((nAttrMatch == nBestAttrMatch) &&
+ (pData->maMatchName2.Len() < nBestStrLen)) )
+ {
+ pFoundData = pData;
+ nBestMatch = nTestMatch;
+ nBestAttrMatch = nAttrMatch;
+ nBestStrLen = pData->maMatchName2.Len();
+ }
+ }
+ else
+ {
+ pFoundData = pData;
+ nBestMatch = nTestMatch;
+ nBestAttrMatch = nAttrMatch;
+ nBestStrLen = pData->maMatchName2.Len();
+ }
+ }
+ }
+ }
+
+ // Wenn wir immer noch keinen passenden Font gefunden haben, versuchen
+ // wir es ueber die Attribute
+ if ( !pFoundData )
+ {
+ if ( bFixed )
+ {
+ pFoundData = pFontList->GetStandardFont( IMPL_STDFONT_FIXED );
+ if ( !pFoundData )
+ {
+ nBestMatch = 0;
+ for ( i = 0; i < nFontCount; i++ )
+ {
+ ImplDevFontListData* pData = pFontList->Get( i );
+ if ( (pData->meMatchPitch == PITCH_FIXED) &&
+ !pData->mbSymbol &&
+ (pData->meMatchFamily != FAMILY_DECORATIVE) )
+ {
+ if ( pData->mnMatch > nBestMatch )
+ {
+ pFoundData = pData;
+ nBestMatch = pData->mnMatch;
+ }
+ }
+ }
+ }
+ }
+
+ if ( bFamily && !pFoundData )
+ {
+ if ( eSearchFamily == FAMILY_SWISS )
+ pFoundData = pFontList->GetStandardFont( IMPL_STDFONT_SWISS );
+ else if ( eSearchFamily == FAMILY_ROMAN )
+ pFoundData = pFontList->GetStandardFont( IMPL_STDFONT_ROMAN );
+ else if ( eSearchFamily == FAMILY_SCRIPT )
+ pFoundData = pFontList->GetStandardFont( IMPL_STDFONT_SCRIPT );
+ if ( !pFoundData )
+ {
+ nBestMatch = 0;
+ for ( i = 0; i < nFontCount; i++ )
+ {
+ ImplDevFontListData* pData = pFontList->Get( i );
+ if ( (pData->meMatchFamily == eSearchFamily) &&
+ !pData->mbSymbol &&
+ (pData->meMatchPitch != PITCH_FIXED) )
+ {
+ if ( pData->mnMatch > nBestMatch )
+ {
+ pFoundData = pData;
+ nBestMatch = pData->mnMatch;
+ }
+ }
+ }
+ }
+ }
+
+ if ( bSymbol && !pFoundData )
+ {
+ pFoundData = pFontList->GetStandardFont( IMPL_STDFONT_SYMBOL );
+ if ( !pFoundData )
+ {
+ nBestMatch = 0;
+ for ( i = 0; i < nFontCount; i++ )
+ {
+ ImplDevFontListData* pData = pFontList->Get( i );
+ if ( pData->mbSymbol )
+ {
+ if ( pData->mnMatch > nBestMatch )
+ {
+ pFoundData = pData;
+ nBestMatch = pData->mnMatch;
+ }
+ }
+ }
+ }
+ }
+
+ if ( !pFoundData )
+ {
+ pFoundData = pFontList->GetStandardFont( IMPL_STDFONT_ROMAN );
+ // Wenn alles nichts hilft, nehmen wir den ersten
+ if ( !pFoundData )
+ pFontList->Get( 0 );
+ }
+ }
+#endif
+ }
+
+ // Script evtl. aus CharSet gewinnen, wenn nicht ueber den Fontnamen
+ // ermittelt werden konnte
+ if ( eScript == SCRIPT_DONTKNOW )
+ eScript = eCharSetScript;
+
+ // Jetzt suchen wir den Font ueber die Attribute
+ ImplFontData* pFontData = NULL;
+ if ( pFoundData )
+ {
+ ULONG nBestMatch = 0; // Der groessere Wert ist der bessere
+ ULONG nBestHeightMatch = 0; // Der kleinere Wert ist der bessere
+ ULONG nBestWidthMatch = 0; // Der kleinere Wert ist der bessere
+ ULONG nMatch;
+ ULONG nHeightMatch;
+ ULONG nWidthMatch;
+ ImplFontData* pCurFontData;
+
+// !!!!! Wegen Office-Fehler !!!!
+// XubString aCompareStyleName = rStyleName;
+// aCompareStyleName.ToLowerAscii();
+
+ // Vorallem wegen OS2-System-Standard-Fonts vergleichen wir
+ // den FontNamen mit FontName + StyleName, damit
+ // WarpSans Bold auch einen fetten Font ergibt
+ const xub_Unicode* pCompareStyleName = NULL;
+ if ( (aLowerFontName.Len() > pFoundData->maMatchName.Len()) &&
+ aLowerFontName.Equals( pFoundData->maMatchName, 0, pFoundData->maMatchName.Len() ) )
+ pCompareStyleName = aLowerFontName.GetBuffer()+pFoundData->maMatchName.Len()+1;
+
+ pCurFontData = pFoundData->mpFirst;
+ while ( pCurFontData )
+ {
+ nMatch = 0;
+ nHeightMatch = 0;
+ nWidthMatch = 0;
+
+// if ( aCompareStyleName.Len() &&
+// aCompareStyleName.EqualsIgnoreCaseAscii( pCurFontData->maStyleName ) )
+// nMatch += 120000;
+ if ( pCompareStyleName &&
+ pCurFontData->maStyleName.EqualsIgnoreCaseAscii( pCompareStyleName ) )
+ nMatch += 120000;
+
+ if ( eCharSet != RTL_TEXTENCODING_DONTKNOW )
+ {
+ if ( eCharSet == pCurFontData->meCharSet )
+ nMatch += 60000;
+ }
+
+ if ( eScript == pCurFontData->meScript )
+ nMatch += 30000;
+
+ if ( (ePitch != PITCH_DONTKNOW) && (ePitch == pCurFontData->mePitch) )
+ nMatch += 15000;
+
+ if ( (eFamily != FAMILY_DONTKNOW) && (eFamily == pCurFontData->meFamily) )
+ nMatch += 7500;
+
+ // Normale Schriftbreiten bevorzugen, da wir noch keine Daten
+ // von den Applikationen bekommen
+ if ( pCurFontData->meWidthType == WIDTH_NORMAL )
+ nMatch += 3750;
+
+ if ( eWeight != WEIGHT_DONTKNOW )
+ {
+ USHORT nReqWeight;
+ USHORT nGivenWeight;
+ USHORT nWeightDiff;
+ // schmale Fonts werden bei nicht Bold vor fetten
+ // Fonts bevorzugt
+ if ( eWeight > WEIGHT_MEDIUM )
+ nReqWeight = ((USHORT)eWeight)+100;
+ else
+ nReqWeight = (USHORT)eWeight;
+ if ( pCurFontData->meWeight > WEIGHT_MEDIUM )
+ nGivenWeight = ((USHORT)pCurFontData->meWeight)+100;
+ else
+ nGivenWeight = (USHORT)pCurFontData->meWeight;
+ if ( nReqWeight > nGivenWeight )
+ nWeightDiff = nReqWeight-nGivenWeight;
+ else
+ nWeightDiff = nGivenWeight-nReqWeight;
+
+ if ( nWeightDiff == 0 )
+ nMatch += 1000;
+ else if ( nWeightDiff == 1 )
+ nMatch += 700;
+ else if ( nWeightDiff < 50 )
+ nMatch += 200;
+ }
+ if ( eItalic == ITALIC_NONE )
+ {
+ if ( pCurFontData->meItalic == ITALIC_NONE )
+ nMatch += 900;
+ }
+ else
+ {
+ if ( eItalic == pCurFontData->meItalic )
+ nMatch += 900;
+ else if ( pCurFontData->meItalic != ITALIC_NONE )
+ nMatch += 600;
+ }
+
+ if ( pCurFontData->mbDevice )
+ nMatch += 40;
+ if ( pCurFontData->meType == TYPE_SCALABLE )
+ {
+ if ( nOrientation )
+ nMatch += 80;
+ else
+ {
+ if ( nWidth )
+ nMatch += 25;
+ else
+ nMatch += 5;
+ }
+ }
+ else
+ {
+ if ( nHeight == pCurFontData->mnHeight )
+ {
+ nMatch += 20;
+ if ( nWidth == pCurFontData->mnWidth )
+ nMatch += 10;
+ }
+ else
+ {
+ // Dann kommt die Size-Abweichung in die
+ // Bewertung rein. Hier bevorzugen wir
+ // nach Moeglichkeit den kleineren Font
+ if ( nHeight < pCurFontData->mnHeight )
+ nHeightMatch += pCurFontData->mnHeight-nHeight;
+ else
+ nHeightMatch += (nHeight-pCurFontData->mnHeight-nHeight)+10000;
+ if ( nWidth && pCurFontData->mnWidth && (nWidth != pCurFontData->mnWidth) )
+ {
+ if ( nWidth < pCurFontData->mnWidth )
+ nWidthMatch += pCurFontData->mnWidth-nWidth;
+ else
+ nWidthMatch += nWidth-pCurFontData->mnWidth-nWidth;
+ }
+ }
+ }
+
+ if ( nMatch > nBestMatch )
+ {
+ pFontData = pCurFontData;
+ nBestMatch = nMatch;
+ nBestHeightMatch = nHeightMatch;
+ nBestWidthMatch = nWidthMatch;
+ }
+ else if ( nMatch == nBestMatch )
+ {
+ // Wenn 2 gleichwertig sind, kommt die Size-Bewertung
+ // Hier gewinnt der jenige, der die niedrigere Abweichung
+ // in der Groesse hat (also den kleinsten Match)
+ if ( nHeightMatch < nBestHeightMatch )
+ {
+ pFontData = pCurFontData;
+ nBestHeightMatch = nHeightMatch;
+ nBestWidthMatch = nWidthMatch;
+ }
+ else if ( nHeightMatch == nBestHeightMatch )
+ {
+ if ( nWidthMatch < nBestWidthMatch )
+ {
+ pFontData = pCurFontData;
+ nBestWidthMatch = nWidthMatch;
+ }
+ }
+ }
+
+ pCurFontData = pCurFontData->mpNext;
+ }
+ }
+
+ // Daten initialisieren und in die Liste aufnehmen
+ pEntry = new ImplFontEntry;
+ pEntry->mbInit = FALSE;
+ pEntry->mnRefCount = 1;
+ pEntry->mpNext = mpFirstEntry;
+ pEntry->mnWidthAryCount = 0;
+ pEntry->mnWidthArySize = 0;
+ pEntry->mpWidthAry = NULL;
+ pEntry->mpKernPairs = NULL;
+ pEntry->mpKernInfo = NULL;
+ pEntry->mnOwnOrientation = 0;
+ pEntry->mnOrientation = 0;
+ mpFirstEntry = pEntry;
+
+ // Font-Selection-Daten setzen
+ ImplFontSelectData* pFontSelData = &(pEntry->maFontSelData);
+ pFontSelData->mpFontData = pFontData;
+ pFontSelData->mpSysSelData = NULL;
+ pFontSelData->maName = rName;
+ pFontSelData->maStyleName = rStyleName;
+ pFontSelData->mnWidth = nWidth;
+ pFontSelData->mnHeight = nHeight;
+ pFontSelData->meFamily = eFamily;
+ pFontSelData->meCharSet = eCharSet;
+ pFontSelData->meWidthType = WIDTH_DONTKNOW;
+ pFontSelData->meWeight = eWeight;
+ pFontSelData->meItalic = eItalic;
+ pFontSelData->mePitch = ePitch;
+ pFontSelData->mnOrientation = nOrientation;
+
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFontCache::Release( ImplFontEntry* pEntry )
+{
+ pEntry->mnRefCount--;
+
+ if ( !pEntry->mnRefCount )
+ {
+ if ( mnRef0Count >= MAXFONT_CACHE )
+ {
+ // Letzten Entry mit RefCount 0 loeschen
+ ImplFontEntry* pPrevDelEntry = mpFirstEntry;
+ ImplFontEntry* pDelEntry = pPrevDelEntry->mpNext;
+ USHORT nCurRef0Count = !(pPrevDelEntry->mnRefCount);
+ while ( pDelEntry )
+ {
+ if ( !pDelEntry->mnRefCount )
+ nCurRef0Count++;
+
+ if ( nCurRef0Count >= MAXFONT_CACHE )
+ {
+ pPrevDelEntry->mpNext = pDelEntry->mpNext;
+ delete pDelEntry;
+ break;
+ }
+
+ pPrevDelEntry = pDelEntry;
+ pDelEntry = pDelEntry->mpNext;
+ }
+ }
+ else
+ mnRef0Count++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFontCache::Clear()
+{
+ // Alle Eintraege loeschen
+ ImplFontEntry* pTemp;
+ ImplFontEntry* pEntry = mpFirstEntry;
+ while ( pEntry )
+ {
+ DBG_ASSERT( !pEntry->mnRefCount, "ImplFontCache::Clear() - Font in use" );
+ pTemp = pEntry->mpNext;
+ delete pEntry;
+ pEntry = pTemp;
+ }
+
+ mpFirstEntry = NULL;
+ mnRef0Count = 0;
+}
+
+// =======================================================================
+
+class ImplTextLineInfo
+{
+private:
+ long mnWidth;
+ xub_StrLen mnIndex;
+ xub_StrLen mnLen;
+
+public:
+ ImplTextLineInfo( long nWidth, xub_StrLen nIndex, xub_StrLen nLen )
+ {
+ mnWidth = nWidth;
+ mnIndex = nIndex;
+ mnLen = nLen;
+ }
+
+ long GetWidth() const { return mnWidth; }
+ xub_StrLen GetIndex() const { return mnIndex; }
+ xub_StrLen GetLen() const { return mnLen; }
+};
+
+#define MULTITEXTLINEINFO_RESIZE 16
+typedef ImplTextLineInfo* PImplTextLineInfo;
+
+class ImplMultiTextLineInfo
+{
+private:
+ PImplTextLineInfo* mpLines;
+ xub_StrLen mnLines;
+ xub_StrLen mnSize;
+
+public:
+ ImplMultiTextLineInfo();
+ ~ImplMultiTextLineInfo();
+
+ void AddLine( ImplTextLineInfo* pLine );
+ void Clear();
+
+ ImplTextLineInfo* GetLine( USHORT nLine ) const
+ { return mpLines[nLine]; }
+ xub_StrLen Count() const { return mnLines; }
+
+private:
+ ImplMultiTextLineInfo( const ImplMultiTextLineInfo& );
+ ImplMultiTextLineInfo& operator=( const ImplMultiTextLineInfo& );
+};
+
+ImplMultiTextLineInfo::ImplMultiTextLineInfo()
+{
+ mpLines = new PImplTextLineInfo[MULTITEXTLINEINFO_RESIZE];
+ mnLines = 0;
+ mnSize = MULTITEXTLINEINFO_RESIZE;
+}
+
+ImplMultiTextLineInfo::~ImplMultiTextLineInfo()
+{
+ for ( xub_StrLen i = 0; i < mnLines; i++ )
+ delete mpLines[i];
+ delete mpLines;
+}
+
+void ImplMultiTextLineInfo::AddLine( ImplTextLineInfo* pLine )
+{
+ if ( mnSize == mnLines )
+ {
+ mnSize += MULTITEXTLINEINFO_RESIZE;
+ PImplTextLineInfo* pNewLines = new PImplTextLineInfo[mnSize];
+ memcpy( pNewLines, mpLines, mnLines*sizeof(PImplTextLineInfo) );
+ mpLines = pNewLines;
+ }
+
+ mpLines[mnLines] = pLine;
+ mnLines++;
+}
+
+void ImplMultiTextLineInfo::Clear()
+{
+ for ( xub_StrLen i = 0; i < mnLines; i++ )
+ delete mpLines[i];
+ mnLines = 0;
+}
+
+// =======================================================================
+
+void OutputDevice::ImplInitFont()
+{
+ DBG_TESTSOLARMUTEX();
+
+ if ( mbInitFont )
+ {
+#ifndef REMOTE_APPSERVER
+ mpFontEntry->mnSetFontFlags = mpGraphics->SetFont( &(mpFontEntry->maFontSelData) );
+ mbInitFont = FALSE;
+#else
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ RemoteFont aFont;
+
+ if ( pFontEntry->maFontSelData.mpFontData )
+ {
+ aFont.maName = pFontEntry->maFontSelData.mpFontData->maName;
+ aFont.maStyleName = pFontEntry->maFontSelData.mpFontData->maStyleName;
+ }
+ else
+ {
+ aFont.maName = pFontEntry->maFontSelData.maName;
+ aFont.maStyleName = pFontEntry->maFontSelData.maStyleName;
+ }
+ aFont.mnWidth = pFontEntry->maFontSelData.mnWidth;
+ aFont.mnHeight = pFontEntry->maFontSelData.mnHeight;
+ aFont.meFamily = pFontEntry->maFontSelData.meFamily;
+ aFont.meCharSet = pFontEntry->maFontSelData.meCharSet;
+ aFont.meWidthType = pFontEntry->maFontSelData.meWidthType;
+ aFont.meWeight = pFontEntry->maFontSelData.meWeight;
+ aFont.meItalic = pFontEntry->maFontSelData.meItalic;
+ aFont.mePitch = pFontEntry->maFontSelData.mePitch;
+ aFont.mnOrientation = pFontEntry->maFontSelData.mnOrientation;
+ mpGraphics->SetFont( aFont );
+ pFontEntry->mnSetFontFlags = 0;
+ mbInitFont = FALSE;
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplInitTextColor()
+{
+ DBG_TESTSOLARMUTEX();
+
+ if ( mbInitTextColor )
+ {
+#ifndef REMOTE_APPSERVER
+ mpGraphics->SetTextColor( ImplColorToSal( GetTextColor() ) );
+#else
+ mpGraphics->SetTextColor( GetTextColor() );
+#endif
+ mbInitTextColor = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+int OutputDevice::ImplNewFont()
+{
+ DBG_TESTSOLARMUTEX();
+
+ if ( !mbNewFont )
+ return TRUE;
+
+ mbNewFont = FALSE;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return FALSE;
+ }
+ SalGraphics* pGraphics = mpGraphics;
+#else
+ // Da wegen Clipping hier NULL zurueckkommen kann, koennen wir nicht
+ // den Rueckgabewert nehmen
+ ImplGetServerGraphics();
+ ImplServerGraphics* pGraphics = mpGraphics;
+#endif
+
+ // Groesse umrechnen
+ Size aSize = ImplLogicToDevicePixel( maFont.GetSize() );
+ if ( !aSize.Height() )
+ {
+ // Nur dann Defaultgroesse setzen, wenn Fonthoehe auch in logischen
+ // Koordinaaten 0 ist
+ if ( maFont.GetSize().Height() )
+ aSize.Height() = 1;
+ else
+ aSize.Height() = (12*mnDPIY)/72;
+ }
+
+ // Neuen Font besorgen
+ ImplFontEntry* pOldEntry = mpFontEntry;
+ mpFontEntry = mpFontCache->Get( mpFontList, maFont, aSize );
+ ImplFontEntry* pFontEntry = mpFontEntry;
+
+ // Feststellen, ob Font neu selektiert werden muss
+ if ( pFontEntry != pOldEntry )
+ mbInitFont = TRUE;
+
+ // these two may be filled in remote version
+ ImplKernPairData* pKernPairs = NULL;
+ long nKernPairs = 0;
+ // Wenn Font nicht initialisiert ist, dann sofort selektieren
+ if ( !pFontEntry->mbInit )
+ {
+ ImplInitFont();
+
+ // und die Font-Daten besorgen
+ if ( pGraphics )
+ {
+ pFontEntry->mbInit = TRUE;
+
+ pFontEntry->maMetric.mnWidth = pFontEntry->maFontSelData.mnWidth;
+ pFontEntry->maMetric.meFamily = pFontEntry->maFontSelData.meFamily;
+ pFontEntry->maMetric.meCharSet = pFontEntry->maFontSelData.meCharSet;
+ pFontEntry->maMetric.meWeight = pFontEntry->maFontSelData.meWeight;
+ pFontEntry->maMetric.meItalic = pFontEntry->maFontSelData.meItalic;
+ pFontEntry->maMetric.mePitch = pFontEntry->maFontSelData.mePitch;
+ pFontEntry->maMetric.mnOrientation = pFontEntry->maFontSelData.mnOrientation;
+ if ( pFontEntry->maFontSelData.mpFontData )
+ {
+ pFontEntry->maMetric.meType = pFontEntry->maFontSelData.mpFontData->meType;
+ pFontEntry->maMetric.maName = pFontEntry->maFontSelData.mpFontData->maName;
+ pFontEntry->maMetric.maStyleName= pFontEntry->maFontSelData.mpFontData->maStyleName;
+ pFontEntry->maMetric.mbDevice = pFontEntry->maFontSelData.mpFontData->mbDevice;
+ }
+ else
+ {
+ pFontEntry->maMetric.meType = TYPE_DONTKNOW;
+ pFontEntry->maMetric.maName = pFontEntry->maFontSelData.maName.GetToken( 0 );
+ pFontEntry->maMetric.maStyleName= pFontEntry->maFontSelData.maStyleName;
+ pFontEntry->maMetric.mbDevice = FALSE;
+ }
+ pFontEntry->maMetric.mnSuperscriptSize = 0;
+ pFontEntry->maMetric.mnSuperscriptOffset = 0;
+ pFontEntry->maMetric.mnSubscriptSize = 0;
+ pFontEntry->maMetric.mnSubscriptOffset = 0;
+ pFontEntry->maMetric.mnUnderlineSize = 0;
+ pFontEntry->maMetric.mnUnderlineOffset = 0;
+ pFontEntry->maMetric.mnBUnderlineSize = 0;
+ pFontEntry->maMetric.mnBUnderlineOffset = 0;
+ pFontEntry->maMetric.mnDUnderlineSize = 0;
+ pFontEntry->maMetric.mnDUnderlineOffset1 = 0;
+ pFontEntry->maMetric.mnDUnderlineOffset2 = 0;
+ pFontEntry->maMetric.mnWUnderlineSize = 0;
+ pFontEntry->maMetric.mnWUnderlineOffset = 0;
+ pFontEntry->maMetric.mnStrikeoutSize = 0;
+ pFontEntry->maMetric.mnStrikeoutOffset = 0;
+ pFontEntry->maMetric.mnBStrikeoutSize = 0;
+ pFontEntry->maMetric.mnBStrikeoutOffset = 0;
+ pFontEntry->maMetric.mnDStrikeoutSize = 0;
+ pFontEntry->maMetric.mnDStrikeoutOffset1 = 0;
+ pFontEntry->maMetric.mnDStrikeoutOffset2 = 0;
+#ifndef REMOTE_APPSERVER
+ pGraphics->GetFontMetric( &(pFontEntry->maMetric) );
+ pFontEntry->mnWidthFactor = pGraphics->GetCharWidth( 0, CHARCACHE_STD-1, pFontEntry->maWidthAry );
+#else
+ long nFactor = 0;
+
+ pGraphics->GetFontMetric(
+ pFontEntry->maMetric,
+ nFactor, 0, CHARCACHE_STD-1, pFontEntry->maWidthAry,
+ maFont.IsKerning(), &pKernPairs, nKernPairs
+ );
+ pFontEntry->mnWidthFactor = nFactor;
+#endif
+ if ( !pFontEntry->mnWidthFactor )
+ {
+ memset( pFontEntry->maWidthAry, 0, sizeof(long)*(CHARCACHE_STD-1) );
+ pFontEntry->mnWidthFactor = 1;
+ }
+
+ pFontEntry->mbFixedFont = pFontEntry->maMetric.mePitch == PITCH_FIXED;
+ pFontEntry->mnLineHeight = pFontEntry->maMetric.mnAscent+pFontEntry->maMetric.mnDescent;
+ pFontEntry->mbInitKernPairs = FALSE;
+ pFontEntry->mnKernPairs = nKernPairs;
+
+ if ( pFontEntry->maFontSelData.mnOrientation && !pFontEntry->maMetric.mnOrientation &&
+ (meOutDevType != OUTDEV_PRINTER) )
+ {
+ pFontEntry->mnOwnOrientation = pFontEntry->maFontSelData.mnOrientation;
+ pFontEntry->mnOrientation = pFontEntry->mnOwnOrientation;
+ }
+ else
+ pFontEntry->mnOrientation = pFontEntry->maMetric.mnOrientation;
+ }
+ }
+
+ // Wenn Kerning gewuenscht ist, die Kerning-Werte ermitteln
+ if ( maFont.IsKerning() )
+ {
+ ImplInitKerningPairs( pKernPairs, nKernPairs );
+ mbKerning = (pFontEntry->mnKernPairs) != 0;
+ }
+ else
+ mbKerning = FALSE;
+
+ // Je nach TextAlign den TextOffset berechnen
+ TextAlign eAlign = maFont.GetAlign();
+ if ( eAlign == ALIGN_BASELINE )
+ {
+ mnTextOffX = 0;
+ mnTextOffY = 0;
+ }
+ else if ( eAlign == ALIGN_TOP )
+ {
+ long nOrientation = pFontEntry->mnOrientation;
+ if ( nOrientation )
+ {
+ double nRad = ((double)nOrientation * F_2PI) / 3600.0;
+ long nOff = pFontEntry->maMetric.mnAscent;
+ mnTextOffX = (long)(nOff * sin( nRad ));
+ mnTextOffY = (long)(nOff * cos( nRad ));
+ }
+ else
+ {
+ mnTextOffX = 0;
+ mnTextOffY = pFontEntry->maMetric.mnAscent;
+ }
+ }
+ else // eAlign == ALIGN_BOTTOM
+ {
+ long nOrientation = pFontEntry->mnOrientation;
+ if ( nOrientation )
+ {
+ double nRad = ((double)nOrientation * F_2PI) / 3600.0;
+ long nOff = pFontEntry->maMetric.mnDescent;
+ mnTextOffX = (long)(nOff - (nOff * sin( nRad )));
+ nOff = -nOff;
+ mnTextOffY = (long)(nOff * cos( nRad ));
+ }
+ else
+ {
+ mnTextOffX = 0;
+ mnTextOffY = -pFontEntry->maMetric.mnDescent;
+ }
+ }
+
+ mbTextLines = ((maFont.GetUnderline() != UNDERLINE_NONE) && (maFont.GetUnderline() != UNDERLINE_DONTKNOW)) ||
+ ((maFont.GetStrikeout() != STRIKEOUT_NONE) && (maFont.GetStrikeout() != STRIKEOUT_DONTKNOW));
+ mbTextSpecial = maFont.IsShadow() || maFont.IsOutline();
+
+ if ( pOldEntry )
+ mpFontCache->Release( pOldEntry );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplGetCharWidth( sal_Unicode c ) const
+{
+ USHORT nChar = (USHORT)c;
+ if ( nChar < CHARCACHE_STD )
+ return mpFontEntry->maWidthAry[nChar];
+
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ ImplWidthInfoData* pInfo;
+ ImplWidthInfoData* pWidthAry = pFontEntry->mpWidthAry;
+ USHORT nWidthCount = pFontEntry->mnWidthAryCount;
+ USHORT nInsIndex;
+
+ if ( nWidthCount )
+ {
+ USHORT nLow;
+ USHORT nHigh;
+ USHORT nMid;
+ USHORT nCompareChar;
+
+ nLow = 0;
+ nHigh = nWidthCount-1;
+ do
+ {
+ nMid = (nLow+nHigh)/2;
+ pInfo = pWidthAry+nMid;
+ nCompareChar = pInfo->mnChar;
+ if ( nChar < nCompareChar )
+ {
+ if ( !nMid )
+ break;
+ nHigh = nMid-1;
+ }
+ else
+ {
+ if ( nChar > nCompareChar )
+ nLow = nMid+1;
+ else
+ return pInfo->mnWidth;
+ }
+ }
+ while ( nLow <= nHigh );
+
+ if ( nChar > nCompareChar )
+ nInsIndex = nMid+1;
+ else
+ nInsIndex = nMid;
+ }
+ else
+ {
+ pFontEntry->mnWidthArySize = WIDTHARY_INIT;
+ pFontEntry->mpWidthAry = new ImplWidthInfoData[pFontEntry->mnWidthArySize];
+ pWidthAry = pFontEntry->mpWidthAry;
+ nInsIndex = 0;
+ }
+
+ if ( nWidthCount == pFontEntry->mnWidthArySize )
+ {
+ USHORT nOldSize = pFontEntry->mnWidthArySize;
+ pFontEntry->mnWidthArySize += WIDTHARY_RESIZE;
+ pFontEntry->mpWidthAry = new ImplWidthInfoData[pFontEntry->mnWidthArySize];
+ memcpy( pFontEntry->mpWidthAry, pWidthAry, nOldSize*sizeof(ImplWidthInfoData) );
+ delete pWidthAry;
+ pWidthAry = pFontEntry->mpWidthAry;
+ }
+
+ // Um die Zeichenbreite zu ermitteln, brauchen wir einen Graphics und der
+ // Font muss natuerlich auch selektiert sein
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !((OutputDevice*)this)->ImplGetGraphics() )
+ return 0;
+ }
+#else
+ // Da wegen Clipping hier NULL zurueckkommen kann, koennen wir nicht
+ // den Rueckgabewert nehmen
+ ((OutputDevice*)this)->ImplGetServerGraphics();
+#endif
+
+ if ( mbNewFont )
+ ((OutputDevice*)this)->ImplNewFont();
+ if ( mbInitFont )
+ ((OutputDevice*)this)->ImplInitFont();
+
+ long nWidth;
+#ifndef REMOTE_APPSERVER
+ long nWidthFactor = mpGraphics->GetCharWidth( nChar, nChar, &nWidth );
+#else
+ long nWidthFactor = pFontEntry->mnWidthFactor;
+ mpGraphics->GetCharWidth( nChar, nChar, &nWidth );
+#endif
+ if ( !nWidthFactor )
+ return 0;
+
+ DBG_ASSERT( (nWidthFactor == pFontEntry->mnWidthFactor),
+ "OutputDevice::ImplGetCharWidth() - other WidthFactor" );
+
+ // Breite in Liste einfuegen und zurueckgeben
+ pInfo = pWidthAry+nInsIndex;
+ memmove( pInfo+1, pInfo, (nWidthCount-nInsIndex)*sizeof(ImplWidthInfoData) );
+ pFontEntry->mnWidthAryCount++;
+ pInfo->mnChar = nChar;
+ pInfo->mnWidth = nWidth;
+ return nWidth;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplInitKerningPairs( ImplKernPairData* pKernPairs, long nKernPairs )
+{
+ if ( mbNewFont )
+ {
+ if ( !ImplNewFont() )
+ return;
+ }
+
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ if ( !pFontEntry->mbInitKernPairs )
+ {
+ if ( mbInitFont )
+ ImplInitFont();
+ pFontEntry->mbInitKernPairs = TRUE;
+#ifndef REMOTE_APPSERVER
+ pFontEntry->mnKernPairs = mpGraphics->GetKernPairs( 0, NULL );
+ if ( pFontEntry->mnKernPairs )
+ {
+ ImplKernInfoData* pKernInfo = new ImplKernInfoData;
+ pKernPairs = new ImplKernPairData[pFontEntry->mnKernPairs];
+ memset( pKernPairs, 0, sizeof(ImplKernPairData)*pFontEntry->mnKernPairs );
+ pFontEntry->mnKernPairs = mpGraphics->GetKernPairs( pFontEntry->mnKernPairs, pKernPairs );
+ pFontEntry->mpKernInfo = pKernInfo;
+ pFontEntry->mpKernPairs = pKernPairs;
+
+ // Wir akzeptieren erstmal nur max. 65535-Paare
+ USHORT nMaxKernPairs;
+ if ( pFontEntry->mnKernPairs > 0xFFFF )
+ nMaxKernPairs = 0xFFFF;
+ else
+ nMaxKernPairs = (USHORT)pFontEntry->mnKernPairs;
+ memset( pKernInfo->maFirstAry, 0xFF, sizeof( pKernInfo->maFirstAry ) );
+ memset( pKernInfo->maLastAry, 0, sizeof( pKernInfo->maLastAry ) );
+ for ( USHORT i = 0; i < nMaxKernPairs; i++ )
+ {
+ USHORT nFirst = pKernPairs[i].mnChar1;
+ if ( nFirst < 0xFF )
+ {
+ if ( i < pKernInfo->maFirstAry[nFirst] )
+ pKernInfo->maFirstAry[nFirst] = i;
+ pKernInfo->maLastAry[nFirst] = i;
+ }
+ }
+ }
+#else
+ // Wir arbeiten erstmal nur mit USHORT
+ if( ! pKernPairs )
+ nKernPairs = mpGraphics->GetKernPairs( &pKernPairs );
+ if ( nKernPairs )
+ {
+ ImplKernInfoData* pKernInfo = new ImplKernInfoData;
+ pFontEntry->mpKernInfo = pKernInfo;
+ pFontEntry->mpKernPairs = pKernPairs;
+
+ // Wir akzeptieren erstmal nur max. 65535-Paare
+ USHORT nMaxKernPairs;
+ if( ! pFontEntry->mnKernPairs )
+ pFontEntry->mnKernPairs = nKernPairs;
+ if ( pFontEntry->mnKernPairs > 0xFFFF )
+ nMaxKernPairs = 0xFFFF;
+ else
+ nMaxKernPairs = (USHORT)pFontEntry->mnKernPairs;
+ memset( pKernInfo->maFirstAry, 0xFF, sizeof( pKernInfo->maFirstAry ) );
+ memset( pKernInfo->maLastAry, 0, sizeof( pKernInfo->maLastAry ) );
+ for ( USHORT i = 0; i < nMaxKernPairs; i++ )
+ {
+ USHORT nFirst = pKernPairs[i].mnChar1;
+ if ( nFirst < 0xFF )
+ {
+ if ( i < pKernInfo->maFirstAry[nFirst] )
+ pKernInfo->maFirstAry[nFirst] = i;
+ pKernInfo->maLastAry[nFirst] = i;
+ }
+ }
+ }
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplCalcKerning( const sal_Unicode* pStr, xub_StrLen nLen,
+ long* pDXAry, xub_StrLen nAryLen ) const
+{
+ if ( !nLen )
+ return 0;
+
+ ImplFontEntry* pEntry = mpFontEntry;
+ ImplKernPairData* pKernPairs = pEntry->mpKernPairs;
+ ImplKernInfoData* pKernInfo = pEntry->mpKernInfo;
+ long nWidth = 0;
+
+#ifdef DBG_UTIL
+ {
+ ImplKernPairData aTestPair;
+#ifdef __LITTLEENDIAN
+ ULONG nTestComp = ((ULONG)((USHORT)0xAABB) << 16) | (USHORT)0xCCDD;
+#else
+ ULONG nTestComp = ((ULONG)((USHORT)0xCCDD) << 16) | (USHORT)0xAABB;
+#endif
+ aTestPair.mnChar1 = 0xCCDD;
+ aTestPair.mnChar2 = 0xAABB;
+ DBG_ASSERT( nTestComp == *((ULONG*)&aTestPair), "Code doesn't work in this Version" );
+ }
+#endif
+
+ for ( USHORT i = 0; i < nLen-1; i++ )
+ {
+ USHORT nIndex = (USHORT)(unsigned char)pStr[i];
+ USHORT nFirst = pKernInfo->maFirstAry[nIndex];
+ USHORT nLast = pKernInfo->maLastAry[nIndex];
+#ifdef __LITTLEENDIAN
+ ULONG nComp = ((ULONG)((USHORT)(unsigned char)pStr[i+1]) << 16) | nIndex;
+#else
+ ULONG nComp = ((ULONG)nIndex << 16) | ((USHORT)(unsigned char)pStr[i+1]);
+#endif
+ for ( USHORT j = nFirst; j <= nLast; j++ )
+ {
+ if ( nComp == *((ULONG*)&(pKernPairs[j])) )
+ {
+ long nAmount = pKernPairs[j].mnKern;
+ nWidth += nAmount;
+ if ( pDXAry )
+ {
+ for ( USHORT n = i; n < nAryLen; n++ )
+ pDXAry[n] += nAmount;
+ }
+ }
+ }
+ }
+
+ return nWidth;
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplGetTextWidth( const xub_Unicode* pStr, xub_StrLen nLen,
+ const long* pDX )
+{
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ long nFactor = pFontEntry->mnWidthFactor;
+ long nWidth = 0;
+
+ if ( nLen )
+ {
+ if ( pDX )
+ {
+ if ( nLen > 1 )
+ nWidth += pDX[nLen-2];
+ nWidth += ImplGetCharWidth( pStr[nLen-1] ) / nFactor;
+ }
+ else
+ {
+ // Bei Fixed-Fonts reicht eine Multiplikation
+ if ( pFontEntry->mbFixedFont )
+ nWidth = ImplGetCharWidth( 'A' ) * nLen;
+ else
+ {
+ const sal_Unicode* pTempStr = pStr;
+ xub_StrLen nTempLen = nLen;
+ while ( nTempLen )
+ {
+ nWidth += ImplGetCharWidth( *pTempStr );
+ nTempLen--;
+ pTempStr++;
+ }
+ }
+ nWidth /= nFactor;
+
+ // Kerning beruecksichtigen
+ if ( mbKerning )
+ nWidth += ImplCalcKerning( pStr, nLen, NULL, 0 );
+ }
+ }
+
+ return nWidth;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplRotatePos( long nOriginX, long nOriginY, long& rX, long& rY,
+ short nOrientation )
+{
+ double nRealOrientation = nOrientation*F_PI1800;
+ double nCos = cos( nRealOrientation );
+ double nSin = sin( nRealOrientation );
+
+ // Translation...
+ long nX = rX-nOriginX;
+ long nY = rY-nOriginY;
+
+ // Rotation...
+ rX = ((long) ( nCos*nX + nSin*nY )) + nOriginX;
+ rY = ((long) - ( nSin*nX - nCos*nY )) + nOriginY;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawTextRect( long nBaseX, long nBaseY,
+ long nX, long nY, long nWidth, long nHeight )
+{
+ if ( mpFontEntry->mnOrientation )
+ {
+ if ( !(mpFontEntry->mnOrientation % 900) )
+ {
+ long nX2 = nX+nWidth;
+ long nY2 = nY+nHeight;
+ ImplRotatePos( nBaseX, nBaseY, nX, nY, mpFontEntry->mnOrientation );
+ ImplRotatePos( nBaseX, nBaseY, nX2, nY2, mpFontEntry->mnOrientation );
+ nWidth = nX2-nX;
+ nHeight = nY2-nY;
+ }
+ else
+ {
+ // Da Polygone kleiner gezeichnet werden
+ nHeight++;
+ nWidth++;
+ Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
+ Polygon aPoly( aRect );
+ aPoly.Rotate( Point( nBaseX, nBaseY ), mpFontEntry->mnOrientation );
+#ifndef REMOTE_APPSERVER
+ ImplDrawPolygon( aPoly );
+#else
+ mpGraphics->DrawPolygon( aPoly );
+#endif
+ return;
+ }
+ }
+
+#ifndef REMOTE_APPSERVER
+ mpGraphics->DrawRect( nX, nY, nWidth, nHeight );
+#else
+ Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
+ mpGraphics->DrawRect( aRect );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawTextBackground( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen,
+ const long* pDXAry )
+{
+#ifndef REMOTE_APPSERVER
+ if ( mbLineColor || mbInitLineColor )
+ {
+ mpGraphics->SetLineColor();
+ mbInitLineColor = TRUE;
+ }
+ mpGraphics->SetFillColor( ImplColorToSal( GetTextFillColor() ) );
+ mbInitFillColor = TRUE;
+
+ ImplDrawTextRect( nX, nY, nX, nY-mpFontEntry->maMetric.mnAscent,
+ ImplGetTextWidth( pStr, nLen, pDXAry ),
+ mpFontEntry->mnLineHeight );
+#else
+ Color aOldLineColor = GetLineColor();
+ Color aOldFillColor = GetFillColor();
+ SetLineColor();
+ SetFillColor( GetTextFillColor() );
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ ImplDrawTextRect( nX, nY, nX, nY-mpFontEntry->maMetric.mnAscent,
+ ImplGetTextWidth( pStr, nLen, pDXAry ),
+ mpFontEntry->mnLineHeight );
+ SetLineColor( aOldLineColor );
+ SetFillColor( aOldFillColor );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::ImplGetTextBoundRect( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen,
+ const long* pDXAry )
+{
+ if( !nLen )
+ return Rectangle();
+
+ if ( mbNewFont )
+ ImplNewFont();
+
+ if ( mbInitFont )
+ ImplInitFont();
+
+ long nBaseX = nX, nBaseY = nY;
+ long nWidth = ImplGetTextWidth( pStr, nLen, pDXAry ), nHeight = mpFontEntry->mnLineHeight;
+
+ nY -= mpFontEntry->maMetric.mnAscent;
+
+ if ( mpFontEntry->mnOrientation )
+ {
+ if ( !(mpFontEntry->mnOrientation % 900) )
+ {
+ long nX2 = nX+nWidth;
+ long nY2 = nY+nHeight;
+ ImplRotatePos( nBaseX, nBaseY, nX, nY, mpFontEntry->mnOrientation );
+ ImplRotatePos( nBaseX, nBaseY, nX2, nY2, mpFontEntry->mnOrientation );
+ nWidth = nX2-nX;
+ nHeight = nY2-nY;
+ }
+ else
+ {
+ // Da Polygone kleiner gezeichnet werden
+ nHeight++;
+ nWidth++;
+ Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
+ Polygon aPoly( aRect );
+ aPoly.Rotate( Point( nBaseX, nBaseY ), mpFontEntry->mnOrientation );
+ return aPoly.GetBoundRect();
+ }
+ }
+
+ return Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplInitTextLineSize()
+{
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ long nLineHeight;
+ long nLineHeight2;
+ long nBLineHeight;
+ long nBLineHeight2;
+ long n2LineHeight;
+ long n2LineDY;
+ long n2LineDY2;
+ long nUnderlineOffset;
+ long nStrikeoutOffset;
+
+ nLineHeight = ((mpFontEntry->maMetric.mnDescent*25)+50) / 100;
+ if ( !nLineHeight )
+ nLineHeight = 1;
+ nLineHeight2 = nLineHeight / 2;
+ if ( !nLineHeight2 )
+ nLineHeight2 = 1;
+
+ nBLineHeight = ((mpFontEntry->maMetric.mnDescent*50)+50) / 100;
+ if ( nBLineHeight == nLineHeight )
+ nBLineHeight++;
+ nBLineHeight2 = nBLineHeight/2;
+ if ( !nBLineHeight2 )
+ nBLineHeight2 = 1;
+
+ n2LineHeight = ((mpFontEntry->maMetric.mnDescent*16)+50) / 100;
+ if ( !n2LineHeight )
+ n2LineHeight = 1;
+ n2LineDY = n2LineHeight;
+ if ( n2LineDY <= 0 )
+ n2LineDY = 1;
+ n2LineDY2 = n2LineDY/2;
+ if ( !n2LineDY2 )
+ n2LineDY2 = 1;
+
+ nUnderlineOffset = mpFontEntry->maMetric.mnDescent/2 + 1;
+ nStrikeoutOffset = -((mpFontEntry->maMetric.mnAscent-mpFontEntry->maMetric.mnLeading)/3);
+
+ if ( !pFontEntry->maMetric.mnUnderlineSize )
+ {
+ pFontEntry->maMetric.mnUnderlineSize = nLineHeight;
+ pFontEntry->maMetric.mnUnderlineOffset = nUnderlineOffset - nLineHeight2;
+ }
+ if ( !pFontEntry->maMetric.mnBUnderlineSize )
+ {
+ pFontEntry->maMetric.mnBUnderlineSize = nBLineHeight;
+ pFontEntry->maMetric.mnBUnderlineOffset = nUnderlineOffset - nBLineHeight2;
+ }
+ if ( !pFontEntry->maMetric.mnDUnderlineSize )
+ {
+ pFontEntry->maMetric.mnDUnderlineSize = n2LineHeight;
+ pFontEntry->maMetric.mnDUnderlineOffset1 = nUnderlineOffset - n2LineDY2 - n2LineHeight;
+ pFontEntry->maMetric.mnDUnderlineOffset2 = pFontEntry->maMetric.mnDUnderlineOffset1 + n2LineDY + n2LineHeight;
+ }
+ if ( !pFontEntry->maMetric.mnWUnderlineSize )
+ {
+ if ( mpFontEntry->maMetric.mnDescent < 6 )
+ {
+ if ( (mpFontEntry->maMetric.mnDescent == 1) ||
+ (mpFontEntry->maMetric.mnDescent == 2) )
+ pFontEntry->maMetric.mnWUnderlineSize = mpFontEntry->maMetric.mnDescent;
+ else
+ pFontEntry->maMetric.mnWUnderlineSize = 3;
+ }
+ else
+ pFontEntry->maMetric.mnWUnderlineSize = ((mpFontEntry->maMetric.mnDescent*50)+50) / 100;
+ pFontEntry->maMetric.mnWUnderlineOffset = nUnderlineOffset;
+ }
+ if ( !pFontEntry->maMetric.mnStrikeoutSize )
+ {
+ pFontEntry->maMetric.mnStrikeoutSize = nLineHeight;
+ pFontEntry->maMetric.mnStrikeoutOffset = nStrikeoutOffset - nLineHeight2;
+ }
+ if ( !pFontEntry->maMetric.mnBStrikeoutSize )
+ {
+ pFontEntry->maMetric.mnBStrikeoutSize = nBLineHeight;
+ pFontEntry->maMetric.mnBStrikeoutOffset = nStrikeoutOffset - nBLineHeight2;
+ }
+ if ( !pFontEntry->maMetric.mnDStrikeoutSize )
+ {
+ pFontEntry->maMetric.mnDStrikeoutSize = n2LineHeight;
+ pFontEntry->maMetric.mnDStrikeoutOffset1 = nStrikeoutOffset - n2LineDY2 - n2LineHeight;
+ pFontEntry->maMetric.mnDStrikeoutOffset2 = pFontEntry->maMetric.mnDStrikeoutOffset1 + n2LineDY + n2LineHeight;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawWavePixel( long nOriginX, long nOriginY,
+ long nCurX, long nCurY,
+ short nOrientation,
+#ifndef REMOTE_APPSERVER
+ SalGraphics* pGraphics,
+#else
+ ImplServerGraphics* pGraphics,
+#endif
+ BOOL bDrawPixAsRect,
+ long nPixWidth, long nPixHeight )
+{
+ if ( nOrientation )
+ ImplRotatePos( nOriginX, nOriginY, nCurX, nCurY, nOrientation );
+
+ if ( bDrawPixAsRect )
+ {
+#ifndef REMOTE_APPSERVER
+ pGraphics->DrawRect( nCurX, nCurY, nPixWidth, nPixHeight );
+#else
+ Point aPos( nCurX, nCurY );
+ Size aSize( nPixWidth, nPixHeight );
+ Rectangle aRect( aPos, aSize );
+ pGraphics->DrawRect( aRect );
+#endif
+ }
+ else
+ {
+#ifndef REMOTE_APPSERVER
+ pGraphics->DrawPixel( nCurX, nCurY );
+#else
+ Point aPos( nCurX, nCurY );
+ pGraphics->DrawPixel( aPos );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawWaveLine( long nBaseX, long nBaseY,
+ long nStartX, long nStartY,
+ long nWidth, long nHeight,
+ long nLineWidth, short nOrientation,
+ const Color& rColor )
+{
+ if ( !nHeight )
+ return;
+
+ // Bei Hoehe von 1 Pixel reicht es, eine Linie auszugeben
+ if ( (nLineWidth == 1) && (nHeight == 1) )
+ {
+#ifndef REMOTE_APPSERVER
+ mpGraphics->SetLineColor( ImplColorToSal( rColor ) );
+ mbInitLineColor = TRUE;
+#else
+ Color aOldLineColor = GetLineColor();
+ SetLineColor( rColor );
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+#endif
+
+ long nEndX = nStartX+nWidth;
+ long nEndY = nStartY;
+ if ( nOrientation )
+ {
+ ImplRotatePos( nBaseX, nBaseY, nStartX, nStartY, nOrientation );
+ ImplRotatePos( nBaseX, nBaseY, nEndX, nEndY, nOrientation );
+ }
+#ifndef REMOTE_APPSERVER
+ mpGraphics->DrawLine( nStartX, nStartY, nEndX, nEndY );
+#else
+ mpGraphics->DrawLine( Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
+#endif
+
+#ifdef REMOTE_APPSERVER
+ SetLineColor( aOldLineColor );
+#endif
+ }
+ else
+ {
+ long nCurX = nStartX;
+ long nCurY = nStartY;
+ long nDiffX = 2;
+ long nDiffY = nHeight-1;
+ long nCount = nWidth;
+ long nOffY = -1;
+ long nFreq;
+ long i;
+ long nPixWidth;
+ long nPixHeight;
+ BOOL bDrawPixAsRect;
+#ifdef REMOTE_APPSERVER
+ Color aOldLineColor = GetLineColor();
+ Color aOldFillColor = GetFillColor();
+#endif
+ // Auf Druckern die Pixel per DrawRect() ausgeben
+ if ( (GetOutDevType() == OUTDEV_PRINTER) || (nLineWidth > 1) )
+ {
+#ifndef REMOTE_APPSERVER
+ if ( mbLineColor || mbInitLineColor )
+ {
+ mpGraphics->SetLineColor();
+ mbInitLineColor = TRUE;
+ }
+ mpGraphics->SetFillColor( ImplColorToSal( rColor ) );
+ mbInitFillColor = TRUE;
+#else
+ SetLineColor();
+ SetFillColor( rColor );
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+#endif
+ bDrawPixAsRect = TRUE;
+ nPixWidth = nLineWidth;
+ nPixHeight = ((nLineWidth*mnDPIX)+(mnDPIY/2))/mnDPIY;
+ }
+ else
+ {
+#ifndef REMOTE_APPSERVER
+ mpGraphics->SetLineColor( ImplColorToSal( rColor ) );
+ mbInitLineColor = TRUE;
+#else
+ Color aOldLineColor = GetLineColor();
+ SetLineColor( rColor );
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+#endif
+ nPixWidth = 1;
+ nPixHeight = 1;
+ bDrawPixAsRect = FALSE;
+ }
+
+ if ( !nDiffY )
+ {
+ while ( nWidth )
+ {
+ ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
+ mpGraphics,
+ bDrawPixAsRect, nPixWidth, nPixHeight );
+ nCurX++;
+ nWidth--;
+ }
+ }
+ else
+ {
+ nCurY += nDiffY;
+ nFreq = nCount / (nDiffX+nDiffY);
+ while ( nFreq-- )
+ {
+ for( i = nDiffY; i; --i )
+ {
+ ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
+ mpGraphics,
+ bDrawPixAsRect, nPixWidth, nPixHeight );
+ nCurX++;
+ nCurY += nOffY;
+ }
+ for( i = nDiffX; i; --i )
+ {
+ ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
+ mpGraphics,
+ bDrawPixAsRect, nPixWidth, nPixHeight );
+ nCurX++;
+ }
+ nOffY = -nOffY;
+ }
+ nFreq = nCount % (nDiffX+nDiffY);
+ if ( nFreq )
+ {
+ for( i = nDiffY; i && nFreq; --i, --nFreq )
+ {
+ ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
+ mpGraphics,
+ bDrawPixAsRect, nPixWidth, nPixHeight );
+ nCurX++;
+ nCurY += nOffY;
+ }
+ for( i = nDiffX; i && nFreq; --i, --nFreq )
+ {
+ ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
+ mpGraphics,
+ bDrawPixAsRect, nPixWidth, nPixHeight );
+ nCurX++;
+ }
+ }
+ }
+
+#ifdef REMOTE_APPSERVER
+ SetLineColor( aOldLineColor );
+ SetFillColor( aOldFillColor );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawTextLine( long nBaseX,
+ long nX, long nY, long nWidth,
+ FontStrikeout eStrikeout,
+ FontUnderline eUnderline )
+{
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ Color aTextLineColor = GetTextLineColor();
+ long nBaseY = nY;
+ long nLineHeight;
+ long nLinePos;
+ long nLinePos2;
+ long nLeft;
+ BOOL bNormalLines = TRUE;
+
+ if ( !IsTextLineColor() )
+ aTextLineColor = GetTextColor();
+
+ if ( (eUnderline == UNDERLINE_SMALLWAVE) ||
+ (eUnderline == UNDERLINE_WAVE) ||
+ (eUnderline == UNDERLINE_DOUBLEWAVE) ||
+ (eUnderline == UNDERLINE_BOLDWAVE) )
+ {
+ if ( !pFontEntry->maMetric.mnWUnderlineSize )
+ ImplInitTextLineSize();
+ nLineHeight = pFontEntry->maMetric.mnWUnderlineSize;
+ if ( (eUnderline == UNDERLINE_SMALLWAVE) &&
+ (nLineHeight > 3) )
+ nLineHeight = 3;
+ long nLineWidth = (mnDPIX/300);
+ if ( !nLineWidth )
+ nLineWidth = 1;
+ if ( eUnderline == UNDERLINE_BOLDWAVE )
+ nLineWidth *= 2;
+ nLinePos = nY + pFontEntry->maMetric.mnWUnderlineOffset - (nLineHeight / 2);
+ long nLineWidthHeight = ((nLineWidth*mnDPIX)+(mnDPIY/2))/mnDPIY;
+ if ( eUnderline == UNDERLINE_DOUBLEWAVE )
+ {
+ long nOrgLineHeight = nLineHeight;
+ nLineHeight /= 3;
+ if ( nLineHeight < 2 )
+ {
+ if ( nOrgLineHeight > 1 )
+ nLineHeight = 2;
+ else
+ nLineHeight = 1;
+ }
+ long nLineDY = nOrgLineHeight-(nLineHeight*2);
+ if ( nLineDY < nLineWidthHeight )
+ nLineDY = nLineWidthHeight;
+ long nLineDY2 = nLineDY/2;
+ if ( !nLineDY2 )
+ nLineDY2 = 1;
+ nLinePos -= nLineWidthHeight-nLineDY2;
+ ImplDrawWaveLine( nBaseX, nBaseY, nX, nLinePos, nWidth, nLineHeight,
+ nLineWidth, mpFontEntry->mnOrientation, aTextLineColor );
+ nLinePos += nLineWidthHeight+nLineDY;
+ ImplDrawWaveLine( nBaseX, nBaseY, nX, nLinePos, nWidth, nLineHeight,
+ nLineWidth, mpFontEntry->mnOrientation, aTextLineColor );
+ }
+ else
+ {
+ nLinePos -= nLineWidthHeight/2;
+ ImplDrawWaveLine( nBaseX, nBaseY, nX, nLinePos, nWidth, nLineHeight,
+ nLineWidth, mpFontEntry->mnOrientation, aTextLineColor );
+ }
+
+ if ( (eStrikeout == STRIKEOUT_NONE) ||
+ (eStrikeout == STRIKEOUT_DONTKNOW) )
+ bNormalLines = FALSE;
+ }
+
+ if ( bNormalLines &&
+ ((eStrikeout == STRIKEOUT_SLASH) || (eStrikeout == STRIKEOUT_X)) )
+ {
+ BOOL bOldMap = IsMapModeEnabled();
+ EnableMapMode( FALSE );
+ Color aOldColor = GetTextColor();
+ SetTextColor( aTextLineColor );
+ ImplInitTextColor();
+ xub_Unicode c;
+ if ( eStrikeout == STRIKEOUT_SLASH )
+ c = '/';
+ else /* ( eStrikeout == STRIKEOUT_X ) */
+ c = 'X';
+ // Strikeout-String zusammenbauen
+ XubString aStrikeoutText( c );
+ aStrikeoutText += aStrikeoutText.GetChar( 0 );
+ long nStrikeoutWidth = GetTextWidth( aStrikeoutText );
+ long nChars = nWidth/(nStrikeoutWidth/2);
+ aStrikeoutText.Fill( (USHORT)(nChars+1), c );
+ // String solange kuerzen, bis er nicht allzuweit uebersteht
+ long nMaxWidth = nStrikeoutWidth/4;
+ if ( nMaxWidth < 2 )
+ nMaxWidth = 2;
+ nMaxWidth += nWidth;
+ long nFullStrikeoutWidth = GetTextWidth( aStrikeoutText );
+ while ( (nFullStrikeoutWidth > nMaxWidth) && aStrikeoutText.Len() )
+ {
+ aStrikeoutText.Erase( aStrikeoutText.Len()-1 );
+ nFullStrikeoutWidth = GetTextWidth( aStrikeoutText );
+ }
+ if ( mpFontEntry->mnOrientation )
+ ImplRotatePos( nBaseX, nBaseY, nX, nY, mpFontEntry->mnOrientation );
+ ImplDrawTextDirect( nX, nY,
+ aStrikeoutText.GetBuffer(), aStrikeoutText.Len(),
+ NULL, FALSE );
+ SetTextColor( aOldColor );
+ ImplInitTextColor();
+ EnableMapMode( bOldMap );
+
+ if ( (eUnderline == UNDERLINE_NONE) ||
+ (eUnderline == UNDERLINE_DONTKNOW) ||
+ (eUnderline == UNDERLINE_SMALLWAVE) ||
+ (eUnderline == UNDERLINE_WAVE) ||
+ (eUnderline == UNDERLINE_DOUBLEWAVE) ||
+ (eUnderline == UNDERLINE_BOLDWAVE) )
+ bNormalLines = FALSE;
+ }
+
+ if ( bNormalLines )
+ {
+#ifndef REMOTE_APPSERVER
+ if ( mbLineColor || mbInitLineColor )
+ {
+ mpGraphics->SetLineColor();
+ mbInitLineColor = TRUE;
+ }
+ mpGraphics->SetFillColor( ImplColorToSal( aTextLineColor ) );
+ mbInitFillColor = TRUE;
+#else
+ Color aOldLineColor = GetLineColor();
+ Color aOldFillColor = GetFillColor();
+ SetLineColor();
+ SetFillColor( aTextLineColor );
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+#endif
+
+ if ( eUnderline > UNDERLINE_LAST )
+ eUnderline = UNDERLINE_SINGLE;
+
+ if ( (eUnderline == UNDERLINE_SINGLE) ||
+ (eUnderline == UNDERLINE_DOTTED) ||
+ (eUnderline == UNDERLINE_DASH) ||
+ (eUnderline == UNDERLINE_LONGDASH) ||
+ (eUnderline == UNDERLINE_DASHDOT) ||
+ (eUnderline == UNDERLINE_DASHDOTDOT) )
+ {
+ if ( !pFontEntry->maMetric.mnUnderlineSize )
+ ImplInitTextLineSize();
+ nLineHeight = pFontEntry->maMetric.mnUnderlineSize;
+ nLinePos = nY + pFontEntry->maMetric.mnUnderlineOffset;
+ }
+ else if ( (eUnderline == UNDERLINE_BOLD) ||
+ (eUnderline == UNDERLINE_BOLDDOTTED) ||
+ (eUnderline == UNDERLINE_BOLDDASH) ||
+ (eUnderline == UNDERLINE_BOLDLONGDASH) ||
+ (eUnderline == UNDERLINE_BOLDDASHDOT) ||
+ (eUnderline == UNDERLINE_BOLDDASHDOTDOT) )
+ {
+ if ( !pFontEntry->maMetric.mnBUnderlineSize )
+ ImplInitTextLineSize();
+ nLineHeight = pFontEntry->maMetric.mnBUnderlineSize;
+ nLinePos = nY + pFontEntry->maMetric.mnBUnderlineOffset;
+ }
+ else if ( eUnderline == UNDERLINE_DOUBLE )
+ {
+ if ( !pFontEntry->maMetric.mnDUnderlineSize )
+ ImplInitTextLineSize();
+ nLineHeight = pFontEntry->maMetric.mnDUnderlineSize;
+ nLinePos = nY + pFontEntry->maMetric.mnDUnderlineOffset1;
+ nLinePos2 = nY + pFontEntry->maMetric.mnDUnderlineOffset2;
+ }
+ else
+ nLineHeight = 0;
+
+ if ( nLineHeight )
+ {
+ nLeft = nX;
+
+ if ( (eUnderline == UNDERLINE_SINGLE) ||
+ (eUnderline == UNDERLINE_BOLD) )
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nWidth, nLineHeight );
+ else if ( eUnderline == UNDERLINE_DOUBLE )
+ {
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nWidth, nLineHeight );
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos2, nWidth, nLineHeight );
+ }
+ else if ( (eUnderline == UNDERLINE_DOTTED) ||
+ (eUnderline == UNDERLINE_BOLDDOTTED) )
+ {
+ long nDotWidth = nLineHeight*mnDPIY;
+ nDotWidth += mnDPIY/2;
+ nDotWidth /= mnDPIY;
+ long nTempWidth = nDotWidth;
+ long nEnd = nLeft+nWidth;
+ while ( nLeft < nEnd )
+ {
+ if ( nLeft+nTempWidth > nEnd )
+ nTempWidth = nEnd-nLeft;
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempWidth, nLineHeight );
+ nLeft += nDotWidth*2;
+ }
+ }
+ else if ( (eUnderline == UNDERLINE_DASH) ||
+ (eUnderline == UNDERLINE_LONGDASH) ||
+ (eUnderline == UNDERLINE_BOLDDASH) ||
+ (eUnderline == UNDERLINE_BOLDLONGDASH) )
+ {
+ long nDotWidth = nLineHeight*mnDPIY;
+ nDotWidth += mnDPIY/2;
+ nDotWidth /= mnDPIY;
+ long nMinDashWidth;
+ long nMinSpaceWidth;
+ long nSpaceWidth;
+ long nDashWidth;
+ if ( (eUnderline == UNDERLINE_LONGDASH) ||
+ (eUnderline == UNDERLINE_BOLDLONGDASH) )
+ {
+ nMinDashWidth = nDotWidth*6;
+ nMinSpaceWidth = nDotWidth*2;
+ nDashWidth = 200;
+ nSpaceWidth = 100;
+ }
+ else
+ {
+ nMinDashWidth = nDotWidth*4;
+ nMinSpaceWidth = (nDotWidth*150)/100;
+ nDashWidth = 100;
+ nSpaceWidth = 50;
+ }
+ nDashWidth = ((nDashWidth*mnDPIX)+1270)/2540;
+ nSpaceWidth = ((nSpaceWidth*mnDPIX)+1270)/2540;
+ // DashWidth wird gegebenenfalls verbreitert, wenn
+ // die dicke der Linie im Verhaeltnis zur Laenge
+ // zu dick wird
+ if ( nDashWidth < nMinDashWidth )
+ nDashWidth = nMinDashWidth;
+ if ( nSpaceWidth < nMinSpaceWidth )
+ nSpaceWidth = nMinSpaceWidth;
+ long nTempWidth = nDashWidth;
+ long nEnd = nLeft+nWidth;
+ while ( nLeft < nEnd )
+ {
+ if ( nLeft+nTempWidth > nEnd )
+ nTempWidth = nEnd-nLeft;
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempWidth, nLineHeight );
+ nLeft += nDashWidth+nSpaceWidth;
+ }
+ }
+ else if ( (eUnderline == UNDERLINE_DASHDOT) ||
+ (eUnderline == UNDERLINE_BOLDDASHDOT) )
+ {
+ long nDotWidth = nLineHeight*mnDPIY;
+ nDotWidth += mnDPIY/2;
+ nDotWidth /= mnDPIY;
+ long nDashWidth = ((100*mnDPIX)+1270)/2540;
+ long nMinDashWidth = nDotWidth*4;
+ // DashWidth wird gegebenenfalls verbreitert, wenn
+ // die dicke der Linie im Verhaeltnis zur Laenge
+ // zu dick wird
+ if ( nDashWidth < nMinDashWidth )
+ nDashWidth = nMinDashWidth;
+ long nTempDotWidth = nDotWidth;
+ long nTempDashWidth = nDashWidth;
+ long nEnd = nLeft+nWidth;
+ while ( nLeft < nEnd )
+ {
+ if ( nLeft+nTempDotWidth > nEnd )
+ nTempDotWidth = nEnd-nLeft;
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDotWidth, nLineHeight );
+ nLeft += nDotWidth*2;
+ if ( nLeft > nEnd )
+ break;
+ if ( nLeft+nTempDashWidth > nEnd )
+ nTempDashWidth = nEnd-nLeft;
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDashWidth, nLineHeight );
+ nLeft += nDashWidth+nDotWidth;
+ }
+ }
+ else if ( (eUnderline == UNDERLINE_DASHDOTDOT) ||
+ (eUnderline == UNDERLINE_BOLDDASHDOTDOT) )
+ {
+ long nDotWidth = nLineHeight*mnDPIY;
+ nDotWidth += mnDPIY/2;
+ nDotWidth /= mnDPIY;
+ long nDashWidth = ((100*mnDPIX)+1270)/2540;
+ long nMinDashWidth = nDotWidth*4;
+ // DashWidth wird gegebenenfalls verbreitert, wenn
+ // die dicke der Linie im Verhaeltnis zur Laenge
+ // zu dick wird
+ if ( nDashWidth < nMinDashWidth )
+ nDashWidth = nMinDashWidth;
+ long nTempDotWidth = nDotWidth;
+ long nTempDashWidth = nDashWidth;
+ long nEnd = nLeft+nWidth;
+ while ( nLeft < nEnd )
+ {
+ if ( nLeft+nTempDotWidth > nEnd )
+ nTempDotWidth = nEnd-nLeft;
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDotWidth, nLineHeight );
+ nLeft += nDotWidth*2;
+ if ( nLeft > nEnd )
+ break;
+ if ( nLeft+nTempDotWidth > nEnd )
+ nTempDotWidth = nEnd-nLeft;
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDotWidth, nLineHeight );
+ nLeft += nDotWidth*2;
+ if ( nLeft > nEnd )
+ break;
+ if ( nLeft+nTempDashWidth > nEnd )
+ nTempDashWidth = nEnd-nLeft;
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDashWidth, nLineHeight );
+ nLeft += nDashWidth+nDotWidth;
+ }
+ }
+ }
+
+ if ( eStrikeout > STRIKEOUT_LAST )
+ eStrikeout = STRIKEOUT_SINGLE;
+
+ if ( eStrikeout == STRIKEOUT_SINGLE )
+ {
+ if ( !pFontEntry->maMetric.mnStrikeoutSize )
+ ImplInitTextLineSize();
+ nLineHeight = pFontEntry->maMetric.mnStrikeoutSize;
+ nLinePos = nY + pFontEntry->maMetric.mnStrikeoutOffset;
+ }
+ else if ( eStrikeout == STRIKEOUT_BOLD )
+ {
+ if ( !pFontEntry->maMetric.mnBStrikeoutSize )
+ ImplInitTextLineSize();
+ nLineHeight = pFontEntry->maMetric.mnBStrikeoutSize;
+ nLinePos = nY + pFontEntry->maMetric.mnBStrikeoutOffset;
+ }
+ else if ( eStrikeout == STRIKEOUT_DOUBLE )
+ {
+ if ( !pFontEntry->maMetric.mnDStrikeoutSize )
+ ImplInitTextLineSize();
+ nLineHeight = pFontEntry->maMetric.mnDStrikeoutSize;
+ nLinePos = nY + pFontEntry->maMetric.mnDStrikeoutOffset1;
+ nLinePos2 = nY + pFontEntry->maMetric.mnDStrikeoutOffset2;
+ }
+ else
+ nLineHeight = 0;
+
+ if ( nLineHeight )
+ {
+ nLeft = nX;
+
+ if ( (eStrikeout == STRIKEOUT_SINGLE) ||
+ (eStrikeout == STRIKEOUT_BOLD) )
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nWidth, nLineHeight );
+ else if ( eStrikeout == STRIKEOUT_DOUBLE )
+ {
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nWidth, nLineHeight );
+ ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos2, nWidth, nLineHeight );
+ }
+ }
+
+#ifdef REMOTE_APPSERVER
+ SetLineColor( aOldLineColor );
+ SetFillColor( aOldFillColor );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawTextLines( long nX, long nY,
+ const sal_Unicode* pStr, xub_StrLen nLen,
+ const long* pDXAry,
+ FontStrikeout eStrikeout,
+ FontUnderline eUnderline,
+ BOOL bWordLine )
+{
+ if ( bWordLine )
+ {
+ ::rtl::OUString aText( pStr, nLen );
+ uno::Reference < text::XBreakIterator > xBI = vcl::unohelper::CreateBreakIterator();
+ uno::Reference< linguistic::XHyphenator > xHyph;
+ text::LineBreakHyphenationOptions aHyphOptions( xHyph, 1 );
+ text::LineBreakUserOptions aUserOptions;
+
+ text::Boundary aBoundary = xBI->getWordBoundary( aText, 0, GetSettings().GetLocale(), text::WordType::ANYWORD_IGNOREWHITESPACES, TRUE );
+ while ( ( aBoundary.startPos >= 0 ) && ( aBoundary.startPos < nLen ) )
+ {
+ xub_StrLen nWordEnd = Max( (xub_StrLen)aBoundary.endPos, nLen );
+ long nTempX = ImplGetTextWidth( pStr, aBoundary.startPos, pDXAry );
+ long nWidth = ImplGetTextWidth( pStr+aBoundary.startPos, aBoundary.endPos-aBoundary.startPos, pDXAry );
+ ImplDrawTextLine( nX, nX + nTempX, nY, nWidth, eStrikeout, eUnderline );
+ aBoundary = xBI->nextWord( aText, aBoundary.endPos, GetSettings().GetLocale(), text::WordType::ANYWORD_IGNOREWHITESPACES );
+ }
+ }
+ else
+ {
+ ImplDrawTextLine( nX, nX, nY, ImplGetTextWidth( pStr, nLen, pDXAry ), eStrikeout, eUnderline );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawMnemonicLine( long nX, long nY, xub_Unicode c )
+{
+ ImplDrawTextLines( nX, nY, &c, 1, NULL, STRIKEOUT_NONE, UNDERLINE_SINGLE, FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL OutputDevice::ImplDrawRotateText( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen,
+ const long* pDXAry )
+{
+ if ( !mpOutDevData )
+ ImplInitOutDevData();
+ if ( !mpOutDevData->mpRotateDev )
+ mpOutDevData->mpRotateDev = new VirtualDevice( *this, 1 );
+ VirtualDevice* pVDev = mpOutDevData->mpRotateDev;
+ long nWidth = ImplGetTextWidth( pStr, nLen, pDXAry );
+ long nHeight = mpFontEntry->mnLineHeight;
+ Size aSize( nWidth, nHeight );
+
+ if ( pVDev->SetOutputSizePixel( aSize ) )
+ {
+ Font aFont( GetFont() );
+ Bitmap aBmp;
+ long nOff;
+
+ nX -= mnTextOffX;
+ nY -= mnTextOffY;
+ if ( GetTextAlign() == ALIGN_TOP )
+ {
+ nOff = 0L;
+ nY += mpFontEntry->maMetric.mnAscent;
+ }
+ else if ( GetTextAlign() == ALIGN_BOTTOM )
+ {
+ nOff = mpFontEntry->maMetric.mnAscent;
+ nY += -mpFontEntry->maMetric.mnDescent;
+ }
+ else
+ nOff = mpFontEntry->maMetric.mnAscent;
+
+ aFont.SetShadow( FALSE );
+ aFont.SetOutline( FALSE );
+ aFont.SetOrientation( 0 );
+ aFont.SetSize( Size( mpFontEntry->maFontSelData.mnWidth, mpFontEntry->maFontSelData.mnHeight ) );
+ pVDev->SetFont( aFont );
+ // Da Farben und Alignment noch im Font haengen, muessen diese jedesmal
+ // gesetzt werden
+ pVDev->SetTextAlign( ALIGN_TOP );
+ pVDev->SetTextColor( Color( COL_BLACK ) );
+ pVDev->SetTextFillColor();
+ pVDev->ImplNewFont();
+ pVDev->ImplInitFont();
+ pVDev->ImplInitTextColor();
+ pVDev->ImplDrawText( 0, 0, pStr, nLen, pDXAry );
+
+ aBmp = pVDev->GetBitmap( Point(), aSize );
+ if ( !!aBmp && aBmp.Rotate( mpFontEntry->mnOwnOrientation, COL_WHITE ) )
+ {
+ Point aTempPoint;
+ Polygon aPoly( Rectangle( aTempPoint, aSize ) );
+ long nOldOffX = mnOutOffX;
+ long nOldOffY = mnOutOffY;
+ BOOL bOldMap = mbMap;
+
+ aTempPoint.Y() = nOff;
+ aPoly.Rotate( aTempPoint, mpFontEntry->mnOwnOrientation );
+ const Rectangle aBound( aPoly.GetBoundRect() );
+
+ mnOutOffX = 0L;
+ mnOutOffY = 0L;
+ mbMap = FALSE;
+
+ DrawMask( Point( nX + aBound.Left(),
+ nY + aBound.Top() - mpFontEntry->maMetric.mnAscent ),
+ aBmp, GetTextColor() );
+
+ mnOutOffX = nOldOffX;
+ mnOutOffY = nOldOffY;
+ mbMap = bOldMap;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawTextDirect( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen,
+ const long* pDXAry,
+ BOOL bTextLines )
+{
+ BOOL bDraw = FALSE;
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ if ( pFontEntry->mnOwnOrientation )
+ bDraw = ImplDrawRotateText( nX, nY, pStr, nLen, pDXAry );
+ if ( !bDraw )
+ {
+ if ( !pDXAry )
+ {
+#ifndef REMOTE_APPSERVER
+ if ( pFontEntry->mnSetFontFlags & SAL_SETFONT_USEDRAWTEXTARRAY )
+ {
+ long* pCharWidthAry = pFontEntry->maWidthAry;
+ long nFactor = pFontEntry->mnWidthFactor;
+ long nOffset = 0;
+ long aStackAry[128];
+ long* pTempDXAry = (long*)ImplGetStackBuffer( sizeof(long)*(nLen-1), aStackAry, sizeof( aStackAry ) );
+ for ( USHORT i = 0; i < nLen-1; i++ )
+ {
+ nOffset += ImplGetCharWidth( pStr[i] );
+ pTempDXAry[i] = nOffset / nFactor;
+ }
+ mpGraphics->DrawTextArray( nX, nY, pStr, nLen, pTempDXAry );
+ ImplReleaseStackBuffer( pTempDXAry, aStackAry );
+ }
+ else
+#endif
+ mpGraphics->DrawText( nX, nY, pStr, nLen );
+ }
+ else
+ {
+#ifndef REMOTE_APPSERVER
+ if ( pFontEntry->mnSetFontFlags & SAL_SETFONT_USEDRAWTEXT )
+ {
+ long* pCharWidthAry = pFontEntry->maWidthAry;
+ long nFactor = pFontEntry->mnWidthFactor;
+ long nOffset = 0;
+ long nDiff;
+ long nTempX = nX;
+ const sal_Unicode* pTempStr = pStr;
+ xub_StrLen nCombineChars = 1;
+ for ( xub_StrLen i = 0; i < nLen-1; i++ )
+ {
+ nOffset += ImplGetCharWidth( pStr[i] );
+ nDiff = (nOffset/nFactor) - pDXAry[i];
+ if ( (nDiff < -1) || (nDiff > 0) )
+ {
+ mpGraphics->DrawText( nTempX, nY, pTempStr, nCombineChars );
+ nTempX = nX+pDXAry[i];
+ nOffset = pDXAry[i]*nFactor;
+ pTempStr += nCombineChars;
+ nCombineChars = 1;
+ }
+ else
+ nCombineChars++;
+ }
+ mpGraphics->DrawText( nTempX, nY, pTempStr, nCombineChars );
+ }
+ else
+#endif
+ mpGraphics->DrawTextArray( nX, nY, pStr, nLen, pDXAry );
+ }
+
+ if ( bTextLines )
+ {
+ ImplDrawTextLines( nX, nY, pStr, nLen, pDXAry,
+ maFont.GetStrikeout(),
+ maFont.GetUnderline(),
+ maFont.IsWordLineMode() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawSpecialText( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen,
+ const long* pDXAry )
+{
+ Color aOldColor = GetTextColor();
+ Color aOldTextLineColor = GetTextLineColor();
+
+ if ( maFont.IsShadow() )
+ {
+ long nOff = 1 + ((mpFontEntry->mnLineHeight-24)/24);
+ if ( maFont.IsOutline() )
+ nOff++;
+ SetTextLineColor();
+ if ( GetTextColor().GetColor() == COL_BLACK )
+ SetTextColor( Color( COL_LIGHTGRAY ) );
+ else
+ SetTextColor( Color( COL_BLACK ) );
+ ImplInitTextColor();
+ ImplDrawTextDirect( nX+nOff, nY+nOff, pStr, nLen, pDXAry, mbTextLines );
+ SetTextColor( aOldColor );
+ SetTextLineColor( aOldTextLineColor );
+ ImplInitTextColor();
+
+ if ( !maFont.IsOutline() )
+ ImplDrawTextDirect( nX, nY, pStr, nLen, pDXAry, mbTextLines );
+ }
+
+ if ( maFont.IsOutline() )
+ {
+ ImplDrawTextDirect( nX-1, nY+1, pStr, nLen, pDXAry, mbTextLines );
+ ImplDrawTextDirect( nX, nY+1, pStr, nLen, pDXAry, mbTextLines );
+ ImplDrawTextDirect( nX+1, nY+1, pStr, nLen, pDXAry, mbTextLines );
+ ImplDrawTextDirect( nX-1, nY, pStr, nLen, pDXAry, mbTextLines );
+ ImplDrawTextDirect( nX+1, nY, pStr, nLen, pDXAry, mbTextLines );
+ ImplDrawTextDirect( nX-1, nY-1, pStr, nLen, pDXAry, mbTextLines );
+ ImplDrawTextDirect( nX, nY-1, pStr, nLen, pDXAry, mbTextLines );
+ ImplDrawTextDirect( nX+1, nY-1, pStr, nLen, pDXAry, mbTextLines );
+
+ SetTextColor( Color( COL_WHITE ) );
+ SetTextLineColor( Color( COL_WHITE ) );
+ ImplInitTextColor();
+ ImplDrawTextDirect( nX, nY, pStr, nLen, pDXAry, mbTextLines );
+ SetTextColor( aOldColor );
+ SetTextLineColor( aOldTextLineColor );
+ ImplInitTextColor();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawText( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen, const long* pDXAry )
+{
+ nX += mnTextOffX;
+ nY += mnTextOffY;
+
+ if ( IsTextFillColor() )
+ ImplDrawTextBackground( nX, nY, pStr, nLen, pDXAry );
+
+ if ( mbTextSpecial )
+ ImplDrawSpecialText( nX, nY, pStr, nLen, pDXAry );
+ else
+ ImplDrawTextDirect( nX, nY, pStr, nLen, pDXAry, mbTextLines );
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplFillDXAry( long* pDXAry,
+ const xub_Unicode* pStr, xub_StrLen nLen, long nWidth )
+{
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ long* pCharWidthAry = pFontEntry->maWidthAry;
+ long nFactor = pFontEntry->mnWidthFactor;
+
+ // Breiten-Array fuer errechnete Werte mit den Breiten der einzelnen
+ // Character fuellen
+ xub_StrLen i;
+ long nSum = 0;
+ for ( i = 0; i < nLen; i++ )
+ {
+ // Characterbreiten ueber Array holen
+ nSum += ImplGetCharWidth( pStr[i] );
+ pDXAry[i] = nSum / nFactor;
+ }
+ nSum /= nFactor;
+
+ // Differenz zwischen Soll- und Ist-Laenge errechnen
+ // Zusaetzliche Pixel per Character errechnen
+ // Anzahl der zusaetzlich verbliebenen Pixel errechnen
+ long nDelta = (long)nWidth - nSum;
+ long nDeltaPerChar = 0;
+ long nDeltaRest = 0;
+ if ( nLen > 1 )
+ {
+ nDeltaPerChar = nDelta / (long)(nLen-1);
+ nDeltaRest = nDelta % (long)(nLen-1);
+ }
+ long nDeltaRestAbs = Abs( nDeltaRest );
+
+ long nErrorSum = nDeltaRestAbs;
+ long nDeltaSum = 0;
+ for ( i = 0; i < nLen-1; i++, nErrorSum += nDeltaRestAbs )
+ {
+ nDeltaSum += nDeltaPerChar;
+ if ( nErrorSum >= nLen-1 )
+ {
+ nErrorSum -= nLen-1;
+ if ( nDeltaRest > 0 )
+ nDeltaSum++;
+ else if ( nDeltaRest < 0 )
+ nDeltaSum--;
+ }
+ pDXAry[i] += nDeltaSum;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo,
+ long nWidth, const XubString& rStr,
+ USHORT nStyle ) const
+{
+ DBG_ASSERT( nWidth >= 0, "ImplGetTextLines: nWidth <= 0!" );
+
+ long nMaxLineWidth = 0;
+ rLineInfo.Clear();
+ if ( rStr.Len() && ( nWidth > 0 ) )
+ {
+ ::rtl::OUString aText( rStr );
+ uno::Reference < text::XBreakIterator > xBI;
+ uno::Reference< linguistic::XHyphenator > xHyph;
+ text::LineBreakHyphenationOptions aHyphOptions( xHyph, 1 );
+ text::LineBreakUserOptions aUserOptions;
+
+ USHORT nPos = 0;
+ USHORT nLen = rStr.Len();
+ while ( nPos < nLen )
+ {
+ xub_StrLen nBreakPos = nPos;
+ while ( ( nBreakPos < nLen ) && ( rStr.GetChar( nBreakPos ) != _CR ) && ( rStr.GetChar( nBreakPos ) != _LF ) )
+ nBreakPos++;
+
+ long nLineWidth = GetTextWidth( rStr, nPos, nBreakPos-nPos );
+ if ( ( nLineWidth > nWidth ) && ( nStyle & TEXT_DRAW_WORDBREAK ) )
+ {
+ if ( !xBI.is() )
+ xBI = vcl::unohelper::CreateBreakIterator();
+
+ xub_StrLen nSoftBreak = GetTextBreak( rStr, nWidth, nPos, nBreakPos - nPos );
+ DBG_ASSERT( nSoftBreak < nBreakPos, "Break?!" );
+ text::LineBreakResults aLBR = xBI->getLineBreak( aText, nSoftBreak, GetSettings().GetLocale(), nPos, aHyphOptions, aUserOptions );
+ nBreakPos = aLBR.breakIndex;
+ if ( nBreakPos <= nPos )
+ nBreakPos = nSoftBreak;
+ nLineWidth = GetTextWidth( rStr, nPos, nBreakPos-nPos );
+ }
+
+ if ( nLineWidth > nMaxLineWidth )
+ nMaxLineWidth = nLineWidth;
+
+ if ( ( rStr.GetChar( nBreakPos ) == _CR ) || ( rStr.GetChar( nBreakPos ) == _LF ) )
+ {
+ nBreakPos++;
+ // CR/LF?
+ if ( ( nPos < nLen ) && ( rStr.GetChar( nBreakPos ) == _LF ) && ( rStr.GetChar( nBreakPos-1 ) == _CR ) )
+ nBreakPos++;
+ }
+
+ if ( nBreakPos == nPos )
+ nBreakPos++;
+
+ rLineInfo.AddLine( new ImplTextLineInfo( nLineWidth, nPos, nBreakPos-nPos ) );
+
+ nPos = nBreakPos;
+ }
+ }
+
+ return nMaxLineWidth;
+}
+
+// =======================================================================
+
+void OutputDevice::SetFont( const Font& rNewFont )
+{
+ DBG_TRACE( "OutputDevice::SetFont()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rNewFont, Font, NULL );
+
+ Font aFont( rNewFont );
+
+ if ( mnDrawMode & (DRAWMODE_BLACKTEXT | DRAWMODE_WHITETEXT | DRAWMODE_GRAYTEXT | DRAWMODE_GHOSTEDTEXT |
+ DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL | DRAWMODE_GRAYFILL | DRAWMODE_NOFILL |
+ DRAWMODE_GHOSTEDFILL) )
+ {
+ Color aTextColor( aFont.GetColor() );
+ if ( mnDrawMode & DRAWMODE_BLACKTEXT )
+ aTextColor = Color( COL_BLACK );
+ else if ( mnDrawMode & DRAWMODE_WHITETEXT )
+ aTextColor = Color( COL_WHITE );
+ else if ( mnDrawMode & DRAWMODE_GRAYTEXT )
+ {
+ const UINT8 cLum = aTextColor.GetLuminance();
+ aTextColor = Color( cLum, cLum, cLum );
+ }
+ if ( mnDrawMode & DRAWMODE_GHOSTEDTEXT )
+ {
+ aTextColor = Color( (aTextColor.GetRed() >> 1 ) | 0x80,
+ (aTextColor.GetGreen() >> 1 ) | 0x80,
+ (aTextColor.GetBlue() >> 1 ) | 0x80 );
+ }
+ aFont.SetColor( aTextColor );
+
+ BOOL bTransFill = aFont.IsTransparent();
+ if ( !bTransFill )
+ {
+ Color aTextFillColor( aFont.GetFillColor() );
+ if ( mnDrawMode & DRAWMODE_BLACKFILL )
+ aTextFillColor = Color( COL_BLACK );
+ else if ( mnDrawMode & DRAWMODE_WHITEFILL )
+ aTextFillColor = Color( COL_WHITE );
+ else if ( mnDrawMode & DRAWMODE_GRAYFILL )
+ {
+ const UINT8 cLum = aTextFillColor.GetLuminance();
+ aTextFillColor = Color( cLum, cLum, cLum );
+ }
+ else if ( mnDrawMode & DRAWMODE_NOFILL )
+ {
+ aTextFillColor = Color( COL_TRANSPARENT );
+ bTransFill = TRUE;
+ }
+ if ( !bTransFill && (mnDrawMode & DRAWMODE_GHOSTEDFILL) )
+ {
+ aTextFillColor = Color( (aTextFillColor.GetRed() >> 1) | 0x80,
+ (aTextFillColor.GetGreen() >> 1) | 0x80,
+ (aTextFillColor.GetBlue() >> 1) | 0x80 );
+ }
+ aFont.SetFillColor( aTextFillColor );
+ }
+ }
+
+ if ( mpMetaFile )
+ {
+ const Color& rTextFillColor = aFont.GetFillColor();
+
+ mpMetaFile->AddAction( new MetaFontAction( aFont ) );
+ mpMetaFile->AddAction( new MetaTextAlignAction( aFont.GetAlign() ) );
+ mpMetaFile->AddAction( new MetaTextColorAction( aFont.GetColor() ) );
+ mpMetaFile->AddAction( new MetaTextFillColorAction( aFont.GetFillColor(), !aFont.IsTransparent() ) );
+ }
+
+ if ( !maFont.IsSameInstance( aFont ) )
+ {
+ if ( maFont.GetColor() != aFont.GetColor() )
+ mbInitTextColor = TRUE;
+ maFont = aFont;
+ mbNewFont = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetTextColor( const Color& rColor )
+{
+ DBG_TRACE( "OutputDevice::SetTextColor()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Color aColor( rColor );
+
+ if ( mnDrawMode & ( DRAWMODE_BLACKTEXT | DRAWMODE_WHITETEXT |
+ DRAWMODE_GRAYTEXT | DRAWMODE_GHOSTEDTEXT ) )
+ {
+ if ( mnDrawMode & DRAWMODE_BLACKTEXT )
+ aColor = Color( COL_BLACK );
+ else if ( mnDrawMode & DRAWMODE_WHITETEXT )
+ aColor = Color( COL_WHITE );
+ else if ( mnDrawMode & DRAWMODE_GRAYTEXT )
+ {
+ const UINT8 cLum = aColor.GetLuminance();
+ aColor = Color( cLum, cLum, cLum );
+ }
+
+ if ( mnDrawMode & DRAWMODE_GHOSTEDTEXT )
+ {
+ aColor = Color( (aColor.GetRed() >> 1) | 0x80,
+ (aColor.GetGreen() >> 1) | 0x80,
+ (aColor.GetBlue() >> 1) | 0x80 );
+ }
+ }
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextColorAction( aColor ) );
+
+ if ( maFont.GetColor() != aColor )
+ {
+ maFont.SetColor( aColor );
+ mbInitTextColor = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetTextFillColor()
+{
+ DBG_TRACE( "OutputDevice::SetTextFillColor()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextFillColorAction( Color(), FALSE ) );
+
+ if ( maFont.GetColor() != Color( COL_TRANSPARENT ) )
+ maFont.SetFillColor( Color( COL_TRANSPARENT ) );
+ if ( !maFont.IsTransparent() )
+ maFont.SetTransparent( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetTextFillColor( const Color& rColor )
+{
+ DBG_TRACE( "OutputDevice::SetTextFillColor()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Color aColor( rColor );
+ BOOL bTransFill = ImplIsColorTransparent( aColor );
+
+ if ( !bTransFill )
+ {
+ if ( mnDrawMode & ( DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL |
+ DRAWMODE_GRAYFILL | DRAWMODE_NOFILL |
+ DRAWMODE_GHOSTEDFILL ) )
+ {
+ if ( mnDrawMode & DRAWMODE_BLACKFILL )
+ aColor = Color( COL_BLACK );
+ else if ( mnDrawMode & DRAWMODE_WHITEFILL )
+ aColor = Color( COL_WHITE );
+ else if ( mnDrawMode & DRAWMODE_GRAYFILL )
+ {
+ const UINT8 cLum = aColor.GetLuminance();
+ aColor = Color( cLum, cLum, cLum );
+ }
+ else if ( mnDrawMode & DRAWMODE_NOFILL )
+ {
+ aColor = Color( COL_TRANSPARENT );
+ bTransFill = TRUE;
+ }
+ if ( !bTransFill && (mnDrawMode & DRAWMODE_GHOSTEDFILL) )
+ {
+ aColor = Color( (aColor.GetRed() >> 1) | 0x80,
+ (aColor.GetGreen() >> 1) | 0x80,
+ (aColor.GetBlue() >> 1) | 0x80 );
+ }
+ }
+ }
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextFillColorAction( aColor, TRUE ) );
+
+ if ( maFont.GetFillColor() != aColor )
+ maFont.SetFillColor( aColor );
+ if ( maFont.IsTransparent() != bTransFill )
+ maFont.SetTransparent( bTransFill );
+}
+
+// -----------------------------------------------------------------------
+
+Color OutputDevice::GetTextFillColor() const
+{
+ if ( maFont.IsTransparent() )
+ return Color( COL_TRANSPARENT );
+ else
+ return maFont.GetFillColor();
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetTextLineColor()
+{
+ DBG_TRACE( "OutputDevice::SetTextLineColor()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextLineColorAction( Color(), FALSE ) );
+
+ maTextLineColor = Color( COL_TRANSPARENT );
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetTextLineColor( const Color& rColor )
+{
+ DBG_TRACE( "OutputDevice::SetTextLineColor()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Color aColor( rColor );
+
+ if ( mnDrawMode & ( DRAWMODE_BLACKTEXT | DRAWMODE_WHITETEXT |
+ DRAWMODE_GRAYTEXT | DRAWMODE_GHOSTEDTEXT ) )
+ {
+ if ( mnDrawMode & DRAWMODE_BLACKTEXT )
+ aColor = Color( COL_BLACK );
+ else if ( mnDrawMode & DRAWMODE_WHITETEXT )
+ aColor = Color( COL_WHITE );
+ else if ( mnDrawMode & DRAWMODE_GRAYTEXT )
+ {
+ const UINT8 cLum = aColor.GetLuminance();
+ aColor = Color( cLum, cLum, cLum );
+ }
+
+ if ( mnDrawMode & DRAWMODE_GHOSTEDTEXT )
+ {
+ aColor = Color( (aColor.GetRed() >> 1) | 0x80,
+ (aColor.GetGreen() >> 1) | 0x80,
+ (aColor.GetBlue() >> 1) | 0x80 );
+ }
+ }
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextLineColorAction( aColor, TRUE ) );
+
+ maTextLineColor = aColor;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetTextAlign( TextAlign eAlign )
+{
+ DBG_TRACE( "OutputDevice::SetTextAlign()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextAlignAction( eAlign ) );
+
+ if ( maFont.GetAlign() != eAlign )
+ {
+ maFont.SetAlign( eAlign );
+ mbNewFont = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawTextLine( const Point& rPos, long nWidth,
+ FontStrikeout eStrikeout,
+ FontUnderline eUnderline )
+{
+ DBG_TRACE( "OutputDevice::DrawTextLine()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextLineAction( rPos, nWidth, eStrikeout, eUnderline ) );
+
+ if ( ((eUnderline == UNDERLINE_NONE) || (eUnderline == UNDERLINE_DONTKNOW)) &&
+ ((eStrikeout == STRIKEOUT_NONE) || (eStrikeout == STRIKEOUT_DONTKNOW)) )
+ return;
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+#else
+ if ( !ImplGetServerGraphics() )
+ return;
+#endif
+
+ if ( mbNewFont )
+ {
+ if ( !ImplNewFont() )
+ return;
+ }
+
+ Point aPos = ImplLogicToDevicePixel( rPos );
+ nWidth = ImplLogicWidthToDevicePixel( nWidth );
+ aPos.X() += mnTextOffX;
+ aPos.Y() += mnTextOffY;
+ ImplDrawTextLine( aPos.X(), aPos.X(), aPos.Y(), nWidth, eStrikeout, eUnderline );
+}
+
+// ------------------------------------------------------------------------
+
+void OutputDevice::DrawWaveLine( const Point& rStartPos, const Point& rEndPos,
+ USHORT nStyle )
+{
+ DBG_TRACE( "OutputDevice::DrawWaveLine()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+#ifndef REMOTE_APPSERVER
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ Point aStartPt = ImplLogicToDevicePixel( rStartPos );
+ Point aEndPt = ImplLogicToDevicePixel( rEndPos );
+ long nStartX = aStartPt.X();
+ long nStartY = aStartPt.Y();
+ long nEndX = aEndPt.X();
+ long nEndY = aEndPt.Y();
+ short nOrientation = 0;
+
+ if ( (nStartY != nEndY) || (nStartX > nEndX) )
+ {
+ long nDX = nEndX - nStartX;
+ double nO = atan2( -nEndY + nStartY, ((nDX == 0L) ? 0.000000001 : nDX) );
+ nO /= F_PI1800;
+ nOrientation = (short)nO;
+ ImplRotatePos( nStartX, nStartY, nEndX, nEndY, -nOrientation );
+ }
+
+ long nWaveHeight;
+ if ( nStyle == WAVE_NORMAL )
+ {
+ nWaveHeight = 3;
+ nStartY++;
+ nEndY++;
+ }
+ else if( nStyle == WAVE_SMALL )
+ {
+ nWaveHeight = 2;
+ nStartY++;
+ nEndY++;
+ }
+ else // WAVE_FLAT
+ nWaveHeight = 1;
+
+ ImplDrawWaveLine( nStartX, nStartY, nStartX, nStartY,
+ nEndX-nStartX, nWaveHeight, 1,
+ nOrientation, GetLineColor() );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ Point aPos1 = ImplLogicToDevicePixel( rStartPos );
+ Point aPos2 = ImplLogicToDevicePixel( rEndPos );
+ pGraphics->DrawWaveLine( aPos1, aPos2, nStyle );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawText( const Point& rStartPt, const XubString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen )
+{
+ DBG_TRACE( "OutputDevice::DrawText()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextAction( rStartPt, rStr, nIndex, nLen ) );
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ // String-Laenge fuer die Ermittlung der Groesse setzen
+ if ( (ULONG)nLen+nIndex > rStr.Len() )
+ {
+ if ( nIndex < rStr.Len() )
+ nLen = rStr.Len()-nIndex;
+ else
+ nLen = 0;
+ }
+
+ // Ist die Ausgabe leer, dann mache nichts
+ if ( !nLen )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+#else
+ if ( !ImplGetServerGraphics() )
+ return;
+#endif
+
+ if ( mbNewFont )
+ ImplNewFont();
+ if ( mbInitFont )
+ ImplInitFont();
+ if ( mbInitTextColor )
+ ImplInitTextColor();
+
+ Point aStartPt = ImplLogicToDevicePixel( rStartPt );
+
+ // Pointer auf den String-Buffer setzen und um den Index korrigieren
+ const sal_Unicode* pStr = rStr.GetBuffer();
+ pStr += nIndex;
+
+ if ( mbKerning )
+ {
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ long* pCharWidthAry = pFontEntry->maWidthAry;
+ long nFactor = pFontEntry->mnWidthFactor;
+ USHORT i;
+
+ // DX-Array berechnen
+ long nOffset = 0;
+ long aStackAry[128];
+ long* pDXAry = (long*)ImplGetStackBuffer( sizeof(long)*(nLen-1), aStackAry, sizeof( aStackAry ) );
+ for ( i = 0; i < nLen-1; i++ )
+ {
+ nOffset += pCharWidthAry[(unsigned char)pStr[i]];
+ pDXAry[i] = nOffset / nFactor;
+ }
+ ImplCalcKerning( pStr, nLen, pDXAry, nLen-1 );
+ ImplDrawText( aStartPt.X(), aStartPt.Y(), pStr, nLen, pDXAry );
+ ImplReleaseStackBuffer( pDXAry, aStackAry );
+ }
+ else
+ ImplDrawText( aStartPt.X(), aStartPt.Y(), pStr, nLen, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::GetTextWidth( const XubString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen ) const
+{
+ DBG_TRACE( "OutputDevice::GetTextWidth()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mbNewFont )
+ {
+ if ( !((OutputDevice*)this)->ImplNewFont() )
+ return 0;
+ }
+
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ long nWidth = 0;
+
+ if ( nIndex < rStr.Len() )
+ {
+ // String-Laenge fuer die Ermittlung der Groesse setzen
+ if ( (ULONG)nLen+nIndex > rStr.Len() )
+ nLen = rStr.Len()-nIndex;
+
+ if ( nLen )
+ {
+ long* pCharWidthAry = pFontEntry->maWidthAry;
+
+ // Bei Fixed-Fonts reicht eine Multiplikation
+ if ( pFontEntry->mbFixedFont )
+ {
+ nWidth = pCharWidthAry['A'] * nLen;
+ nWidth /= pFontEntry->mnWidthFactor;
+ }
+ else
+ {
+ const sal_Unicode* pStr = rStr.GetBuffer();
+ const sal_Unicode* pTempStr;
+ USHORT nTempLen;
+ pStr += nIndex;
+ pTempStr = pStr;
+ nTempLen = nLen;
+ while ( nTempLen )
+ {
+ nWidth += ImplGetCharWidth( *pTempStr );
+ nTempLen--;
+ pTempStr++;
+ }
+ nWidth /= pFontEntry->mnWidthFactor;
+
+ // Kerning beruecksichtigen (tun wir nur bei Fonts ohne feste Breite)
+ if ( mbKerning )
+ nWidth += ImplCalcKerning( pStr, nLen, NULL, 0 );
+ }
+ }
+ }
+
+ if ( mbMap )
+ nWidth = ImplDevicePixelToLogicWidth( nWidth );
+
+ return nWidth;
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::GetTextHeight() const
+{
+ DBG_TRACE( "OutputDevice::GetTextHeight()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mbNewFont )
+ {
+ if ( !((OutputDevice*)this)->ImplNewFont() )
+ return 0;
+ }
+
+ long nHeight = mpFontEntry->mnLineHeight;
+
+ if ( mbMap )
+ nHeight = ImplDevicePixelToLogicHeight( nHeight );
+
+ return nHeight;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawTextArray( const Point& rStartPt, const XubString& rStr,
+ const long* pDXAry,
+ xub_StrLen nIndex, xub_StrLen nLen )
+{
+ DBG_TRACE( "OutputDevice::DrawTextArray()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextArrayAction( rStartPt, rStr, pDXAry, nIndex, nLen ) );
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ // String-Laenge fuer die Ermittlung der Groesse setzen
+ if ( (ULONG)nLen+nIndex > rStr.Len() )
+ {
+ if ( nIndex < rStr.Len() )
+ nLen = rStr.Len()-nIndex;
+ else
+ nLen = 0;
+ }
+
+ // Ist die Ausgabe leer, dann mache nichts
+ if ( !nLen )
+ return;
+
+ // Bei keinem Pos-Array, DrawText benutzen
+ if ( !pDXAry || (nLen < 2) )
+ {
+ // hier Aufrufen, damit keine doppelte MetaFile Aufzeichnung
+ DrawText( rStartPt, rStr, nIndex, nLen );
+ return;
+ }
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+#else
+ if ( !ImplGetServerGraphics() )
+ return;
+#endif
+
+ if ( mbNewFont )
+ {
+ if ( !ImplNewFont() )
+ return;
+ }
+ if ( mbInitFont )
+ ImplInitFont();
+ if ( mbInitTextColor )
+ ImplInitTextColor();
+
+ // Pointer auf den String-Buffer setzen und um den Index korrigieren
+ const sal_Unicode* pStr = rStr.GetBuffer();
+ pStr += nIndex;
+
+ Point aStartPt = ImplLogicToDevicePixel( rStartPt );
+ if ( mbMap )
+ {
+ long nLogStartX = rStartPt.X();
+ long nPixStartX = aStartPt.X();
+ long aStackAry[128];
+ long* pPixDXAry = (long*)ImplGetStackBuffer( sizeof(long)*(nLen-1), aStackAry, sizeof( aStackAry ) );
+ for ( xub_StrLen i = 0; i < (nLen-1); i++ )
+ pPixDXAry[i] = ImplLogicXToDevicePixel( nLogStartX+pDXAry[i] )-nPixStartX;
+ ImplDrawText( aStartPt.X(), aStartPt.Y(), pStr, nLen, pPixDXAry );
+ ImplReleaseStackBuffer( pPixDXAry, aStackAry );
+ }
+ else
+ ImplDrawText( aStartPt.X(), aStartPt.Y(), pStr, nLen, pDXAry );
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::GetTextArray( const UniString& rStr, long* pDXAry,
+ xub_StrLen nIndex, xub_StrLen nLen ) const
+{
+ DBG_TRACE( "OutputDevice::GetTextArray()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( !pDXAry )
+ return GetTextWidth( rStr, nIndex, nLen );
+
+ // String-Laenge fuer die Ermittlung der Groesse setzen
+ if ( (ULONG)nLen+nIndex > rStr.Len() )
+ {
+ if ( nIndex < rStr.Len() )
+ nLen = rStr.Len()-nIndex;
+ else
+ nLen = 0;
+ }
+
+ if ( !nLen )
+ return 0;
+
+ if ( mbNewFont )
+ {
+ if ( !((OutputDevice*)this)->ImplNewFont() )
+ return 0;
+ }
+
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ long* pCharWidthAry = pFontEntry->maWidthAry;
+ long nFactor = pFontEntry->mnWidthFactor;
+ const sal_Unicode* pTempStr;
+ const sal_Unicode* pStr;
+ long nOffset = 0;
+ xub_StrLen i;
+ pStr = rStr.GetBuffer();
+ pStr += nIndex;
+ pTempStr = pStr;
+
+ // Breiten ermitteln
+ for ( i = 0; i < nLen; i++ )
+ {
+ nOffset += ImplGetCharWidth( *pTempStr );
+ pDXAry[i] = nOffset / nFactor;
+ pTempStr++;
+ }
+
+ // Kerning beruecksichtigen
+ if ( mbKerning )
+ ImplCalcKerning( pStr, nLen, pDXAry, nLen );
+
+ // Breite und Hoehe ermitteln
+ long nWidth = pDXAry[nLen-1];
+
+ // Wenn MapMode gesetzt, dann Werte umrechnen
+ if ( mbMap )
+ {
+ for ( i = 0; i < nLen; i++ )
+ pDXAry[i] = ImplDevicePixelToLogicWidth( pDXAry[i] );
+
+ nWidth = ImplDevicePixelToLogicWidth( nWidth );
+ }
+
+ return nWidth;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawStretchText( const Point& rStartPt, ULONG nWidth,
+ const UniString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen )
+{
+ DBG_TRACE( "OutputDevice::DrawStretchText()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaStretchTextAction( rStartPt, nWidth, rStr, nIndex, nLen ) );
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ // String-Laenge fuer die Ermittlung der Groesse setzen
+ if ( (ULONG)nLen+nIndex > rStr.Len() )
+ {
+ if ( nIndex < rStr.Len() )
+ nLen = rStr.Len()-nIndex;
+ else
+ nLen = 0;
+ }
+
+ // Ist die Ausgabe leer, dann mache nichts
+ if ( !nLen )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+#else
+ if ( !ImplGetServerGraphics() )
+ return;
+#endif
+
+ if ( mbNewFont )
+ {
+ if ( !ImplNewFont() )
+ return;
+ }
+ if ( mbInitFont )
+ ImplInitFont();
+ if ( mbInitTextColor )
+ ImplInitTextColor();
+
+ Point aStartPt = ImplLogicToDevicePixel( rStartPt );
+ nWidth = ImplLogicWidthToDevicePixel( nWidth );
+
+ // Pointer auf den String-Buffer setzen und um den Index korrigieren
+ const sal_Unicode* pStr = rStr.GetBuffer();
+ pStr += nIndex;
+
+ // Breiten-Array fuer errechnete Werte allocieren und
+ // mit den Breiten der einzelnen Character fuellen lassen
+ long aStackAry[128];
+ long* pDXAry = (long*)ImplGetStackBuffer( sizeof(long)*nLen, aStackAry, sizeof( aStackAry ) );
+ ImplFillDXAry( pDXAry, pStr, nLen, (long)nWidth );
+ ImplDrawText( aStartPt.X(), aStartPt.Y(), pStr, nLen, pDXAry );
+ ImplReleaseStackBuffer( pDXAry, aStackAry );
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen OutputDevice::GetTextBreak( const XubString& rStr, long nTextWidth,
+ xub_StrLen nIndex, xub_StrLen nLen,
+ long nCharExtra ) const
+{
+ DBG_TRACE( "OutputDevice::GetTextBreak()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( nIndex > rStr.Len() )
+ return 0;
+
+ if ( mbNewFont )
+ {
+ if ( !((OutputDevice*)this)->ImplNewFont() )
+ return 0;
+ }
+
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ long* pCharWidthAry = pFontEntry->maWidthAry;
+ long nFactor = pFontEntry->mnWidthFactor;
+ const sal_Unicode* pStr;
+ long nCalcWidth = 0;
+ xub_StrLen nLastIndex;
+
+ if ( mbMap )
+ {
+ nTextWidth = ImplLogicWidthToDevicePixel( nTextWidth*10 );
+ nTextWidth *= nFactor;
+ nTextWidth /= 10;
+ if ( nCharExtra )
+ {
+ nCharExtra = ImplLogicWidthToDevicePixel( nCharExtra*10 );
+ nCharExtra *= nFactor;
+ nCharExtra /= 10;
+ }
+ }
+ else
+ {
+ nCharExtra *= nFactor;
+ nTextWidth *= nFactor;
+ }
+
+ // Letzte Index-Position ermitteln
+ if ( (ULONG)nIndex+nLen > rStr.Len() )
+ nLastIndex = rStr.Len();
+ else
+ nLastIndex = nIndex + nLen;
+
+ pStr = rStr.GetBuffer();
+ pStr += nIndex;
+ while ( nIndex < nLastIndex )
+ {
+ nCalcWidth += ImplGetCharWidth( *pStr );
+
+ if ( nCalcWidth > nTextWidth )
+ return nIndex;
+
+ // Kerning beruecksichtigen
+ if ( mbKerning )
+ nCalcWidth += ImplCalcKerning( pStr, 2, NULL, 0 )*nFactor;
+ nCalcWidth += nCharExtra;
+
+ nIndex++;
+ pStr++;
+ }
+
+ return STRING_LEN;
+}
+
+// -----------------------------------------------------------------------
+
+xub_StrLen OutputDevice::GetTextBreak( const XubString& rStr, long nTextWidth,
+ sal_Unicode nExtraChar, xub_StrLen& rExtraCharPos,
+ xub_StrLen nIndex, xub_StrLen nLen,
+ long nCharExtra ) const
+{
+ DBG_TRACE( "OutputDevice::GetTextBreak()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( nIndex > rStr.Len() )
+ return 0;
+
+ if ( mbNewFont )
+ {
+ if ( !((OutputDevice*)this)->ImplNewFont() )
+ return 0;
+ }
+
+ ImplFontEntry* pFontEntry = mpFontEntry;
+ long* pCharWidthAry = pFontEntry->maWidthAry;
+ long nFactor = pFontEntry->mnWidthFactor;
+ const sal_Unicode* pStr;
+ long nTextWidth2;
+ long nCalcWidth = 0;
+ xub_StrLen nIndex2 = STRING_LEN;
+ xub_StrLen nLastIndex;
+
+ if ( mbMap )
+ {
+ nTextWidth = ImplLogicWidthToDevicePixel( nTextWidth*10 );
+ nTextWidth *= nFactor;
+ nTextWidth /= 10;
+ if ( nCharExtra )
+ {
+ nCharExtra = ImplLogicWidthToDevicePixel( nCharExtra*10 );
+ nCharExtra *= nFactor;
+ nCharExtra /= 10;
+ }
+ }
+ else
+ {
+ nCharExtra *= nFactor;
+ nTextWidth *= nFactor;
+ }
+
+ // Letzte Index-Position ermitteln
+ if ( (ULONG)nIndex+nLen > rStr.Len() )
+ nLastIndex = rStr.Len();
+ else
+ nLastIndex = nIndex + nLen;
+
+ nTextWidth2 = nTextWidth - ImplGetCharWidth( nExtraChar ) - nCharExtra;
+
+ pStr = rStr.GetBuffer();
+ pStr += nIndex;
+ while ( nIndex < nLastIndex )
+ {
+ nCalcWidth += ImplGetCharWidth( *pStr );
+
+ if ( nCalcWidth > nTextWidth2 )
+ {
+ if ( nIndex2 == STRING_LEN )
+ nIndex2 = nIndex;
+ }
+ if ( nCalcWidth > nTextWidth )
+ {
+ if ( nIndex2 == STRING_LEN )
+ rExtraCharPos = nIndex;
+ else
+ rExtraCharPos = nIndex2;
+ return nIndex;
+ }
+
+ // Kerning beruecksichtigen
+ if ( mbKerning )
+ nCalcWidth += ImplCalcKerning( pStr, 2, NULL, 0 )*nFactor;
+ nCalcWidth += nCharExtra;
+
+ nIndex++;
+ pStr++;
+ }
+
+ rExtraCharPos = nIndex2;
+ return STRING_LEN;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::GetCharWidth( sal_Unicode nFirstChar, sal_Unicode nLastChar,
+ long* pWidthAry ) const
+{
+ DBG_TRACE( "OutputDevice::GetCharWidth()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_ASSERT( nFirstChar <= nLastChar, "OutputDevice::GetCharWidth(): nFirst > nLast" );
+
+ if ( mbNewFont )
+ {
+ if ( !((OutputDevice*)this)->ImplNewFont() )
+ return;
+ }
+
+ long nFactor = mpFontEntry->mnWidthFactor;
+ sal_Unicode nCharCount = nLastChar-nFirstChar+1;
+
+ if ( mbMap )
+ {
+ while ( nCharCount )
+ {
+ *pWidthAry = ImplDevicePixelToLogicWidth( ImplGetCharWidth( nFirstChar ) ) / nFactor;
+ pWidthAry++;
+ nFirstChar++;
+ nCharCount--;
+ }
+ }
+ else
+ {
+ while ( nCharCount )
+ {
+ *pWidthAry = ImplGetCharWidth( nFirstChar ) / nFactor;
+ pWidthAry++;
+ nFirstChar++;
+ nCharCount--;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawText( const Rectangle& rRect,
+ const XubString& rStr, USHORT nStyle )
+{
+ DBG_TRACE( "OutputDevice::DrawText( const Rectangle& )" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTextRectAction( rRect, rStr, nStyle ) );
+
+ if ( !IsDeviceOutputNecessary() || !rStr.Len() || rRect.IsEmpty() )
+ return;
+
+ // Vorsichtshalber hier auch schon Aufrufen, da ImplDrawMnemonicLine()
+ // dies nicht macht
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+#else
+ if ( !ImplGetServerGraphics() )
+ return;
+#endif
+
+ Color aOldTextColor;
+ Color aOldTextFillColor;
+ BOOL bRestoreFillColor;
+ if ( nStyle & TEXT_DRAW_DISABLE )
+ {
+ aOldTextColor = GetTextColor();
+ if ( IsTextFillColor() )
+ {
+ bRestoreFillColor = TRUE;
+ aOldTextFillColor = GetTextFillColor();
+ }
+ else
+ bRestoreFillColor = FALSE;
+ SetTextColor( GetSettings().GetStyleSettings().GetLightColor() );
+ Rectangle aRect = rRect;
+ aRect.Move( 1, 1 );
+ DrawText( aRect, rStr, nStyle & ~TEXT_DRAW_DISABLE );
+ SetTextColor( GetSettings().GetStyleSettings().GetShadowColor() );
+ }
+
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+
+ if ( ((nWidth <= 0) || (nHeight <= 0)) && (nStyle & TEXT_DRAW_CLIP) )
+ return;
+
+ XubString aStr = rStr;
+ Point aPos = rRect.TopLeft();
+ long nTextHeight = GetTextHeight();
+ TextAlign eAlign = GetTextAlign();
+ xub_StrLen nMnemonicPos = STRING_NOTFOUND;
+
+ if ( nStyle & TEXT_DRAW_MNEMONIC )
+ aStr = GetNonMnemonicString( aStr, nMnemonicPos );
+
+ // Mehrzeiligen Text behandeln wir anders
+ if ( nStyle & TEXT_DRAW_MULTILINE )
+ {
+ XubString aLastLine;
+ ImplMultiTextLineInfo aMultiLineInfo;
+ ImplTextLineInfo* pLineInfo;
+ long nMaxTextWidth;
+ xub_StrLen i;
+ xub_StrLen nLines;
+ xub_StrLen nFormatLines;
+
+ if ( nTextHeight )
+ {
+ nMaxTextWidth = ImplGetTextLines( aMultiLineInfo, nWidth, aStr, nStyle );
+ nLines = (xub_StrLen)(nHeight/nTextHeight);
+ nFormatLines = aMultiLineInfo.Count();
+ if ( !nLines )
+ nLines = 1;
+ if ( nFormatLines > nLines )
+ {
+ if ( nStyle & TEXT_DRAW_ENDELLIPSIS )
+ {
+ // Letzte Zeile zusammenbauen und kuerzen
+ nFormatLines = nLines-1;
+ pLineInfo = aMultiLineInfo.GetLine( nFormatLines );
+ aLastLine = aStr.Copy( pLineInfo->GetIndex() );
+ aLastLine.ConvertLineEnd( LINEEND_LF );
+ // Alle LineFeed's durch Spaces ersetzen
+ xub_StrLen nLastLineLen = aLastLine.Len();
+ for ( i = 0; i < nLastLineLen; i++ )
+ {
+ if ( aLastLine.GetChar( i ) == _LF )
+ aLastLine.SetChar( i, ' ' );
+ }
+ aLastLine = GetEllipsisString( aLastLine, nWidth, nStyle );
+ nStyle &= ~(TEXT_DRAW_VCENTER | TEXT_DRAW_BOTTOM);
+ nStyle |= TEXT_DRAW_TOP;
+ }
+ }
+ else
+ {
+ if ( nMaxTextWidth <= nWidth )
+ nStyle &= ~TEXT_DRAW_CLIP;
+ }
+
+ // Muss in der Hoehe geclippt werden?
+ if ( nFormatLines*nTextHeight > nHeight )
+ nStyle |= TEXT_DRAW_CLIP;
+
+ // Clipping setzen
+ if ( nStyle & TEXT_DRAW_CLIP )
+ {
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( rRect );
+ }
+
+ // Vertikales Alignment
+ if ( nStyle & TEXT_DRAW_BOTTOM )
+ aPos.Y() += nHeight-(nFormatLines*nTextHeight);
+ else if ( nStyle & TEXT_DRAW_VCENTER )
+ aPos.Y() += (nHeight-(nFormatLines*nTextHeight))/2;
+
+ // Font Alignment
+ if ( eAlign == ALIGN_BOTTOM )
+ aPos.Y() += nTextHeight;
+ else if ( eAlign == ALIGN_BASELINE )
+ aPos.Y() += GetFontMetric().GetAscent();
+
+ // Alle Zeilen ausgeben, bis auf die letzte
+ for ( i = 0; i < nFormatLines; i++ )
+ {
+ pLineInfo = aMultiLineInfo.GetLine( i );
+ if ( nStyle & TEXT_DRAW_RIGHT )
+ aPos.X() += nWidth-pLineInfo->GetWidth();
+ else if ( nStyle & TEXT_DRAW_CENTER )
+ aPos.X() += (nWidth-pLineInfo->GetWidth())/2;
+ xub_StrLen nIndex = pLineInfo->GetIndex();
+ xub_StrLen nLineLen = pLineInfo->GetLen();
+ DrawText( aPos, aStr, nIndex, nLineLen );
+ if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) )
+ {
+ if ( (nMnemonicPos >= nIndex) && (nMnemonicPos < nIndex+nLineLen) )
+ {
+ long nMnemonicX;
+ long nMnemonicY;
+ xub_Unicode cMnemonic;
+ Point aTempPos = LogicToPixel( aPos );
+ cMnemonic = aStr.GetChar( nMnemonicPos );
+ nMnemonicX = mnOutOffX + aTempPos.X() + ImplLogicWidthToDevicePixel( GetTextWidth( aStr, nIndex, nMnemonicPos-nIndex ) );
+ nMnemonicY = mnOutOffY + aTempPos.Y() + ImplLogicWidthToDevicePixel( GetFontMetric().GetAscent() );
+ ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, cMnemonic );
+ }
+ }
+ aPos.Y() += nTextHeight;
+ aPos.X() = rRect.Left();
+ }
+
+ // Gibt es noch eine letzte Zeile, dann diese linksbuendig ausgeben,
+ // da die Zeile gekuerzt wurde
+ if ( aLastLine.Len() )
+ DrawText( aPos, aLastLine );
+
+ // Clipping zuruecksetzen
+ if ( nStyle & TEXT_DRAW_CLIP )
+ Pop();
+ }
+ }
+ else
+ {
+ long nTextWidth = GetTextWidth( aStr );
+
+ // Evt. Text kuerzen
+ if ( nTextWidth > nWidth )
+ {
+ if ( nStyle & TEXT_DRAW_ELLIPSIS )
+ {
+ aStr = GetEllipsisString( aStr, nWidth, nStyle );
+ nStyle &= ~(TEXT_DRAW_CENTER | TEXT_DRAW_RIGHT);
+ nStyle |= TEXT_DRAW_LEFT;
+ nTextWidth = GetTextWidth( aStr );
+ }
+ }
+ else
+ {
+ if ( nTextHeight <= nHeight )
+ nStyle &= ~TEXT_DRAW_CLIP;
+ }
+
+ // Vertikales Alignment
+ if ( nStyle & TEXT_DRAW_RIGHT )
+ aPos.X() += nWidth-nTextWidth;
+ else if ( nStyle & TEXT_DRAW_CENTER )
+ aPos.X() += (nWidth-nTextWidth)/2;
+
+ // Font Alignment
+ if ( eAlign == ALIGN_BOTTOM )
+ aPos.Y() += nTextHeight;
+ else if ( eAlign == ALIGN_BASELINE )
+ aPos.Y() += GetFontMetric().GetAscent();
+
+ if ( nStyle & TEXT_DRAW_BOTTOM )
+ aPos.Y() += nHeight-nTextHeight;
+ else if ( nStyle & TEXT_DRAW_VCENTER )
+ aPos.Y() += (nHeight-nTextHeight)/2;
+
+ long nMnemonicX;
+ long nMnemonicY;
+ xub_Unicode cMnemonic;
+ if ( nMnemonicPos != STRING_NOTFOUND )
+ {
+ Point aTempPos = LogicToPixel( aPos );
+ cMnemonic = aStr.GetChar( nMnemonicPos );
+ nMnemonicX = mnOutOffX + aTempPos.X() + ImplLogicWidthToDevicePixel( GetTextWidth( aStr, 0, nMnemonicPos ) );
+ nMnemonicY = mnOutOffY + aTempPos.Y() + ImplLogicWidthToDevicePixel( GetFontMetric().GetAscent() );
+ }
+
+ if ( nStyle & TEXT_DRAW_CLIP )
+ {
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( rRect );
+ DrawText( aPos, aStr );
+ if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) )
+ {
+ if ( nMnemonicPos != STRING_NOTFOUND )
+ ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, cMnemonic );
+ }
+ Pop();
+ }
+ else
+ {
+ DrawText( aPos, aStr );
+ if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) )
+ {
+ if ( nMnemonicPos != STRING_NOTFOUND )
+ ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, cMnemonic );
+ }
+ }
+ }
+
+ if ( nStyle & TEXT_DRAW_DISABLE )
+ {
+ SetTextColor( aOldTextColor );
+ if ( bRestoreFillColor )
+ SetTextFillColor( aOldTextFillColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::GetTextRect( const Rectangle& rRect,
+ const XubString& rStr, USHORT nStyle,
+ TextRectInfo* pInfo ) const
+{
+ DBG_TRACE( "OutputDevice::GetTextRect()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Rectangle aRect = rRect;
+ XubString aStr = rStr;
+ xub_StrLen nLines;
+ long nWidth = rRect.GetWidth();
+ long nMaxWidth;
+ long nTextHeight = GetTextHeight();
+
+ if ( nStyle & TEXT_DRAW_MNEMONIC )
+ aStr = GetNonMnemonicString( aStr );
+
+ if ( nStyle & TEXT_DRAW_MULTILINE )
+ {
+ ImplMultiTextLineInfo aMultiLineInfo;
+ ImplTextLineInfo* pLineInfo;
+ xub_StrLen nFormatLines;
+ xub_StrLen i;
+
+ nMaxWidth = 0;
+ ImplGetTextLines( aMultiLineInfo, nWidth, aStr, nStyle );
+ nFormatLines = aMultiLineInfo.Count();
+ if ( !nTextHeight )
+ nTextHeight = 1;
+ nLines = (USHORT)(aRect.GetHeight()/nTextHeight);
+ if ( pInfo )
+ pInfo->mnLineCount = nFormatLines;
+ if ( !nLines )
+ nLines = 1;
+ if ( nFormatLines <= nLines )
+ nLines = nFormatLines;
+ else
+ {
+ if ( !(nStyle & TEXT_DRAW_ENDELLIPSIS) )
+ nLines = nFormatLines;
+ else
+ {
+ if ( pInfo )
+ pInfo->mbEllipsis = TRUE;
+ nMaxWidth = nWidth;
+ }
+ }
+ if ( pInfo )
+ {
+ BOOL bMaxWidth = nMaxWidth == 0;
+ pInfo->mnMaxWidth = 0;
+ for ( i = 0; i < nLines; i++ )
+ {
+ pLineInfo = aMultiLineInfo.GetLine( i );
+ if ( bMaxWidth && (pLineInfo->GetWidth() > nMaxWidth) )
+ nMaxWidth = pLineInfo->GetWidth();
+ if ( pLineInfo->GetWidth() > pInfo->mnMaxWidth )
+ pInfo->mnMaxWidth = pLineInfo->GetWidth();
+ }
+ }
+ else if ( !nMaxWidth )
+ {
+ for ( i = 0; i < nLines; i++ )
+ {
+ pLineInfo = aMultiLineInfo.GetLine( i );
+ if ( pLineInfo->GetWidth() > nMaxWidth )
+ nMaxWidth = pLineInfo->GetWidth();
+ }
+ }
+ }
+ else
+ {
+ nLines = 1;
+ nMaxWidth = GetTextWidth( aStr );
+
+ if ( pInfo )
+ {
+ pInfo->mnLineCount = 1;
+ pInfo->mnMaxWidth = nMaxWidth;
+ }
+
+ if ( (nMaxWidth > nWidth) && (nStyle & TEXT_DRAW_ELLIPSIS) )
+ {
+ if ( pInfo )
+ pInfo->mbEllipsis = TRUE;
+ nMaxWidth = nWidth;
+ }
+ }
+
+ if ( nStyle & TEXT_DRAW_RIGHT )
+ aRect.Left() = aRect.Right()-nMaxWidth+1;
+ else if ( nStyle & TEXT_DRAW_CENTER )
+ {
+ aRect.Left() += (nWidth-nMaxWidth)/2;
+ aRect.Right() = aRect.Left()+nMaxWidth-1;
+ }
+ else
+ aRect.Right() = aRect.Left()+nMaxWidth-1;
+
+ if ( nStyle & TEXT_DRAW_BOTTOM )
+ aRect.Top() = aRect.Bottom()-(nTextHeight*nLines)+1;
+ else if ( nStyle & TEXT_DRAW_VCENTER )
+ {
+ aRect.Top() += (aRect.GetHeight()-(nTextHeight*nLines))/2;
+ aRect.Bottom() = aRect.Top()+(nTextHeight*nLines)-1;
+ }
+ else
+ aRect.Bottom() = aRect.Top()+(nTextHeight*nLines)-1;
+
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplIsCharIn( xub_Unicode c, const sal_Char* pStr )
+{
+ while ( *pStr )
+ {
+ if ( *pStr == c )
+ return TRUE;
+ pStr++;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+XubString OutputDevice::GetEllipsisString( const XubString& rStr, long nMaxWidth,
+ USHORT nStyle ) const
+{
+ DBG_TRACE( "OutputDevice::GetEllipsisString()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ XubString aStr = rStr;
+ xub_StrLen nIndex = GetTextBreak( aStr, nMaxWidth );
+
+ if ( nIndex != STRING_LEN )
+ {
+ if ( nStyle & TEXT_DRAW_ENDELLIPSIS )
+ {
+ aStr.Erase( nIndex );
+ if ( nIndex > 1 )
+ {
+ aStr.AppendAscii( "..." );
+ while ( aStr.Len() && (GetTextWidth( aStr ) > nMaxWidth) )
+ {
+ if ( (nIndex > 1) || (nIndex == aStr.Len()) )
+ nIndex--;
+ aStr.Erase( nIndex, 1 );
+ }
+ }
+
+ if ( !aStr.Len() && (nStyle & TEXT_DRAW_CLIP) )
+ aStr += rStr.GetChar( 0 );
+ }
+ else if ( nStyle & (TEXT_DRAW_PATHELLIPSIS | TEXT_DRAW_NEWSELLIPSIS) )
+ {
+ static sal_Char const aPathSepChars[] = "\\/:";
+ static sal_Char const aNewsSepChars[] = ".";
+ const sal_Char* pSepChars;
+
+ if ( nStyle & TEXT_DRAW_PATHELLIPSIS )
+ pSepChars = aPathSepChars;
+ else
+ pSepChars = aNewsSepChars;
+
+ // Letztes Teilstueck ermitteln
+ xub_StrLen nLastContent = rStr.Len();
+ while ( nLastContent )
+ {
+ nLastContent--;
+ if ( ImplIsCharIn( rStr.GetChar( nLastContent ), pSepChars ) )
+ break;
+ }
+ while ( nLastContent &&
+ ImplIsCharIn( rStr.GetChar( nLastContent-1 ), pSepChars ) )
+ nLastContent--;
+
+ XubString aLastStr( rStr, nLastContent, rStr.Len() );
+ XubString aTempLastStr( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
+ aTempLastStr += aLastStr;
+ if ( GetTextWidth( aTempLastStr ) > nMaxWidth )
+ aStr = GetEllipsisString( rStr, nMaxWidth, nStyle | TEXT_DRAW_ENDELLIPSIS );
+ else
+ {
+ USHORT nFirstContent = 0;
+ while ( nFirstContent < nLastContent )
+ {
+ nFirstContent++;
+ if ( ImplIsCharIn( rStr.GetChar( nFirstContent ), pSepChars ) )
+ break;
+ }
+ while ( (nFirstContent < nLastContent) &&
+ ImplIsCharIn( rStr.GetChar( nFirstContent ), pSepChars ) )
+ nFirstContent++;
+
+ if ( nFirstContent >= nLastContent )
+ aStr = GetEllipsisString( rStr, nMaxWidth, nStyle | TEXT_DRAW_ENDELLIPSIS );
+ else
+ {
+ if ( nFirstContent > 4 )
+ nFirstContent = 4;
+ XubString aFirstStr( rStr, 0, nFirstContent );
+ aFirstStr.AppendAscii( "..." );
+ XubString aTempStr = aFirstStr;
+ aTempStr += aLastStr;
+ if ( GetTextWidth( aTempStr ) > nMaxWidth )
+ aStr = GetEllipsisString( rStr, nMaxWidth, nStyle | TEXT_DRAW_ENDELLIPSIS );
+ else
+ {
+ do
+ {
+ aStr = aTempStr;
+ while ( nFirstContent < nLastContent )
+ {
+ nLastContent--;
+ if ( ImplIsCharIn( rStr.GetChar( nLastContent ), pSepChars ) )
+ break;
+ }
+ while ( (nFirstContent < nLastContent) &&
+ ImplIsCharIn( rStr.GetChar( nLastContent-1 ), pSepChars ) )
+ nLastContent--;
+
+ if ( nFirstContent < nLastContent )
+ {
+ XubString aTempLastStr( rStr, nLastContent, rStr.Len() );
+ aTempStr = aFirstStr;
+ aTempStr += aTempLastStr;
+ if ( GetTextWidth( aTempStr ) > nMaxWidth )
+ break;
+ }
+ }
+ while ( nFirstContent < nLastContent );
+ }
+ }
+ }
+ }
+ }
+
+ return aStr;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawCtrlText( const Point& rPos, const XubString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen,
+ USHORT nStyle )
+{
+ DBG_TRACE( "OutputDevice::DrawCtrlText()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( !IsDeviceOutputNecessary() || (nIndex >= rStr.Len()) )
+ return;
+
+ // Vorsichtshalber hier auch schon Aufrufen, da ImplDrawMnemonicLine()
+ // dies nicht macht
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+#else
+ if ( !ImplGetServerGraphics() )
+ return;
+#endif
+
+ XubString aStr = rStr;
+ xub_StrLen nMnemonicPos = STRING_NOTFOUND;
+ long nMnemonicX;
+ long nMnemonicY;
+ xub_Unicode cMnemonic;
+ if ( nStyle & TEXT_DRAW_MNEMONIC )
+ {
+ aStr = GetNonMnemonicString( aStr, nMnemonicPos );
+ if ( nMnemonicPos != STRING_NOTFOUND )
+ {
+ if ( nMnemonicPos < nIndex )
+ nIndex--;
+ else if ( (nLen < STRING_LEN) &&
+ (nMnemonicPos >= nIndex) && (nMnemonicPos < (ULONG)(nIndex+nLen)) )
+ nLen--;
+ Point aTempPos = LogicToPixel( rPos );
+ cMnemonic = aStr.GetChar( nMnemonicPos );
+ nMnemonicX = mnOutOffX + aTempPos.X() + ImplLogicWidthToDevicePixel( GetTextWidth( aStr, 0, nMnemonicPos ) );
+ nMnemonicY = mnOutOffY + aTempPos.Y() + ImplLogicWidthToDevicePixel( GetFontMetric().GetAscent() );
+ }
+ }
+
+ if ( nStyle & TEXT_DRAW_DISABLE )
+ {
+ Color aOldTextColor;
+ Color aOldTextFillColor;
+ BOOL bRestoreFillColor;
+ aOldTextColor = GetTextColor();
+ if ( IsTextFillColor() )
+ {
+ bRestoreFillColor = TRUE;
+ aOldTextFillColor = GetTextFillColor();
+ }
+ else
+ bRestoreFillColor = FALSE;
+ SetTextColor( GetSettings().GetStyleSettings().GetLightColor() );
+ DrawText( Point( rPos.X()+1, rPos.Y()+1 ), aStr, nIndex, nLen );
+ if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) )
+ {
+ if ( nMnemonicPos != STRING_NOTFOUND )
+ ImplDrawMnemonicLine( nMnemonicX+1, nMnemonicY+1, cMnemonic );
+ }
+ SetTextColor( GetSettings().GetStyleSettings().GetShadowColor() );
+ DrawText( rPos, aStr, nIndex, nLen );
+ if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) )
+ {
+ if ( nMnemonicPos != STRING_NOTFOUND )
+ ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, cMnemonic );
+ }
+ SetTextColor( aOldTextColor );
+ if ( bRestoreFillColor )
+ SetTextFillColor( aOldTextFillColor );
+ }
+ else
+ {
+ DrawText( rPos, aStr, nIndex, nLen );
+ if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) )
+ {
+ if ( nMnemonicPos != STRING_NOTFOUND )
+ ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, cMnemonic );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::GetCtrlTextWidth( const XubString& rStr,
+ xub_StrLen nIndex, xub_StrLen nLen,
+ USHORT nStyle ) const
+{
+ DBG_TRACE( "OutputDevice::GetCtrlTextSize()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( nStyle & TEXT_DRAW_MNEMONIC )
+ {
+ xub_StrLen nMnemonicPos;
+ XubString aStr = GetNonMnemonicString( rStr, nMnemonicPos );
+ if ( nMnemonicPos != STRING_NOTFOUND )
+ {
+ if ( nMnemonicPos < nIndex )
+ nIndex--;
+ else if ( (nLen < STRING_LEN) &&
+ (nMnemonicPos >= nIndex) && (nMnemonicPos < (ULONG)(nIndex+nLen)) )
+ nLen--;
+ }
+ return GetTextWidth( aStr, nIndex, nLen );
+ }
+ else
+ return GetTextWidth( rStr, nIndex, nLen );
+}
+
+// -----------------------------------------------------------------------
+
+XubString OutputDevice::GetNonMnemonicString( const XubString& rStr, xub_StrLen& rMnemonicPos )
+{
+ XubString aStr = rStr;
+ xub_StrLen nLen = aStr.Len();
+ xub_StrLen i = 0;
+
+ rMnemonicPos = STRING_NOTFOUND;
+ while ( i < nLen )
+ {
+ if ( aStr.GetChar( i ) == '~' )
+ {
+ if ( aStr.GetChar( i+1 ) != '~' )
+ {
+ if ( rMnemonicPos == STRING_NOTFOUND )
+ rMnemonicPos = i;
+ aStr.Erase( i, 1 );
+ nLen--;
+ }
+ else
+ {
+ aStr.Erase( i, 1 );
+ nLen--;
+ i++;
+ }
+ }
+ else
+ i++;
+ }
+
+ return aStr;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT OutputDevice::GetDevFontCount() const
+{
+ DBG_TRACE( "OutputDevice::GetDevFontCount()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ // Wenn wir schon eine Liste der Fonts haben, dann nicht iterieren
+ if ( mpGetDevFontList )
+ return (USHORT)mpGetDevFontList->Count();
+
+ ((OutputDevice*)this)->mpGetDevFontList = new ImplGetDevFontList;
+
+ // Fill Fontlist
+ ImplDevFontListData* pFontListData = mpFontList->First();
+ while ( pFontListData )
+ {
+ ImplFontData* pLastData = NULL;
+ ImplFontData* pData = pFontListData->mpFirst;
+ while ( pData )
+ {
+ // Compare with the last font, because we wan't in the list
+ // only fonts, that have different attributes, but not
+ // different sizes
+ if ( !pLastData ||
+ (ImplCompareFontDataWithoutSize( pLastData, pData ) != 0) )
+ mpGetDevFontList->Add( pData );
+
+ pLastData = pData;
+ pData = pData->mpNext;
+ }
+
+ pFontListData = mpFontList->Next();
+ }
+
+ return (USHORT)mpGetDevFontList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+FontInfo OutputDevice::GetDevFont( USHORT nDevFont ) const
+{
+ DBG_TRACE( "OutputDevice::GetDevFont()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ FontInfo aFontInfo;
+ USHORT nCount = GetDevFontCount();
+
+ // Wertebereich ueberpruefen
+ if ( nDevFont < nCount )
+ {
+ ImplFontData* pData = mpGetDevFontList->Get( nDevFont );
+ aFontInfo.SetName( pData->maName );
+ aFontInfo.SetStyleName( pData->maStyleName );
+// !!! UNICODE !!! aFontInfo.SetCharSet( ImplGetFakeEncoding( pData->meCharSet ) );
+ aFontInfo.SetCharSet( pData->meCharSet );
+ aFontInfo.SetFamily( pData->meFamily );
+ aFontInfo.SetPitch( pData->mePitch );
+ aFontInfo.SetWeight( pData->meWeight );
+ aFontInfo.SetItalic( pData->meItalic );
+ aFontInfo.mpImplMetric->meType = pData->meType;
+ aFontInfo.mpImplMetric->mbDevice = pData->mbDevice;
+ }
+
+ return aFontInfo;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT OutputDevice::GetDevFontSizeCount( const Font& rFont ) const
+{
+ DBG_TRACE( "OutputDevice::GetDevFontSizeCount()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ XubString aFontName = rFont.GetName();
+
+ // Wenn die Liste schon existiert und der FontName sich nicht
+ // unterscheidet, dann brauchen wir Sie nicht neu erzeugen
+ if ( mpGetDevSizeList )
+ {
+ if ( mpGetDevSizeList->GetFontName() == aFontName )
+ return (USHORT)mpGetDevSizeList->Count();
+ else
+ {
+ mpGetDevSizeList->Clear();
+ mpGetDevSizeList->SetFontName( aFontName );
+ }
+ }
+ else
+ ((OutputDevice*)this)->mpGetDevSizeList = new ImplGetDevSizeList( aFontName );
+
+ // Fonts aus unserer Fontliste in die GetDevFontSizeListe eintragen
+ ImplDevFontListData* pFontListData = mpFontList->FindFont( aFontName );
+ if ( pFontListData )
+ {
+ ImplFontData* pData = pFontListData->mpFirst;
+ do
+ {
+ mpGetDevSizeList->Add( pData->mnHeight );
+ pData = pData->mpNext;
+ }
+ while ( pData );
+ }
+
+ return (USHORT)mpGetDevSizeList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+Size OutputDevice::GetDevFontSize( const Font& rFont, USHORT nSize ) const
+{
+ DBG_TRACE( "OutputDevice::GetDevFontSize()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ USHORT nCount = GetDevFontSizeCount( rFont );
+
+ // Wertebereich ueberpruefen
+ if ( nSize >= nCount )
+ return Size();
+
+ // Wenn MapMode gesetzt ist, wird auf ,5-Points gerundet
+ Size aSize( 0, mpGetDevSizeList->Get( nSize ) );
+ if ( mbMap )
+ {
+ aSize.Height() *= 10;
+ MapMode aMap( MAP_10TH_INCH, Point(), Fraction( 1, 72 ), Fraction( 1, 72 ) );
+ aSize = PixelToLogic( aSize, aMap );
+ aSize.Height() += 5;
+ aSize.Height() /= 10;
+ long nRound = aSize.Height() % 5;
+ if ( nRound >= 3 )
+ aSize.Height() += (5-nRound);
+ else
+ aSize.Height() -= nRound;
+ aSize.Height() *= 10;
+ aSize = LogicToPixel( aSize, aMap );
+ aSize = PixelToLogic( aSize );
+ aSize.Height() += 5;
+ aSize.Height() /= 10;
+ }
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL OutputDevice::IsFontAvailable( const XubString& rFontName ) const
+{
+ DBG_TRACE( "OutputDevice::IsFontAvailable()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ return (mpFontList->FindFont( rFontName ) != 0);
+}
+
+// -----------------------------------------------------------------------
+
+FontMetric OutputDevice::GetFontMetric() const
+{
+ DBG_TRACE( "OutputDevice::GetFontMetric()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ FontMetric aMetric;
+
+ if ( mbNewFont )
+ {
+ if ( !((OutputDevice*)this)->ImplNewFont() )
+ return aMetric;
+ }
+
+ ImplFontEntry* pEntry = mpFontEntry;
+ ImplFontMetricData* pMetric = &(pEntry->maMetric);
+
+ // Mappen und StarView Struktur fuellen
+ aMetric.Font::operator=( maFont );
+
+ // Fontdaten ermitteln und setzen
+ aMetric.SetName( pMetric->maName );
+ aMetric.SetStyleName( pMetric->maStyleName );
+ aMetric.SetSize( PixelToLogic( Size( pMetric->mnWidth, pMetric->mnAscent+pMetric->mnDescent-pMetric->mnLeading ) ) );
+ aMetric.SetCharSet( pMetric->meCharSet );
+ aMetric.SetFamily( pMetric->meFamily );
+ aMetric.SetPitch( pMetric->mePitch );
+ aMetric.SetWeight( pMetric->meWeight );
+ aMetric.SetItalic( pMetric->meItalic );
+ if ( pEntry->mnOwnOrientation )
+ aMetric.SetOrientation( pEntry->mnOwnOrientation );
+ else
+ aMetric.SetOrientation( pMetric->mnOrientation );
+ if ( !mbKerning )
+ aMetric.SetKerning( FALSE );
+
+ // restliche Metricen setzen
+ aMetric.mpImplMetric->meType = pMetric->meType;
+ aMetric.mpImplMetric->mbDevice = pMetric->mbDevice;
+ aMetric.mpImplMetric->mnAscent = ImplDevicePixelToLogicHeight( pMetric->mnAscent );
+ aMetric.mpImplMetric->mnDescent = ImplDevicePixelToLogicHeight( pMetric->mnDescent );
+ aMetric.mpImplMetric->mnLeading = ImplDevicePixelToLogicHeight( pMetric->mnLeading );
+ aMetric.mpImplMetric->mnLineHeight = ImplDevicePixelToLogicHeight( pMetric->mnAscent+pMetric->mnDescent );
+ aMetric.mpImplMetric->mnSlant = ImplDevicePixelToLogicHeight( pMetric->mnSlant );
+ aMetric.mpImplMetric->mnFirstChar = pMetric->mnFirstChar;
+ aMetric.mpImplMetric->mnLastChar = pMetric->mnLastChar;
+
+ return aMetric;
+}
+
+// -----------------------------------------------------------------------
+
+FontMetric OutputDevice::GetFontMetric( const Font& rFont ) const
+{
+ // Uebergebenen Font selektieren, Metric abfragen und alten wieder
+ // selektieren
+ Font aOldFont = GetFont();
+ ((OutputDevice*)this)->SetFont( rFont );
+ FontMetric aMetric( GetFontMetric() );
+ ((OutputDevice*)this)->SetFont( aOldFont );
+ return aMetric;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG OutputDevice::GetKerningPairCount() const
+{
+ DBG_TRACE( "OutputDevice::GetKerningPairCount()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ ((OutputDevice*)this)->ImplInitKerningPairs();
+ return mpFontEntry->mnKernPairs;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::GetKerningPairs( ULONG nPairs, KerningPair* pKernPairs ) const
+{
+ DBG_TRACE( "OutputDevice::GetKerningPairs()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ ((OutputDevice*)this)->ImplInitKerningPairs();
+ if ( nPairs > mpFontEntry->mnKernPairs )
+ nPairs = mpFontEntry->mnKernPairs;
+ if ( nPairs )
+ memcpy( pKernPairs, mpFontEntry->mpKernPairs, nPairs*sizeof( KerningPair ) );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL OutputDevice::GetGlyphBoundRect( xub_Unicode cChar, Rectangle& rRect, BOOL bOptimize )
+{
+ DBG_TRACE( "OutputDevice::GetGlyphBoundRect()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ BOOL bRet = FALSE;
+
+#ifndef REMOTE_APPSERVER
+ if ( mpGraphics || ImplGetGraphics() )
+ {
+ Font* pOldFont;
+ long nLeft, nTop, nWidth, nHeight;
+ long nFontWidth, nFontHeight;
+ long nOrgWidth, nOrgHeight;
+
+ if ( bOptimize )
+ {
+ pOldFont = new Font( GetFont() );
+
+ Font aFont( *pOldFont );
+ Size aFontSize( LogicToPixel( aFont.GetSize() ) );
+
+ if ( aFontSize.Width() && aFontSize.Height() )
+ {
+ const double fFactor = (double) aFontSize.Width() / aFontSize.Height();
+
+ if ( fFactor < 1.0 )
+ {
+ aFontSize.Width() = FRound( fFactor * 500. );
+ aFontSize.Height() = 500;
+ }
+ else
+ {
+ aFontSize.Width() = 500;
+ aFontSize.Height() = FRound( 500. / fFactor );
+ }
+
+ aFont.SetSize( PixelToLogic( aFontSize ) );
+ ((OutputDevice*)this)->SetFont( aFont );
+ nFontWidth = aFont.GetSize().Width();
+ nFontHeight = aFont.GetSize().Height();
+ nOrgWidth = pOldFont->GetSize().Width();
+ nOrgHeight = pOldFont->GetSize().Height();
+ }
+ else
+ {
+ aFont.SetSize( PixelToLogic( Size( 0, 500 ) ) );
+ ((OutputDevice*)this)->SetFont( aFont );
+ nFontWidth = nFontHeight = aFont.GetSize().Height();
+ nOrgWidth = nOrgHeight = pOldFont->GetSize().Height();
+ }
+ }
+
+ if ( mbNewFont )
+ ImplNewFont();
+ if ( mbInitFont )
+ ImplInitFont();
+
+ if ( mpGraphics->GetGlyphBoundRect( cChar, &nLeft, &nTop, &nWidth, &nHeight ) )
+ {
+ if ( bOptimize )
+ {
+ nLeft = ImplDevicePixelToLogicWidth( nLeft ) * nOrgWidth / nFontWidth;
+ nTop = ImplDevicePixelToLogicHeight( nTop ) * nOrgHeight / nFontHeight;
+ nWidth = ImplDevicePixelToLogicWidth( nWidth ) * nOrgWidth / nFontWidth;
+ nHeight = ImplDevicePixelToLogicHeight( nHeight ) * nOrgHeight / nFontHeight;
+ }
+ else
+ {
+ nLeft = ImplDevicePixelToLogicWidth( nLeft );
+ nTop = ImplDevicePixelToLogicHeight( nTop );
+ nWidth = ImplDevicePixelToLogicWidth( nWidth );
+ nHeight = ImplDevicePixelToLogicHeight( nHeight );
+ }
+
+ rRect = Rectangle( Point( nLeft, nTop ), Size( nWidth, nHeight ) );
+ bRet = TRUE;
+ }
+
+ if ( bOptimize )
+ {
+ ((OutputDevice*)this)->SetFont( *pOldFont );
+ delete pOldFont;
+ }
+
+ if ( !bRet && (OUTDEV_PRINTER != meOutDevType) )
+ {
+ if ( bOptimize )
+ {
+ if ( mbNewFont )
+ ImplNewFont();
+ if ( mbInitFont )
+ ImplInitFont();
+ }
+
+ VirtualDevice* pVDev = new VirtualDevice( 1 );
+ long nWidth = ImplGetTextWidth( &cChar, 1, NULL );
+ long nHeight = mpFontEntry->mnLineHeight;
+ Point aOffset( nWidth >> 1, 8 );
+ Size aSize( nWidth + ( aOffset.X() << 1 ), nHeight + ( aOffset.Y() << 1 ) );
+
+ if ( pVDev->SetOutputSizePixel( aSize ) )
+ {
+ Font aFont( GetFont() );
+ Bitmap aBmp;
+
+ aFont.SetShadow( FALSE );
+ aFont.SetOutline( FALSE );
+ aFont.SetOrientation( 0 );
+ aFont.SetSize( Size( mpFontEntry->maFontSelData.mnWidth, mpFontEntry->maFontSelData.mnHeight ) );
+
+ pVDev->SetFont( aFont );
+ pVDev->SetTextAlign( ALIGN_TOP );
+ pVDev->SetTextColor( Color( COL_BLACK ) );
+ pVDev->SetTextFillColor();
+ pVDev->ImplNewFont();
+ pVDev->ImplInitFont();
+ pVDev->ImplInitTextColor();
+ pVDev->ImplDrawText( aOffset.X(), aOffset.Y(), &cChar, 1, NULL );
+ aBmp = pVDev->GetBitmap( Point(), aSize );
+ delete pVDev;
+
+ BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+
+ if ( pAcc )
+ {
+ const long nW = pAcc->Width();
+ const long nW1 = nW - 1L;
+ const long nH = pAcc->Height();
+ long nRight, nBottom;
+ const BitmapColor aBlack( pAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ BOOL bLineDone;
+
+ nLeft = nW;
+ nTop = nH;
+ nRight = nBottom = -1L;
+
+ for( long nY = 0L; nY < nH; nY++ )
+ {
+ bLineDone = FALSE;
+
+ for( long nX = 0L; ( nX < nW ) && !bLineDone; nX++ )
+ {
+ if( pAcc->GetPixel( nY, nX ) == aBlack )
+ {
+ // find y minimum
+ if( nY < nTop )
+ nTop = nY;
+
+ // find y maximum
+ if( nY > nBottom )
+ nBottom = nY;
+
+ // find x minimum
+ if( nX < nLeft )
+ nLeft = nX;
+
+ // find x maximum (last pixel in line)
+ for( long nX2 = nW1; nX2 >= nX; nX2-- )
+ {
+ if( pAcc->GetPixel( nY, nX2 ) == aBlack )
+ {
+ if( nX2 > nRight )
+ nRight = nX2;
+
+ bLineDone = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if( nLeft < nW && nTop < nH && nRight > -1L && nBottom > -1L )
+ {
+ nLeft -= aOffset.X(), nTop -= aOffset.Y();
+ nRight -= aOffset.X(), nBottom -= aOffset.Y();
+
+ nWidth = ImplDevicePixelToLogicWidth( nRight - nLeft + 1L );
+ nHeight = ImplDevicePixelToLogicHeight( nBottom - nTop + 1L );
+ nLeft = ImplDevicePixelToLogicWidth( nLeft );
+ nTop = ImplDevicePixelToLogicHeight( nTop );
+ rRect = Rectangle( Point( nLeft, nTop ), Size( nWidth, nHeight ) );
+ bRet = TRUE;
+ }
+
+ aBmp.ReleaseAccess( pAcc );
+ }
+ }
+ else
+ delete pVDev;
+ }
+ }
+#else
+ if ( mbNewFont )
+ ImplNewFont();
+ if ( mbInitFont )
+ ImplInitFont();
+
+ bRet = mpGraphics->GetGlyphBoundRect( cChar, rRect, bOptimize );
+
+ if ( bRet )
+ {
+ rRect = Rectangle( Point( ImplDevicePixelToLogicWidth( rRect.Left() ),
+ ImplDevicePixelToLogicHeight( rRect.Top() ) ),
+ Size( ImplDevicePixelToLogicWidth( rRect.GetWidth() ),
+ ImplDevicePixelToLogicHeight( rRect.GetHeight() ) ) );
+ }
+
+#endif
+
+ if ( !bRet )
+ rRect.SetEmpty();
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL OutputDevice::GetGlyphOutline( xub_Unicode cChar, PolyPolygon& rPolyPoly, BOOL bOptimize )
+{
+ DBG_TRACE( "OutputDevice::GetGlyphOutline()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ BOOL bRet = FALSE;
+
+#ifndef REMOTE_APPSERVER
+ if ( mpGraphics || ImplGetGraphics() )
+ {
+ Font* pOldFont;
+ USHORT* pPolySizes = NULL;
+ SalPoint* pPoints = NULL;
+ BYTE* pFlags = NULL;
+ long nFontWidth, nFontHeight;
+ long nOrgWidth, nOrgHeight;
+ ULONG nPolyCount;
+
+ if ( bOptimize )
+ {
+ pOldFont = new Font( GetFont() );
+
+ Font aFont( *pOldFont );
+ Size aFontSize( LogicToPixel( aFont.GetSize() ) );
+
+ if ( aFontSize.Width() && aFontSize.Height() )
+ {
+ const double fFactor = (double) aFontSize.Width() / aFontSize.Height();
+
+ if ( fFactor < 1.0 )
+ {
+ aFontSize.Width() = FRound( fFactor * 500. );
+ aFontSize.Height() = 500;
+ }
+ else
+ {
+ aFontSize.Width() = 500;
+ aFontSize.Height() = FRound( 500. / fFactor );
+ }
+
+ aFont.SetSize( PixelToLogic( aFontSize ) );
+ ((OutputDevice*)this)->SetFont( aFont );
+ nFontWidth = aFont.GetSize().Width();
+ nFontHeight = aFont.GetSize().Height();
+ nOrgWidth = pOldFont->GetSize().Width();
+ nOrgHeight = pOldFont->GetSize().Height();
+ }
+ else
+ {
+ aFont.SetSize( PixelToLogic( Size( 0, 500 ) ) );
+ ((OutputDevice*)this)->SetFont( aFont );
+ nFontWidth = nFontHeight = aFont.GetSize().Height();
+ nOrgWidth = nOrgHeight = pOldFont->GetSize().Height();
+ }
+ }
+
+ if ( mbNewFont )
+ ImplNewFont();
+ if ( mbInitFont )
+ ImplInitFont();
+
+ nPolyCount = mpGraphics->GetGlyphOutline( cChar, &pPolySizes, &pPoints, &pFlags );
+ if ( nPolyCount && pPolySizes && pPoints && pFlags )
+ {
+ ULONG nTotalPos = 0UL;
+
+ rPolyPoly.Clear();
+
+ for( ULONG i = 0UL; i < nPolyCount; i++ )
+ {
+ const USHORT nSize = pPolySizes[ i ];
+
+ if( nSize )
+ {
+ Polygon aPoly( nSize );
+ Point* pPt = aPoly.ImplGetPointAry();
+ BYTE* pFl = aPoly.ImplGetFlagAry();
+
+ memcpy( pFl, pFlags + nTotalPos, nSize );
+
+ for( USHORT n = 0; n < nSize; n++ )
+ {
+ const SalPoint& rSalPt = pPoints[ nTotalPos++ ];
+ Point& rPt = pPt[ n ];
+
+ if( bOptimize )
+ {
+ rPt.X() = ImplDevicePixelToLogicWidth( rSalPt.mnX ) *
+ nOrgWidth / nFontWidth;
+ rPt.Y() = ImplDevicePixelToLogicHeight( rSalPt.mnY ) *
+ nOrgHeight / nFontHeight;
+ }
+ else
+ {
+ rPt.X() = ImplDevicePixelToLogicWidth( rSalPt.mnX );
+ rPt.Y() = ImplDevicePixelToLogicHeight( rSalPt.mnY );
+ }
+ }
+
+ rPolyPoly.Insert( aPoly );
+ }
+ }
+
+ bRet = TRUE;
+ }
+
+ delete[] pPolySizes;
+ delete[] pPoints;
+ delete[] pFlags;
+
+ if ( bOptimize )
+ {
+ ((OutputDevice*)this)->SetFont( *pOldFont );
+ delete pOldFont;
+ }
+
+ if ( !bRet && (OUTDEV_PRINTER != meOutDevType) )
+ {
+ if ( bOptimize )
+ {
+ if( mbNewFont )
+ ImplNewFont();
+ if( mbInitFont )
+ ImplInitFont();
+ }
+
+ Font aFont( GetFont() );
+ VirtualDevice* pVDev = new VirtualDevice( 1 );
+ const Size aFontSize( pVDev->LogicToPixel( Size( 0, GLYPH_FONT_HEIGHT ), MAP_POINT ) );
+ const long nOrgWidth = ImplGetTextWidth( &cChar, 1, NULL );
+ const long nOrgHeight = mpFontEntry->mnLineHeight;
+
+ aFont.SetShadow( FALSE );
+ aFont.SetOutline( FALSE );
+ aFont.SetOrientation( 0 );
+ aFont.SetSize( aFontSize );
+ pVDev->SetFont( aFont );
+ pVDev->SetTextAlign( ALIGN_TOP );
+ pVDev->SetTextColor( Color( COL_BLACK ) );
+ pVDev->SetTextFillColor();
+ pVDev->ImplNewFont();
+ pVDev->ImplInitFont();
+ pVDev->ImplInitTextColor();
+
+ const long nWidth = pVDev->ImplGetTextWidth( &cChar, 1, NULL );
+ const long nHeight = pVDev->mpFontEntry->mnLineHeight;
+ const Point aOffset( nWidth >> 1, 8 );
+ const Size aSize( nWidth + ( aOffset.X() << 1 ), nHeight + ( aOffset.Y() << 1 ) );
+ const double fScaleX = ( nOrgWidth && nWidth ) ? ( (double) nOrgWidth / nWidth ) : 0.0;
+ const double fScaleY = ( nOrgHeight && nHeight ) ? ( (double) nOrgHeight / nHeight ) : 0.0;
+
+ if ( pVDev->SetOutputSizePixel( aSize ) )
+ {
+ Bitmap aBmp;
+
+ pVDev->ImplDrawText( aOffset.X(), aOffset.Y(), &cChar, 1, NULL );
+ aBmp = pVDev->GetBitmap( Point(), aSize );
+ delete pVDev;
+
+ if( aBmp.Vectorize( rPolyPoly, BMP_VECTORIZE_OUTER | BMP_VECTORIZE_REDUCE_EDGES ) )
+ {
+ const long nOffX = aOffset.X(), nOffY = aOffset.Y();
+
+ for( USHORT i = 0UL, nCount = rPolyPoly.Count(); i < nCount; i++ )
+ {
+ Polygon& rPoly = rPolyPoly[ i ];
+
+ for( USHORT n = 0, nSize = rPoly.GetSize(); n < nSize; n++ )
+ {
+ Point& rPt = rPoly[ n ];
+ rPt.X() = FRound( ImplDevicePixelToLogicWidth( rPt.X() - nOffX ) * fScaleX );
+ rPt.Y() = FRound( ImplDevicePixelToLogicHeight( rPt.Y() - nOffY ) * fScaleY );
+ }
+ }
+
+ bRet = TRUE;
+ }
+ }
+ else
+ delete pVDev;
+ }
+ }
+#else
+ if ( mbNewFont )
+ ImplNewFont();
+ if ( mbInitFont )
+ ImplInitFont();
+
+ bRet = mpGraphics->GetGlyphOutline( cChar, rPolyPoly, bOptimize );
+
+ if( bRet )
+ {
+ for( USHORT i = 0UL, nCount = rPolyPoly.Count(); i < nCount; i++ )
+ {
+ Polygon& rPoly = rPolyPoly[ i ];
+
+ for( USHORT n = 0, nSize = rPoly.GetSize(); n < nSize; n++ )
+ {
+ Point& rPt = rPoly[ n ];
+ rPt.X() = ImplDevicePixelToLogicWidth( rPt.X() );
+ rPt.Y() = ImplDevicePixelToLogicHeight( rPt.Y() );
+ }
+ }
+ }
+
+#endif
+
+ if( !bRet )
+ rPolyPoly = PolyPolygon();
+
+ return bRet;
+}
diff --git a/vcl/source/gdi/outdev4.cxx b/vcl/source/gdi/outdev4.cxx
new file mode 100644
index 000000000000..fc8e313b825d
--- /dev/null
+++ b/vcl/source/gdi/outdev4.cxx
@@ -0,0 +1,1634 @@
+/*************************************************************************
+ *
+ * $RCSfile: outdev4.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_OUTDEV_CXX
+
+#include <math.h>
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#endif
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#else
+#ifndef _SV_RMOUTDEV_HXX
+#include <rmoutdev.hxx>
+#endif
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_GRADIENT_HXX
+#include <gradient.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_OUTDATA_HXX
+#include <outdata.hxx>
+#endif
+#ifndef _SV_POLY_H
+#include <poly.h>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_LINE_HXX
+#include <line.hxx>
+#endif
+#ifndef _SV_HATCH_HXX
+#include <hatch.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define HATCH_MAXPOINTS 1024
+#define GRADIENT_DEFAULT_STEPCOUNT 0
+
+// ----------------
+// - Cmp-Function -
+// ----------------
+
+extern "C" int __LOADONCALLAPI ImplHatchCmpFnc( const void* p1, const void* p2 )
+{
+ const long nX1 = ( (Point*) p1 )->X();
+ const long nX2 = ( (Point*) p2 )->X();
+ const long nY1 = ( (Point*) p1 )->Y();
+ const long nY2 = ( (Point*) p2 )->Y();
+
+ return ( nX1 > nX2 ? 1 : nX1 == nX2 ? nY1 > nY2 ? 1: nY1 == nY2 ? 0 : -1 : -1 );
+}
+
+// =======================================================================
+
+DBG_NAMEEX( OutputDevice );
+DBG_NAMEEX( Gradient );
+
+// =======================================================================
+
+#ifndef REMOTE_APPSERVER
+
+void OutputDevice::ImplDrawPolygon( const Polygon& rPoly )
+{
+ USHORT nPoints = rPoly.GetSize();
+
+ if ( nPoints < 2 )
+ return;
+
+ const SalPoint* pPtAry = (const SalPoint*)rPoly.ImplGetConstPointAry();
+ mpGraphics->DrawPolygon( nPoints, pPtAry );
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawPolyPolygon( const PolyPolygon& rPolyPoly )
+{
+ USHORT nPoly = rPolyPoly.Count();
+
+ if ( !nPoly )
+ return;
+
+ if ( nPoly == 1 )
+ {
+ const Polygon rPoly = rPolyPoly.GetObject( 0 );
+ USHORT nSize = rPoly.GetSize();
+ if ( nSize >= 2 )
+ {
+ const SalPoint* pPtAry = (const SalPoint*)rPoly.ImplGetConstPointAry();
+ mpGraphics->DrawPolygon( nSize, pPtAry );
+ }
+ }
+ else
+ {
+ ULONG* pPointAry = new ULONG[nPoly];
+ PCONSTSALPOINT* pPointAryAry = new PCONSTSALPOINT[nPoly];
+ USHORT i = 0;
+ do
+ {
+ const Polygon& rPoly = rPolyPoly.GetObject( i );
+ USHORT nSize = rPoly.GetSize();
+ if ( nSize )
+ {
+ pPointAry[i] = nSize;
+ pPointAryAry[i] = (PCONSTSALPOINT)rPoly.ImplGetConstPointAry();
+ i++;
+ }
+ else
+ nPoly--;
+ }
+ while ( i < nPoly );
+
+ if ( nPoly == 1 )
+ mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry );
+ else
+ mpGraphics->DrawPolyPolygon( nPoly, pPointAry, pPointAryAry );
+
+ delete pPointAry;
+ delete pPointAryAry;
+ }
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+inline UINT8 ImplGetGradientColorValue( long nValue )
+{
+ if ( nValue < 0 )
+ return 0;
+ else if ( nValue > 0xFF )
+ return 0xFF;
+ else
+ return (UINT8)nValue;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawLinearGradient( const Rectangle& rRect,
+ const Gradient& rGradient,
+ BOOL bMtf )
+{
+ // rotiertes BoundRect ausrechnen
+ Rectangle aRect = rRect;
+ aRect.Left()--;
+ aRect.Top()--;
+ aRect.Right()++;
+ aRect.Bottom()++;
+ USHORT nAngle = rGradient.GetAngle();
+ double fAngle = (nAngle % 3600) * F_PI1800;
+ double fWidth = aRect.GetWidth();
+ double fHeight = aRect.GetHeight();
+ double fDX = fWidth * fabs( cos( fAngle ) ) +
+ fHeight * fabs( sin( fAngle ) );
+ double fDY = fHeight * fabs( cos( fAngle ) ) +
+ fWidth * fabs( sin( fAngle ) );
+ fDX = (fDX - fWidth) * 0.5 + 0.5;
+ fDY = (fDY - fHeight) * 0.5 + 0.5;
+ aRect.Left() -= (long)fDX;
+ aRect.Right() += (long)fDX;
+ aRect.Top() -= (long)fDY;
+ aRect.Bottom() += (long)fDY;
+
+ // Rand berechnen und Rechteck neu setzen
+ Point aCenter = rRect.Center();
+ Rectangle aFullRect = aRect;
+ long nBorder = (long)rGradient.GetBorder() * aRect.GetHeight() / 100;
+ BOOL bLinear;
+
+ // Rand berechnen und Rechteck neu setzen fuer linearen Farbverlauf
+ if ( rGradient.GetStyle() == GRADIENT_LINEAR )
+ {
+ bLinear = TRUE;
+ aRect.Top() += nBorder;
+ }
+ // Rand berechnen und Rechteck neu setzen fuer axiale Farbverlauf
+ else
+ {
+ bLinear = FALSE;
+ nBorder >>= 1;
+
+ aRect.Top() += nBorder;
+ aRect.Bottom() -= nBorder;
+ }
+
+ // Top darf nicht groesser als Bottom sein
+ aRect.Top() = Min( aRect.Top(), (long)(aRect.Bottom() - 1) );
+
+ long nMinRect = aRect.GetHeight();
+
+ // Intensitaeten von Start- und Endfarbe ggf. aendern und
+ // Farbschrittweiten berechnen
+ long nFactor;
+ Color aStartCol = rGradient.GetStartColor();
+ Color aEndCol = rGradient.GetEndColor();
+ long nStartRed = aStartCol.GetRed();
+ long nStartGreen = aStartCol.GetGreen();
+ long nStartBlue = aStartCol.GetBlue();
+ long nEndRed = aEndCol.GetRed();
+ long nEndGreen = aEndCol.GetGreen();
+ long nEndBlue = aEndCol.GetBlue();
+ nFactor = rGradient.GetStartIntensity();
+ nStartRed = (nStartRed * nFactor) / 100;
+ nStartGreen = (nStartGreen * nFactor) / 100;
+ nStartBlue = (nStartBlue * nFactor) / 100;
+ nFactor = rGradient.GetEndIntensity();
+ nEndRed = (nEndRed * nFactor) / 100;
+ nEndGreen = (nEndGreen * nFactor) / 100;
+ nEndBlue = (nEndBlue * nFactor) / 100;
+ long nRedSteps = nEndRed - nStartRed;
+ long nGreenSteps = nEndGreen - nStartGreen;
+ long nBlueSteps = nEndBlue - nStartBlue;
+
+ // Bei nicht linearen Farbverlaeufen haben wir nur die halben Steps
+ // pro Farbe
+ if ( !bLinear )
+ {
+ nRedSteps <<= 1;
+ nGreenSteps <<= 1;
+ nBlueSteps <<= 1;
+ }
+
+ // Anzahl der Schritte berechnen, falls nichts uebergeben wurde
+ USHORT nStepCount = rGradient.GetSteps();
+ if ( !nStepCount )
+ {
+ long nInc;
+
+ if ( meOutDevType != OUTDEV_PRINTER && !bMtf )
+ nInc = (nMinRect < 50) ? 2 : 4;
+ else
+ nInc = ((nMinRect >> 9) + 1) << 3;
+
+ if ( !nInc )
+ nInc = 1;
+
+ nStepCount = (USHORT)(nMinRect / nInc);
+ }
+ // minimal drei Schritte und maximal die Anzahl der Farbunterschiede
+ long nSteps = Max( nStepCount, (USHORT)3 );
+ long nCalcSteps = Abs( nRedSteps );
+ long nTempSteps = Abs( nGreenSteps );
+ if ( nTempSteps > nCalcSteps )
+ nCalcSteps = nTempSteps;
+ nTempSteps = Abs( nBlueSteps );
+ if ( nTempSteps > nCalcSteps )
+ nCalcSteps = nTempSteps;
+ if ( nCalcSteps < nSteps )
+ nSteps = nCalcSteps;
+ if ( !nSteps )
+ nSteps = 1;
+
+ // Falls axialer Farbverlauf, muss die Schrittanzahl ungerade sein
+ if ( !bLinear && !(nSteps & 1) )
+ nSteps++;
+
+ // Berechnung ueber Double-Addition wegen Genauigkeit
+ double fScanLine = aRect.Top();
+ double fScanInc = (double)aRect.GetHeight() / (double)nSteps;
+
+ // Startfarbe berechnen und setzen
+ UINT8 nRed;
+ UINT8 nGreen;
+ UINT8 nBlue;
+ long nSteps2;
+ long nStepsHalf;
+ if ( bLinear )
+ {
+ // Um 1 erhoeht, um die Border innerhalb der Schleife
+ // zeichnen zu koennen
+ nSteps2 = nSteps + 1;
+ nRed = (UINT8)nStartRed;
+ nGreen = (UINT8)nStartGreen;
+ nBlue = (UINT8)nStartBlue;
+ }
+ else
+ {
+ // Um 2 erhoeht, um die Border innerhalb der Schleife
+ // zeichnen zu koennen
+ nSteps2 = nSteps + 2;
+ nRed = (UINT8)nEndRed;
+ nGreen = (UINT8)nEndGreen;
+ nBlue = (UINT8)nEndBlue;
+ nStepsHalf = nSteps >> 1;
+ }
+
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), TRUE ) );
+#ifndef REMOTE_APPSERVER
+ else
+ mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
+#endif
+
+ // Startpolygon erzeugen (== Borderpolygon)
+ Polygon aPoly( 4 );
+ Polygon aTempPoly( 2 );
+ aPoly[0] = aFullRect.TopLeft();
+ aPoly[1] = aFullRect.TopRight();
+ aPoly[2] = aRect.TopRight();
+ aPoly[3] = aRect.TopLeft();
+ aPoly.Rotate( aCenter, nAngle );
+
+ // Schleife, um rotierten Verlauf zu fuellen
+ for ( long i = 0; i < nSteps2; i++ )
+ {
+ // berechnetesPolygon ausgeben
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaPolygonAction( aPoly ) );
+#ifndef REMOTE_APPSERVER
+ else
+ ImplDrawPolygon( aPoly );
+#endif
+
+ // neues Polygon berechnen
+ aRect.Top() = (long)(fScanLine += fScanInc);
+
+ // unteren Rand komplett fuellen
+ if ( i == nSteps )
+ {
+ aTempPoly[0] = aFullRect.BottomLeft();
+ aTempPoly[1] = aFullRect.BottomRight();
+ }
+ else
+ {
+ aTempPoly[0] = aRect.TopLeft();
+ aTempPoly[1] = aRect.TopRight();
+ }
+ aTempPoly.Rotate( aCenter, nAngle );
+
+ aPoly[0] = aPoly[3];
+ aPoly[1] = aPoly[2];
+ aPoly[2] = aTempPoly[1];
+ aPoly[3] = aTempPoly[0];
+
+ // Farbintensitaeten aendern...
+ // fuer lineare FV
+ if ( bLinear )
+ {
+ nRed = ImplGetGradientColorValue( nStartRed+((nRedSteps*i)/nSteps2) );
+ nGreen = ImplGetGradientColorValue( nStartGreen+((nGreenSteps*i)/nSteps2) );
+ nBlue = ImplGetGradientColorValue( nStartBlue+((nBlueSteps*i)/nSteps2) );
+ }
+ // fuer radiale FV
+ else
+ {
+ // fuer axiale FV muss die letzte Farbe der ersten
+ // Farbe entsprechen
+ if ( i > nSteps )
+ {
+ nRed = (UINT8)nEndRed;
+ nGreen = (UINT8)nEndGreen;
+ nBlue = (UINT8)nEndBlue;
+ }
+ else
+ {
+ if ( i <= nStepsHalf )
+ {
+ nRed = ImplGetGradientColorValue( nEndRed-((nRedSteps*i)/nSteps2) );
+ nGreen = ImplGetGradientColorValue( nEndGreen-((nGreenSteps*i)/nSteps2) );
+ nBlue = ImplGetGradientColorValue( nEndBlue-((nBlueSteps*i)/nSteps2) );
+ }
+ // genau die Mitte und hoeher
+ else
+ {
+ long i2 = i - nStepsHalf;
+ nRed = ImplGetGradientColorValue( nStartRed+((nRedSteps*i2)/nSteps2) );
+ nGreen = ImplGetGradientColorValue( nStartGreen+((nGreenSteps*i2)/nSteps2) );
+ nBlue = ImplGetGradientColorValue( nStartBlue+((nBlueSteps*i2)/nSteps2) );
+ }
+ }
+ }
+
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), TRUE ) );
+#ifndef REMOTE_APPSERVER
+ else
+ mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawRadialGradient( const Rectangle& rRect,
+ const Gradient& rGradient,
+ BOOL bMtf )
+{
+ // Feststellen ob Ausgabe ueber Polygon oder PolyPolygon
+ // Bei Rasteroperationen ungleich Overpaint immer PolyPolygone,
+ // da es zu falschen Ergebnissen kommt, wenn man mehrfach uebereinander
+ // ausgibt
+ // Bei Druckern auch immer PolyPolygone, da nicht alle Drucker
+ // das Uebereinanderdrucken von Polygonen koennen
+ // Virtuelle Device werden auch ausgeklammert, da einige Treiber
+ // ansonsten zu langsam sind
+ PolyPolygon* pPolyPoly;
+ if ( (meRasterOp != ROP_OVERPAINT) || (meOutDevType != OUTDEV_WINDOW) || bMtf )
+ pPolyPoly = new PolyPolygon( 2 );
+ else
+ pPolyPoly = NULL;
+
+ // Radien-Berechnung fuer Kreisausgabe (Kreis schliesst Rechteck ein)
+ USHORT nAngle = rGradient.GetAngle();
+ Rectangle aFullRect = rRect;
+ Rectangle aRect = rRect;
+ long nZWidth = aRect.GetWidth() * (long)rGradient.GetOfsX() / 100;
+ long nZHeight= aRect.GetHeight() * (long)rGradient.GetOfsY() / 100;
+ Size aSize = aRect.GetSize();
+ Point aCenter( aRect.Left() + nZWidth, aRect.Top() + nZHeight );
+ if ( rGradient.GetStyle() == GRADIENT_RADIAL )
+ {
+ aSize.Width() = (long)(0.5 + sqrt((double)aSize.Width()*(double)aSize.Width() +
+ (double)aSize.Height()*(double)aSize.Height()));
+ aSize.Height() = aSize.Width();
+ }
+ // Radien-Berechnung fuer Ellipse
+ else
+ {
+ aSize.Width() = (long)(0.5 + (double)aSize.Width() * 1.4142);
+ aSize.Height() = (long)(0.5 + (double)aSize.Height() * 1.4142);
+ }
+
+ // Border berechnen
+ long nBorderX = (long)rGradient.GetBorder() * aSize.Width() / 100;
+ long nBorderY = (long)rGradient.GetBorder() * aSize.Height() / 100;
+ aSize.Width() -= nBorderX;
+ aSize.Height() -= nBorderY;
+ aRect.Left() = aCenter.X() - (aSize.Width() >> 1);
+ aRect.Top() = aCenter.Y() - (aSize.Height() >> 1);
+ aRect.SetSize( aSize );
+
+ long nMinRect = Min( aRect.GetWidth(), aRect.GetHeight() );
+
+ // Intensitaeten von Start- und Endfarbe ggf. aendern und
+ // Farbschrittweiten berechnen
+ long nFactor;
+ Color aStartCol = rGradient.GetStartColor();
+ Color aEndCol = rGradient.GetEndColor();
+ long nStartRed = aStartCol.GetRed();
+ long nStartGreen = aStartCol.GetGreen();
+ long nStartBlue = aStartCol.GetBlue();
+ long nEndRed = aEndCol.GetRed();
+ long nEndGreen = aEndCol.GetGreen();
+ long nEndBlue = aEndCol.GetBlue();
+ nFactor = rGradient.GetStartIntensity();
+ nStartRed = (nStartRed * nFactor) / 100;
+ nStartGreen = (nStartGreen * nFactor) / 100;
+ nStartBlue = (nStartBlue * nFactor) / 100;
+ nFactor = rGradient.GetEndIntensity();
+ nEndRed = (nEndRed * nFactor) / 100;
+ nEndGreen = (nEndGreen * nFactor) / 100;
+ nEndBlue = (nEndBlue * nFactor) / 100;
+ long nRedSteps = nEndRed - nStartRed;
+ long nGreenSteps = nEndGreen - nStartGreen;
+ long nBlueSteps = nEndBlue - nStartBlue;
+
+ // Anzahl der Schritte berechnen, falls nichts uebergeben wurde
+ USHORT nStepCount = rGradient.GetSteps();
+ if ( !nStepCount )
+ {
+ long nInc;
+
+ if ( meOutDevType != OUTDEV_PRINTER && !bMtf )
+ nInc = (nMinRect < 50) ? 2 : 4;
+ else
+ nInc = ((nMinRect >> 9) + 1) << 3;
+
+ if ( !nInc )
+ nInc = 1;
+
+ nStepCount = (USHORT)(nMinRect / nInc);
+ }
+ // minimal drei Schritte und maximal die Anzahl der Farbunterschiede
+ long nSteps = Max( nStepCount, (USHORT)3 );
+ long nCalcSteps = Abs( nRedSteps );
+ long nTempSteps = Abs( nGreenSteps );
+ if ( nTempSteps > nCalcSteps )
+ nCalcSteps = nTempSteps;
+ nTempSteps = Abs( nBlueSteps );
+ if ( nTempSteps > nCalcSteps )
+ nCalcSteps = nTempSteps;
+ if ( nCalcSteps < nSteps )
+ nSteps = nCalcSteps;
+ if ( !nSteps )
+ nSteps = 1;
+
+ // Ausgabebegrenzungen und Schrittweite fuer jede Richtung festlegen
+ double fScanLeft = aRect.Left();
+ double fScanTop = aRect.Top();
+ double fScanRight = aRect.Right();
+ double fScanBottom = aRect.Bottom();
+ double fScanInc = (double)nMinRect / (double)nSteps * 0.5;
+
+ // Startfarbe berechnen und setzen
+ UINT8 nRed = (UINT8)nStartRed;
+ UINT8 nGreen = (UINT8)nStartGreen;
+ UINT8 nBlue = (UINT8)nStartBlue;
+
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), TRUE ) );
+#ifndef REMOTE_APPSERVER
+ else
+ mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
+#endif
+
+ // Recteck erstmal ausgeben
+ aFullRect.Bottom()++;
+ aFullRect.Right()++;
+ Polygon aPoly( aFullRect );
+#ifndef REMOTE_APPSERVER
+ if ( pPolyPoly )
+ {
+ pPolyPoly->Insert( aPoly );
+ aPoly = Polygon( aRect );
+ aPoly.Rotate( aCenter, nAngle );
+ pPolyPoly->Insert( aPoly );
+
+ // erstes Polygon zeichnen (entspricht Rechteck)
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( *pPolyPoly ) );
+ else
+ ImplDrawPolyPolygon( *pPolyPoly );
+ }
+ else
+ ImplDrawPolygon( aPoly );
+#else
+ pPolyPoly->Insert( aPoly );
+ aPoly = Polygon( aRect );
+ aPoly.Rotate( aCenter, nAngle );
+ pPolyPoly->Insert( aPoly );
+
+ // erstes Polygon zeichnen (entspricht Rechteck)
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( *pPolyPoly ) );
+#endif
+
+ // Schleife, um nacheinander die Polygone/PolyPolygone auszugeben
+ for ( long i = 0; i < nSteps; i++ )
+ {
+ // neues Polygon berechnen
+ aRect.Left() = (long)(fScanLeft += fScanInc);
+ aRect.Top() = (long)(fScanTop += fScanInc);
+ aRect.Right() = (long)(fScanRight -= fScanInc);
+ aRect.Bottom() = (long)(fScanBottom -= fScanInc);
+
+ if ( (aRect.GetWidth() < 2) || (aRect.GetHeight() < 2) )
+ break;
+
+ // ... Evt. eine maximale Anzahl von Stuetztstellen fuer W16
+ aPoly = Polygon( aRect.Center(),
+ aRect.GetWidth() >> 1,
+ aRect.GetHeight() >> 1 );
+ aPoly.Rotate( aCenter, nAngle );
+
+ // entweder langsame PolyPolygon-Ausgaben oder
+ // schnelles Polygon-Painting
+#ifndef REMOTE_APPSERVER
+ if ( pPolyPoly )
+ {
+ pPolyPoly->Replace( pPolyPoly->GetObject( 1 ), 0 );
+ pPolyPoly->Replace( aPoly, 1 );
+
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( *pPolyPoly ) );
+ else
+ ImplDrawPolyPolygon( *pPolyPoly );
+ }
+ else
+ ImplDrawPolygon( aPoly );
+#else
+ pPolyPoly->Replace( pPolyPoly->GetObject( 1 ), 0 );
+ pPolyPoly->Replace( aPoly, 1 );
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( *pPolyPoly ) );
+#endif
+
+ // Farbe entsprechend anpassen
+ nRed = ImplGetGradientColorValue( nStartRed+((nRedSteps*i)/nSteps) );
+ nGreen = ImplGetGradientColorValue( nStartGreen+((nGreenSteps*i)/nSteps) );
+ nBlue = ImplGetGradientColorValue( nStartBlue+((nBlueSteps*i)/nSteps) );
+
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), TRUE ) );
+#ifndef REMOTE_APPSERVER
+ else
+ mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
+#endif
+ }
+
+ // Falls PolyPolygon-Ausgabe, muessen wir noch ein letztes
+ // inneres Polygon zeichnen
+ if ( pPolyPoly )
+ {
+ const Polygon rPoly = pPolyPoly->GetObject( 1 );
+ if ( !rPoly.GetBoundRect().IsEmpty() )
+ {
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
+#ifndef REMOTE_APPSERVER
+ else
+ ImplDrawPolygon( rPoly );
+#endif
+ }
+ delete pPolyPoly;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawRectGradient( const Rectangle& rRect,
+ const Gradient& rGradient,
+ BOOL bMtf )
+{
+ // Feststellen ob Ausgabe ueber Polygon oder PolyPolygon
+ // Bei Rasteroperationen ungleich Overpaint immer PolyPolygone,
+ // da es zu falschen Ergebnissen kommt, wenn man mehrfach uebereinander
+ // ausgibt
+ // Bei Druckern auch immer PolyPolygone, da nicht alle Drucker
+ // das Uebereinanderdrucken von Polygonen koennen
+ // Virtuelle Device werden auch ausgeklammert, da einige Treiber
+ // ansonsten zu langsam sind
+ PolyPolygon* pPolyPoly;
+ if ( (meRasterOp != ROP_OVERPAINT) || (meOutDevType != OUTDEV_WINDOW) || bMtf )
+ pPolyPoly = new PolyPolygon( 2 );
+ else
+ pPolyPoly = NULL;
+
+ // rotiertes BoundRect ausrechnen
+ Rectangle aRect( rRect );
+ aRect.Left()--;
+ aRect.Top()--;
+ aRect.Right()++;
+ aRect.Bottom()++;
+
+ Rectangle aFullRect( aRect );
+ USHORT nAngle = rGradient.GetAngle();
+ double fAngle = (nAngle % 3600) * F_PI1800;
+ double fWidth = aRect.GetWidth();
+ double fHeight = aRect.GetHeight();
+ double fDX = fWidth * fabs( cos( fAngle ) ) +
+ fHeight * fabs( sin( fAngle ) );
+ double fDY = fHeight * fabs( cos( fAngle ) ) +
+ fWidth * fabs( sin( fAngle ) );
+ fDX = (fDX - fWidth) * 0.5 + 0.5;
+ fDY = (fDY - fHeight) * 0.5 + 0.5;
+ aRect.Left() -= (long)fDX;
+ aRect.Right() += (long)fDX;
+ aRect.Top() -= (long)fDY;
+ aRect.Bottom() += (long)fDY;
+
+ // Quadratisch machen, wenn angefordert;
+ Size aSize = aRect.GetSize();
+ if ( rGradient.GetStyle() == GRADIENT_SQUARE )
+ {
+ if ( aSize.Width() > aSize.Height() )
+ aSize.Height() = aSize.Width();
+ else
+ aSize.Width() = aSize.Height();
+ }
+
+ // neue Mittelpunkte berechnen
+ long nZWidth = aRect.GetWidth() * (long)rGradient.GetOfsX() / 100;
+ long nZHeight = aRect.GetHeight() * (long)rGradient.GetOfsY() / 100;
+ long nBorderX = (long)rGradient.GetBorder() * aSize.Width() / 100;
+ long nBorderY = (long)rGradient.GetBorder() * aSize.Height() / 100;
+ Point aCenter( aRect.Left() + nZWidth, aRect.Top() + nZHeight );
+
+ // Rand beruecksichtigen
+ aSize.Width() -= nBorderX;
+ aSize.Height() -= nBorderY;
+
+ // Ausgaberechteck neu setzen
+ aRect.Left() = aCenter.X() - (aSize.Width() >> 1);
+ aRect.Top() = aCenter.Y() - (aSize.Height() >> 1);
+ aRect.SetSize( aSize );
+
+ long nMinRect = Min( aRect.GetWidth(), aRect.GetHeight() );
+
+ // Intensitaeten von Start- und Endfarbe ggf. aendern und
+ // Farbschrittweiten berechnen
+ long nFactor;
+ Color aStartCol = rGradient.GetStartColor();
+ Color aEndCol = rGradient.GetEndColor();
+ long nStartRed = aStartCol.GetRed();
+ long nStartGreen = aStartCol.GetGreen();
+ long nStartBlue = aStartCol.GetBlue();
+ long nEndRed = aEndCol.GetRed();
+ long nEndGreen = aEndCol.GetGreen();
+ long nEndBlue = aEndCol.GetBlue();
+ nFactor = rGradient.GetStartIntensity();
+ nStartRed = (nStartRed * nFactor) / 100;
+ nStartGreen = (nStartGreen * nFactor) / 100;
+ nStartBlue = (nStartBlue * nFactor) / 100;
+ nFactor = rGradient.GetEndIntensity();
+ nEndRed = (nEndRed * nFactor) / 100;
+ nEndGreen = (nEndGreen * nFactor) / 100;
+ nEndBlue = (nEndBlue * nFactor) / 100;
+ long nRedSteps = nEndRed - nStartRed;
+ long nGreenSteps = nEndGreen - nStartGreen;
+ long nBlueSteps = nEndBlue - nStartBlue;
+
+ // Anzahl der Schritte berechnen, falls nichts uebergeben wurde
+ USHORT nStepCount = rGradient.GetSteps();
+ if ( !nStepCount )
+ {
+ long nInc;
+
+ if ( meOutDevType != OUTDEV_PRINTER && !bMtf )
+ nInc = (nMinRect < 50) ? 2 : 4;
+ else
+ nInc = ((nMinRect >> 9) + 1) << 3;
+
+ if ( !nInc )
+ nInc = 1;
+
+ nStepCount = (USHORT)(nMinRect / nInc);
+ }
+ // minimal drei Schritte und maximal die Anzahl der Farbunterschiede
+ long nSteps = Max( nStepCount, (USHORT)3 );
+ long nCalcSteps = Abs( nRedSteps );
+ long nTempSteps = Abs( nGreenSteps );
+ if ( nTempSteps > nCalcSteps )
+ nCalcSteps = nTempSteps;
+ nTempSteps = Abs( nBlueSteps );
+ if ( nTempSteps > nCalcSteps )
+ nCalcSteps = nTempSteps;
+ if ( nCalcSteps < nSteps )
+ nSteps = nCalcSteps;
+ if ( !nSteps )
+ nSteps = 1;
+
+ // Ausgabebegrenzungen und Schrittweite fuer jede Richtung festlegen
+ double fScanLeft = aRect.Left();
+ double fScanTop = aRect.Top();
+ double fScanRight = aRect.Right();
+ double fScanBottom = aRect.Bottom();
+ double fScanInc = (double)nMinRect / (double)nSteps * 0.5;
+
+ // Startfarbe berechnen und setzen
+ UINT8 nRed = (UINT8)nStartRed;
+ UINT8 nGreen = (UINT8)nStartGreen;
+ UINT8 nBlue = (UINT8)nStartBlue;
+
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), TRUE ) );
+#ifndef REMOTE_APPSERVER
+ else
+ mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
+#endif
+
+ // Recteck erstmal ausgeben
+ Polygon aPoly( aFullRect );
+#ifndef REMOTE_APPSERVER
+ if ( pPolyPoly )
+ {
+ pPolyPoly->Insert( aPoly );
+ aPoly = Polygon( aRect );
+ aPoly.Rotate( aCenter, nAngle );
+ pPolyPoly->Insert( aPoly );
+
+ // erstes Polygon zeichnen (entspricht Rechteck)
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( *pPolyPoly ) );
+ else
+ ImplDrawPolyPolygon( *pPolyPoly );
+ }
+ else
+ ImplDrawPolygon( aPoly );
+#else
+ pPolyPoly->Insert( aPoly );
+ aPoly = Polygon( aRect );
+ aPoly.Rotate( aCenter, nAngle );
+ pPolyPoly->Insert( aPoly );
+
+ // erstes Polygon zeichnen (entspricht Rechteck)
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( *pPolyPoly ) );
+#endif
+
+ // Schleife, um nacheinander die Polygone/PolyPolygone auszugeben
+ for ( long i = 0; i < nSteps; i++ )
+ {
+ // neues Polygon berechnen
+ aRect.Left() = (long)(fScanLeft += fScanInc);
+ aRect.Top() = (long)(fScanTop += fScanInc);
+ aRect.Right() = (long)(fScanRight -= fScanInc);
+ aRect.Bottom() = (long)(fScanBottom-= fScanInc);
+
+ if ( (aRect.GetWidth() < 2) || (aRect.GetHeight() < 2) )
+ break;
+
+ aPoly = Polygon( aRect );
+ aPoly.Rotate( aCenter, nAngle );
+
+#ifndef REMOTE_APPSERVER
+ // entweder langsame PolyPolygon-Ausgaben oder
+ // schnelles Polygon-Painting
+ if ( pPolyPoly )
+ {
+ pPolyPoly->Replace( pPolyPoly->GetObject( 1 ), 0 );
+ pPolyPoly->Replace( aPoly, 1 );
+
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( *pPolyPoly ) );
+ else
+ ImplDrawPolyPolygon( *pPolyPoly );
+ }
+ else
+ ImplDrawPolygon( aPoly );
+#else
+ pPolyPoly->Replace( pPolyPoly->GetObject( 1 ), 0 );
+ pPolyPoly->Replace( aPoly, 1 );
+ mpMetaFile->AddAction( new MetaPolyPolygonAction( *pPolyPoly ) );
+#endif
+
+ // Farbe entsprechend anpassen
+ nRed = ImplGetGradientColorValue( nStartRed+((nRedSteps*i)/nSteps) );
+ nGreen = ImplGetGradientColorValue( nStartGreen+((nGreenSteps*i)/nSteps) );
+ nBlue = ImplGetGradientColorValue( nStartBlue+((nBlueSteps*i)/nSteps) );
+
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), TRUE ) );
+#ifndef REMOTE_APPSERVER
+ else
+ mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
+#endif
+ }
+
+ // Falls PolyPolygon-Ausgabe, muessen wir noch ein letztes
+ // inneres Polygon zeichnen
+ if ( pPolyPoly )
+ {
+ const Polygon rPoly = pPolyPoly->GetObject( 1 );
+ if ( !rPoly.GetBoundRect().IsEmpty() )
+ {
+ if ( bMtf )
+ mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
+#ifndef REMOTE_APPSERVER
+ else
+ ImplDrawPolygon( rPoly );
+#endif
+ }
+ delete pPolyPoly;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawGradient( const Rectangle& rRect,
+ const Gradient& rGradient )
+{
+ DBG_TRACE( "OutputDevice::DrawGradient()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rGradient, Gradient, NULL );
+
+ if ( mnDrawMode & DRAWMODE_NOGRADIENT )
+ return;
+ else if ( mnDrawMode & ( DRAWMODE_BLACKGRADIENT | DRAWMODE_WHITEGRADIENT ) )
+ {
+ BYTE cCmpVal;
+
+ if ( mnDrawMode & DRAWMODE_BLACKGRADIENT )
+ cCmpVal = ( mnDrawMode & DRAWMODE_GHOSTEDGRADIENT ) ? 0x80 : 0;
+ else
+ cCmpVal = 255;
+
+ Color aCol( cCmpVal, cCmpVal, cCmpVal );
+ Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ SetLineColor( aCol );
+ SetFillColor( aCol );
+ DrawRect( rRect );
+ Pop();
+ return;
+ }
+
+ Gradient aGradient( rGradient );
+
+ if ( mnDrawMode & ( DRAWMODE_GRAYGRADIENT | DRAWMODE_GHOSTEDGRADIENT ) )
+ {
+ Color aStartCol( aGradient.GetStartColor() );
+ Color aEndCol( aGradient.GetEndColor() );
+
+ if ( mnDrawMode & DRAWMODE_GRAYGRADIENT )
+ {
+ BYTE cStartLum = aStartCol.GetLuminance(), cEndLum = aEndCol.GetLuminance();
+ aStartCol = Color( cStartLum, cStartLum, cStartLum );
+ aEndCol = Color( cEndLum, cEndLum, cEndLum );
+ }
+
+ if ( mnDrawMode & DRAWMODE_GHOSTEDGRADIENT )
+ {
+ aStartCol = Color( ( aStartCol.GetRed() >> 1 ) | 0x80,
+ ( aStartCol.GetGreen() >> 1 ) | 0x80,
+ ( aStartCol.GetBlue() >> 1 ) | 0x80 );
+
+ aEndCol = Color( ( aEndCol.GetRed() >> 1 ) | 0x80,
+ ( aEndCol.GetGreen() >> 1 ) | 0x80,
+ ( aEndCol.GetBlue() >> 1 ) | 0x80 );
+ }
+
+ aGradient.SetStartColor( aStartCol );
+ aGradient.SetEndColor( aEndCol );
+ }
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaGradientAction( rRect, aGradient ) );
+
+ if( !IsDeviceOutputNecessary() )
+ return;
+
+ // Rechteck in Pixel umrechnen
+ Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+ aRect.Justify();
+
+ // Wenn Rechteck leer ist, brauchen wir nichts machen
+ if ( !aRect.IsEmpty() )
+ {
+#ifndef REMOTE_APPSERVER
+ // Clip Region sichern
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( rRect );
+
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if ( !mbOutputClipped )
+ {
+ // Gradienten werden ohne Umrandung gezeichnet
+ if ( mbLineColor || mbInitLineColor )
+ {
+ mpGraphics->SetLineColor();
+ mbInitLineColor = TRUE;
+ }
+
+ mbInitFillColor = TRUE;
+
+ // calculate step count if neccessary
+ if ( !aGradient.GetSteps() )
+ aGradient.SetSteps( GRADIENT_DEFAULT_STEPCOUNT );
+
+ // Farbverlauf ausgeben
+ switch( aGradient.GetStyle() )
+ {
+ case GRADIENT_LINEAR:
+ case GRADIENT_AXIAL:
+ ImplDrawLinearGradient( aRect, aGradient, FALSE );
+ break;
+
+ case GRADIENT_RADIAL:
+ case GRADIENT_ELLIPTICAL:
+ ImplDrawRadialGradient( aRect, aGradient, FALSE );
+ break;
+
+ case GRADIENT_SQUARE:
+ case GRADIENT_RECT:
+ ImplDrawRectGradient( aRect, aGradient, FALSE );
+ break;
+ }
+ }
+
+ Pop();
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ pGraphics->DrawGradient( aRect, aGradient );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawGradient( const PolyPolygon& rPolyPoly,
+ const Gradient& rGradient )
+{
+ DBG_TRACE( "OutputDevice::DrawGradient()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rGradient, Gradient, NULL );
+
+ if( rPolyPoly.Count() && rPolyPoly[ 0 ].GetSize() && !( mnDrawMode & DRAWMODE_NOGRADIENT ) )
+ {
+ if( mnDrawMode & ( DRAWMODE_BLACKGRADIENT | DRAWMODE_WHITEGRADIENT ) )
+ {
+ BYTE cCmpVal;
+
+ if ( mnDrawMode & DRAWMODE_BLACKGRADIENT )
+ cCmpVal = ( mnDrawMode & DRAWMODE_GHOSTEDGRADIENT ) ? 0x80 : 0;
+ else
+ cCmpVal = 255;
+
+ Color aCol( cCmpVal, cCmpVal, cCmpVal );
+ Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ SetLineColor( aCol );
+ SetFillColor( aCol );
+ DrawPolyPolygon( rPolyPoly );
+ Pop();
+ return;
+ }
+
+ if( mpMetaFile )
+ {
+ const Rectangle aRect( rPolyPoly.GetBoundRect() );
+
+ if( OUTDEV_PRINTER == meOutDevType )
+ {
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( rPolyPoly );
+ DrawGradient( aRect, rGradient );
+ Pop();
+ }
+ else
+ {
+ const BOOL bOldOutput = IsOutputEnabled();
+
+ EnableOutput( FALSE );
+ Push( PUSH_RASTEROP );
+ SetRasterOp( ROP_XOR );
+ DrawGradient( aRect, rGradient );
+ SetFillColor( COL_BLACK );
+ SetRasterOp( ROP_0 );
+ DrawPolyPolygon( rPolyPoly );
+ SetRasterOp( ROP_XOR );
+ DrawGradient( aRect, rGradient );
+ Pop();
+ EnableOutput( bOldOutput );
+ }
+ }
+
+ if( !IsDeviceOutputNecessary() )
+ return;
+
+ Gradient aGradient( rGradient );
+
+ if ( mnDrawMode & ( DRAWMODE_GRAYGRADIENT | DRAWMODE_GHOSTEDGRADIENT ) )
+ {
+ Color aStartCol( aGradient.GetStartColor() );
+ Color aEndCol( aGradient.GetEndColor() );
+
+ if ( mnDrawMode & DRAWMODE_GRAYGRADIENT )
+ {
+ BYTE cStartLum = aStartCol.GetLuminance(), cEndLum = aEndCol.GetLuminance();
+ aStartCol = Color( cStartLum, cStartLum, cStartLum );
+ aEndCol = Color( cEndLum, cEndLum, cEndLum );
+ }
+
+ if ( mnDrawMode & DRAWMODE_GHOSTEDGRADIENT )
+ {
+ aStartCol = Color( ( aStartCol.GetRed() >> 1 ) | 0x80,
+ ( aStartCol.GetGreen() >> 1 ) | 0x80,
+ ( aStartCol.GetBlue() >> 1 ) | 0x80 );
+
+ aEndCol = Color( ( aEndCol.GetRed() >> 1 ) | 0x80,
+ ( aEndCol.GetGreen() >> 1 ) | 0x80,
+ ( aEndCol.GetBlue() >> 1 ) | 0x80 );
+ }
+
+ aGradient.SetStartColor( aStartCol );
+ aGradient.SetEndColor( aEndCol );
+ }
+
+#ifndef REMOTE_APPSERVER
+ if( OUTDEV_PRINTER == meOutDevType )
+ {
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( rPolyPoly );
+ DrawGradient( rPolyPoly.GetBoundRect(), aGradient );
+ Pop();
+ }
+ else
+ {
+ const PolyPolygon aPolyPoly( LogicToPixel( rPolyPoly ) );
+ const Rectangle aBoundRect( aPolyPoly.GetBoundRect() );
+ Point aPoint;
+ Rectangle aDstRect( aPoint, GetOutputSizePixel() );
+
+ aDstRect.Intersection( aBoundRect );
+
+ if( OUTDEV_WINDOW == meOutDevType )
+ {
+ const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
+
+ if( !aPaintRgn.IsNull() )
+ aDstRect.Intersection( LogicToPixel( aPaintRgn ).GetBoundRect() );
+ }
+
+ if( !aDstRect.IsEmpty() )
+ {
+ VirtualDevice aVDev;
+ const Size aDstSize( aDstRect.GetSize() );
+
+ if( aVDev.SetOutputSizePixel( aDstSize) )
+ {
+ MapMode aVDevMap;
+ const RasterOp eOldROP = GetRasterOp();
+ const BOOL bOldMap = mbMap;
+
+ mbMap = FALSE;
+
+ aVDev.DrawOutDev( Point(), aDstSize, aDstRect.TopLeft(), aDstSize, *this );
+ DrawGradient( aBoundRect, aGradient );
+ aVDev.SetRasterOp( ROP_XOR );
+ aVDev.DrawOutDev( Point(), aDstSize, aDstRect.TopLeft(), aDstSize, *this );
+ aVDev.SetFillColor( COL_BLACK );
+ aVDev.SetRasterOp( ROP_0 );
+ aVDevMap.SetOrigin( Point( -aDstRect.Left(), -aDstRect.Top() ) );
+ aVDev.SetMapMode( aVDevMap );
+ aVDev.DrawPolyPolygon( aPolyPoly );
+ aVDevMap.SetOrigin( Point() );
+ aVDev.SetMapMode( aVDevMap );
+ SetRasterOp( ROP_XOR );
+ DrawOutDev( aDstRect.TopLeft(), aDstSize, Point(), aDstSize, aVDev );
+ SetRasterOp( eOldROP );
+
+ mbMap = bOldMap;
+ }
+ }
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ pGraphics->DrawGradient( ImplLogicToDevicePixel( rPolyPoly ), aGradient );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::AddGradientActions( const Rectangle& rRect, const Gradient& rGradient,
+ GDIMetaFile& rMtf )
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rGradient, Gradient, NULL );
+
+ Rectangle aRect( rRect );
+
+ aRect.Justify();
+
+ // Wenn Rechteck leer ist, brauchen wir nichts machen
+ if ( !aRect.IsEmpty() )
+ {
+ Gradient aGradient( rGradient );
+ GDIMetaFile* pOldMtf = mpMetaFile;
+
+ mpMetaFile = &rMtf;
+ mpMetaFile->AddAction( new MetaPushAction( PUSH_ALL ) );
+ mpMetaFile->AddAction( new MetaISectRectClipRegionAction( aRect ) );
+ mpMetaFile->AddAction( new MetaLineColorAction( Color(), FALSE ) );
+
+ // calculate step count if neccessary
+ if ( !aGradient.GetSteps() )
+ aGradient.SetSteps( GRADIENT_DEFAULT_STEPCOUNT );
+
+ // Farbverlaufactions aufzeichnen
+ switch( rGradient.GetStyle() )
+ {
+ case GRADIENT_LINEAR:
+ case GRADIENT_AXIAL:
+ ImplDrawLinearGradient( aRect, aGradient, TRUE );
+ break;
+
+ case GRADIENT_RADIAL:
+ case GRADIENT_ELLIPTICAL:
+ ImplDrawRadialGradient( aRect, aGradient, TRUE );
+ break;
+
+ case GRADIENT_SQUARE:
+ case GRADIENT_RECT:
+ ImplDrawRectGradient( aRect, aGradient, TRUE );
+ break;
+ }
+
+ mpMetaFile->AddAction( new MetaPopAction() );
+ mpMetaFile = pOldMtf;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawHatch( const PolyPolygon& rPolyPoly, const Hatch& rHatch )
+{
+ DBG_TRACE( "OutputDevice::DrawHatch()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Hatch aHatch( rHatch );
+
+ if ( mnDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE |
+ DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE ) )
+ {
+ Color aColor( rHatch.GetColor() );
+
+ if ( mnDrawMode & DRAWMODE_BLACKLINE )
+ aColor = Color( COL_BLACK );
+ else if ( mnDrawMode & DRAWMODE_WHITELINE )
+ aColor = Color( COL_WHITE );
+ else if ( mnDrawMode & DRAWMODE_GRAYLINE )
+ {
+ const UINT8 cLum = aColor.GetLuminance();
+ aColor = Color( cLum, cLum, cLum );
+ }
+
+ if ( mnDrawMode & DRAWMODE_GHOSTEDLINE )
+ {
+ aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
+ ( aColor.GetGreen() >> 1 ) | 0x80,
+ ( aColor.GetBlue() >> 1 ) | 0x80);
+ }
+
+ aHatch.SetColor( aColor );
+ }
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaHatchAction( rPolyPoly, aHatch ) );
+
+ if( !IsDeviceOutputNecessary() )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ if( !mpGraphics && !ImplGetGraphics() )
+ return;
+
+ if( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if( mbOutputClipped )
+ return;
+#endif
+
+ PolyPolygon aPolyPoly( rPolyPoly );
+ aPolyPoly.Optimize( POLY_OPTIMIZE_NO_SAME | POLY_OPTIMIZE_CLOSE );
+
+ if( aPolyPoly.Count() )
+ {
+#ifndef REMOTE_APPSERVER
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+
+ mpMetaFile = NULL;
+ Push( PUSH_LINECOLOR );
+ SetLineColor( aHatch.GetColor() );
+ ImplInitLineColor();
+ ImplDrawHatch( aPolyPoly, aHatch, FALSE );
+ Pop();
+ mpMetaFile = pOldMetaFile;
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ aHatch.SetDistance( ImplLogicWidthToDevicePixel( aHatch.GetDistance() ) );
+ pGraphics->DrawHatch( ImplLogicToDevicePixel( aPolyPoly ), aHatch );
+ }
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::AddHatchActions( const PolyPolygon& rPolyPoly, const Hatch& rHatch,
+ GDIMetaFile& rMtf )
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ PolyPolygon aPolyPoly( rPolyPoly );
+ aPolyPoly.Optimize( POLY_OPTIMIZE_NO_SAME | POLY_OPTIMIZE_CLOSE );
+
+ if( aPolyPoly.Count() )
+ {
+ GDIMetaFile* pOldMtf = mpMetaFile;
+
+ mpMetaFile = &rMtf;
+ mpMetaFile->AddAction( new MetaPushAction( PUSH_ALL ) );
+ mpMetaFile->AddAction( new MetaLineColorAction( rHatch.GetColor(), TRUE ) );
+ ImplDrawHatch( aPolyPoly, rHatch, TRUE );
+ mpMetaFile->AddAction( new MetaPopAction() );
+ mpMetaFile = pOldMtf;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawHatch( const PolyPolygon& rPolyPoly, const Hatch& rHatch, BOOL bMtf )
+{
+ Rectangle aRect( rPolyPoly.GetBoundRect() );
+ const long nLogPixelWidth = ImplDevicePixelToLogicWidth( 1 );
+ const long nWidth = ImplDevicePixelToLogicWidth( Max( ImplLogicWidthToDevicePixel( rHatch.GetDistance() ), 5L ) );
+ Point* pPtBuffer = new Point[ HATCH_MAXPOINTS ];
+ Point aPt1, aPt2, aEndPt1;
+ Size aInc;
+
+ // Single hatch
+ aRect.Left() -= nLogPixelWidth; aRect.Top() -= nLogPixelWidth; aRect.Right() += nLogPixelWidth; aRect.Bottom() += nLogPixelWidth;
+ ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle(), aPt1, aPt2, aInc, aEndPt1 );
+ do
+ {
+ ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf );
+ aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height();
+ aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height();
+ }
+ while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) );
+
+ if( ( rHatch.GetStyle() == HATCH_DOUBLE ) || ( rHatch.GetStyle() == HATCH_TRIPLE ) )
+ {
+ // Double hatch
+ ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle() + 900, aPt1, aPt2, aInc, aEndPt1 );
+ do
+ {
+ ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf );
+ aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height();
+ aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height();
+ }
+ while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) );
+
+ if( rHatch.GetStyle() == HATCH_TRIPLE )
+ {
+ // Triple hatch
+ ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle() + 450, aPt1, aPt2, aInc, aEndPt1 );
+ do
+ {
+ ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf );
+ aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height();
+ aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height();
+ }
+ while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) );
+ }
+ }
+
+ delete[] pPtBuffer;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplCalcHatchValues( const Rectangle& rRect, long nDist, USHORT nAngle10,
+ Point& rPt1, Point& rPt2, Size& rInc, Point& rEndPt1 )
+{
+ Point aRef;
+ long nAngle = nAngle10 % 1800;
+ long nOffset = 0;
+
+ if( nAngle > 900 )
+ nAngle -= 1800;
+
+ aRef = ( !IsRefPoint() ? rRect.TopLeft() : GetRefPoint() );
+
+ if( 0 == nAngle )
+ {
+ rInc = Size( 0, nDist );
+ rPt1 = rRect.TopLeft();
+ rPt2 = rRect.TopRight();
+ rEndPt1 = rRect.BottomLeft();
+
+ if( aRef.Y() <= rRect.Top() )
+ nOffset = ( ( rRect.Top() - aRef.Y() ) % nDist );
+ else
+ nOffset = ( nDist - ( ( aRef.Y() - rRect.Top() ) % nDist ) );
+
+ rPt1.Y() -= nOffset;
+ rPt2.Y() -= nOffset;
+ }
+ else if( 900 == nAngle )
+ {
+ rInc = Size( nDist, 0 );
+ rPt1 = rRect.TopLeft();
+ rPt2 = rRect.BottomLeft();
+ rEndPt1 = rRect.TopRight();
+
+ if( aRef.X() <= rRect.Left() )
+ nOffset = ( rRect.Left() - aRef.X() ) % nDist;
+ else
+ nOffset = nDist - ( ( aRef.X() - rRect.Left() ) % nDist );
+
+ rPt1.X() -= nOffset;
+ rPt2.X() -= nOffset;
+ }
+ else if( nAngle >= -450 && nAngle <= 450 )
+ {
+ const double fAngle = F_PI1800 * labs( nAngle );
+ const double fTan = tan( fAngle );
+ const long nYOff = FRound( ( rRect.Right() - rRect.Left() ) * fTan );
+ long nPY;
+
+ rInc = Size( 0, nDist = FRound( nDist / cos( fAngle ) ) );
+
+ if( nAngle > 0 )
+ {
+ rPt1 = rRect.TopLeft();
+ rPt2 = Point( rRect.Right(), rRect.Top() - nYOff );
+ rEndPt1 = Point( rRect.Left(), rRect.Bottom() + nYOff );
+ nPY = FRound( aRef.Y() - ( ( rPt1.X() - aRef.X() ) * fTan ) );
+ }
+ else
+ {
+ rPt1 = rRect.TopRight();
+ rPt2 = Point( rRect.Left(), rRect.Top() - nYOff );
+ rEndPt1 = Point( rRect.Right(), rRect.Bottom() + nYOff );
+ nPY = FRound( aRef.Y() + ( ( rPt1.X() - aRef.X() ) * fTan ) );
+ }
+
+ if( nPY <= rPt1.Y() )
+ nOffset = ( rPt1.Y() - nPY ) % nDist;
+ else
+ nOffset = nDist - ( ( nPY - rPt1.Y() ) % nDist );
+
+ rPt1.Y() -= nOffset;
+ rPt2.Y() -= nOffset;
+ }
+ else
+ {
+ const double fAngle = F_PI1800 * labs( nAngle );
+ const double fTan = tan( fAngle );
+ const long nXOff = FRound( ( rRect.Bottom() - rRect.Top() ) / fTan );
+ long nPX;
+
+ rInc = Size( nDist = FRound( nDist / sin( fAngle ) ), 0 );
+
+ if( nAngle > 0 )
+ {
+ rPt1 = rRect.TopLeft();
+ rPt2 = Point( rRect.Left() - nXOff, rRect.Bottom() );
+ rEndPt1 = Point( rRect.Right() + nXOff, rRect.Top() );
+ nPX = FRound( aRef.X() - ( ( rPt1.Y() - aRef.Y() ) / fTan ) );
+ }
+ else
+ {
+ rPt1 = rRect.BottomLeft();
+ rPt2 = Point( rRect.Left() - nXOff, rRect.Top() );
+ rEndPt1 = Point( rRect.Right() + nXOff, rRect.Bottom() );
+ nPX = FRound( aRef.X() + ( ( rPt1.Y() - aRef.Y() ) / fTan ) );
+ }
+
+ if( nPX <= rPt1.X() )
+ nOffset = ( rPt1.X() - nPX ) % nDist;
+ else
+ nOffset = nDist - ( ( nPX - rPt1.X() ) % nDist );
+
+ rPt1.X() -= nOffset;
+ rPt2.X() -= nOffset;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void OutputDevice::ImplDrawHatchLine( const Line& rLine, const PolyPolygon& rPolyPoly,
+ Point* pPtBuffer, BOOL bMtf )
+{
+#ifdef REMOTE_APPSERVER
+ ImplServerGraphics* pGraphics;
+ if( !bMtf && !( pGraphics = ImplGetServerGraphics() ) )
+ return;
+#endif
+
+ double fSaveDist = 0.0;
+ long nPCounter = 0;
+
+ for( long nPoly = 0, nPolyCount = rPolyPoly.Count(); nPoly < nPolyCount; nPoly++ )
+ {
+ const Polygon& rPoly = rPolyPoly[ (USHORT) nPoly ];
+
+ if( rPoly.GetSize() > 1 )
+ {
+ Point aIntersection;
+ Point aPt1( rPoly[0] );
+
+ for( long i = 1, nCount = rPoly.GetSize(); i < nCount; i++ )
+ {
+ const Point& rPt2 = rPoly[ (USHORT) i ];
+
+ if( rLine.Intersection( Line( aPt1, rPt2 ), aIntersection ) )
+ {
+ const BOOL bDifferent = !nPCounter || aIntersection != pPtBuffer[ nPCounter - 1 ];
+
+ if( aIntersection == aPt1 )
+ {
+ double fDist1 = rLine.GetDistance( rPoly[ ( i > 1 ) ? i - 2 : nCount - 2 ] );
+ double fDist2 = rLine.GetDistance( rPt2 );
+
+ if( 1 == i )
+ nCount--;
+
+ if( bDifferent )
+ {
+ pPtBuffer[ nPCounter++ ] = aIntersection;
+
+ if( ( ( fDist1 < 0.0 && fDist2 < 0.0 ) || ( fDist1 > 0.0 && fDist2 > 0.0 ) ) )
+ pPtBuffer[ nPCounter++ ] = aIntersection;
+ else if( fDist1 == 0.0 )
+ {
+ if( ( fSaveDist > 0.0 && fDist2 < 0.0 ) || ( fSaveDist < 0.0 && fDist2 > 0.0 ) )
+ pPtBuffer[ nPCounter++ ] = aIntersection;
+ }
+ }
+ }
+ else if( aIntersection == rPt2 )
+ {
+ double fDist1 = rLine.GetDistance( aPt1 );
+ double fDist2 = rLine.GetDistance( rPoly[ ( i < nCount - 1 ) ? i + 1 : 1 ] );
+
+ if( bDifferent )
+ {
+ pPtBuffer[ nPCounter++ ] = aIntersection;
+
+ if( ( ( fDist1 < 0.0 && fDist2 < 0.0 ) || ( fDist1 > 0.0 && fDist2 > 0.0 ) ) )
+ pPtBuffer[ nPCounter++ ] = aIntersection;
+ else if( fDist2 == 0.0 )
+ fSaveDist = fDist1;
+ }
+ }
+ else
+ pPtBuffer[ nPCounter++ ] = aIntersection;
+ }
+
+ aPt1 = rPt2;
+ }
+ }
+ }
+
+ if( nPCounter > 1 )
+ {
+ qsort( pPtBuffer, nPCounter, sizeof( Point ), ImplHatchCmpFnc );
+
+ if( nPCounter & 1 )
+ nPCounter--;
+
+ if( bMtf )
+ {
+ for( long i = 0; i < nPCounter; i += 2 )
+ mpMetaFile->AddAction( new MetaLineAction( pPtBuffer[ i ], pPtBuffer[ i + 1 ] ) );
+ }
+ else
+ {
+ for( long i = 0; i < nPCounter; i += 2 )
+ {
+ const Point aPt1( ImplLogicToDevicePixel( pPtBuffer[ i ] ) );
+ const Point aPt2( ImplLogicToDevicePixel( pPtBuffer[ i + 1 ] ) );
+
+#ifndef REMOTE_APPSERVER
+ mpGraphics->DrawLine( aPt1.X(), aPt1.Y(), aPt2.X(), aPt2.Y() );
+#else
+ pGraphics->DrawLine( aPt1, aPt2 );
+#endif
+ }
+ }
+ }
+}
diff --git a/vcl/source/gdi/outdev5.cxx b/vcl/source/gdi/outdev5.cxx
new file mode 100644
index 000000000000..f162b1196fd1
--- /dev/null
+++ b/vcl/source/gdi/outdev5.cxx
@@ -0,0 +1,430 @@
+/*************************************************************************
+ *
+ * $RCSfile: outdev5.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_OUTDEV_CXX
+#include <tools/ref.hxx>
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#endif
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#else
+#ifndef _SV_RMOUTDEV_HXX
+#include <rmoutdev.hxx>
+#endif
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_POLY_H
+#include <poly.h>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_OUTDATA_HXX
+#include <outdata.hxx>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+
+// =======================================================================
+
+DBG_NAMEEX( OutputDevice );
+
+// =======================================================================
+
+void OutputDevice::DrawRect( const Rectangle& rRect,
+ ULONG nHorzRound, ULONG nVertRound )
+{
+ DBG_TRACE( "OutputDevice::DrawRoundRect()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaRoundRectAction( rRect, nHorzRound, nVertRound ) );
+
+ if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) )
+ return;
+
+ const Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+
+ if ( aRect.IsEmpty() )
+ return;
+
+ nHorzRound = ImplLogicWidthToDevicePixel( nHorzRound );
+ nVertRound = ImplLogicHeightToDevicePixel( nVertRound );
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+
+ if ( !nHorzRound && !nVertRound )
+ mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight() );
+ else
+ {
+ const Polygon aRoundRectPoly( aRect, nHorzRound, nVertRound );
+
+ if ( aRoundRectPoly.GetSize() >= 2 )
+ {
+ const SalPoint* pPtAry = (const SalPoint*) aRoundRectPoly.ImplGetConstPointAry();
+
+ if ( !mbFillColor )
+ mpGraphics->DrawPolyLine( aRoundRectPoly.GetSize(), pPtAry );
+ else
+ mpGraphics->DrawPolygon( aRoundRectPoly.GetSize(), pPtAry );
+ }
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ if ( !nHorzRound || !nVertRound )
+ pGraphics->DrawRect( aRect );
+ else
+ pGraphics->DrawRect( aRect, nHorzRound, nVertRound );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawEllipse( const Rectangle& rRect )
+{
+ DBG_TRACE( "OutputDevice::DrawEllipse()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaEllipseAction( rRect ) );
+
+ if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) )
+ return;
+
+ Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+ if ( aRect.IsEmpty() )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ Polygon aRectPoly( aRect.Center(), aRect.GetWidth() >> 1, aRect.GetHeight() >> 1 );
+ if ( aRectPoly.GetSize() >= 2 )
+ {
+ const SalPoint* pPtAry = (const SalPoint*)aRectPoly.ImplGetConstPointAry();
+ if ( !mbFillColor )
+ mpGraphics->DrawPolyLine( aRectPoly.GetSize(), pPtAry );
+ else
+ {
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ mpGraphics->DrawPolygon( aRectPoly.GetSize(), pPtAry );
+ }
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ pGraphics->DrawEllipse( aRect );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawArc( const Rectangle& rRect,
+ const Point& rStartPt, const Point& rEndPt )
+{
+ DBG_TRACE( "OutputDevice::DrawArc()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaArcAction( rRect, rStartPt, rEndPt ) );
+
+ if ( !IsDeviceOutputNecessary() || !mbLineColor )
+ return;
+
+ Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+ if ( aRect.IsEmpty() )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ const Point aStart( ImplLogicToDevicePixel( rStartPt ) );
+ const Point aEnd( ImplLogicToDevicePixel( rEndPt ) );
+ Polygon aArcPoly( aRect, aStart, aEnd, POLY_ARC );
+
+ if ( aArcPoly.GetSize() >= 2 )
+ {
+ const SalPoint* pPtAry = (const SalPoint*)aArcPoly.ImplGetConstPointAry();
+ mpGraphics->DrawPolyLine( aArcPoly.GetSize(), pPtAry );
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ pGraphics->DrawArc( aRect,
+ ImplLogicToDevicePixel( rStartPt ),
+ ImplLogicToDevicePixel( rEndPt ) );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawPie( const Rectangle& rRect,
+ const Point& rStartPt, const Point& rEndPt )
+{
+ DBG_TRACE( "OutputDevice::DrawPie()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaPieAction( rRect, rStartPt, rEndPt ) );
+
+ if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) )
+ return;
+
+ Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+ if ( aRect.IsEmpty() )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ const Point aStart( ImplLogicToDevicePixel( rStartPt ) );
+ const Point aEnd( ImplLogicToDevicePixel( rEndPt ) );
+ Polygon aPiePoly( aRect, aStart, aEnd, POLY_PIE );
+
+ if ( aPiePoly.GetSize() >= 2 )
+ {
+ const SalPoint* pPtAry = (const SalPoint*)aPiePoly.ImplGetConstPointAry();
+ if ( !mbFillColor )
+ mpGraphics->DrawPolyLine( aPiePoly.GetSize(), pPtAry );
+ else
+ {
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ mpGraphics->DrawPolygon( aPiePoly.GetSize(), pPtAry );
+ }
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ pGraphics->DrawPie( aRect,
+ ImplLogicToDevicePixel( rStartPt ),
+ ImplLogicToDevicePixel( rEndPt ) );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawChord( const Rectangle& rRect,
+ const Point& rStartPt, const Point& rEndPt )
+{
+ DBG_TRACE( "OutputDevice::DrawChord()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaChordAction( rRect, rStartPt, rEndPt ) );
+
+ if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) )
+ return;
+
+ Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+ if ( aRect.IsEmpty() )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+
+ const Point aStart( ImplLogicToDevicePixel( rStartPt ) );
+ const Point aEnd( ImplLogicToDevicePixel( rEndPt ) );
+ Polygon aChordPoly( aRect, aStart, aEnd, POLY_CHORD );
+
+ if ( aChordPoly.GetSize() >= 2 )
+ {
+ const SalPoint* pPtAry = (const SalPoint*)aChordPoly.ImplGetConstPointAry();
+ if ( !mbFillColor )
+ mpGraphics->DrawPolyLine( aChordPoly.GetSize(), pPtAry );
+ else
+ {
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ mpGraphics->DrawPolygon( aChordPoly.GetSize(), pPtAry );
+ }
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ pGraphics->DrawChord( aRect,
+ ImplLogicToDevicePixel( rStartPt ),
+ ImplLogicToDevicePixel( rEndPt ) );
+ }
+#endif
+}
diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx
new file mode 100644
index 000000000000..371334530488
--- /dev/null
+++ b/vcl/source/gdi/outdev6.cxx
@@ -0,0 +1,1043 @@
+/*************************************************************************
+ *
+ * $RCSfile: outdev6.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:37 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_WALL_CXX
+
+#include <math.h>
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#else // REMOTE_APPSERVER
+#include <tools/stream.hxx>
+#endif // REMOTE_APPSERVER
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_GRAPH_HXX
+#include <graph.hxx>
+#endif
+#ifdef REMOTE_APPSERVER
+#include <rmoutdev.hxx>
+#endif
+#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
+#include <com/sun/star/uno/Sequence.hxx>
+#endif
+
+// ========================================================================
+
+DBG_NAMEEX( OutputDevice );
+
+// ------------------------------------------------------------------------
+
+void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, ULONG nFlags )
+{
+ DBG_TRACE( "OutputDevice::DrawGrid()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
+ aDstRect.Intersection( rRect );
+
+ if( aDstRect.IsEmpty() )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ if( !mpGraphics && !ImplGetGraphics() )
+ return;
+
+ if( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if( mbOutputClipped )
+ return;
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+
+ if( !pGraphics )
+ return;
+#endif
+
+ const long nDistX = Max( rDist.Width(), 1L );
+ const long nDistY = Max( rDist.Height(), 1L );
+ long nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
+ long nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
+ const long nRight = aDstRect.Right();
+ const long nBottom = aDstRect.Bottom();
+ const long nStartX = ImplLogicXToDevicePixel( nX );
+ const long nEndX = ImplLogicXToDevicePixel( nRight );
+ const long nStartY = ImplLogicYToDevicePixel( nY );
+ const long nEndY = ImplLogicYToDevicePixel( nBottom );
+ long nHorzCount = 0L;
+ long nVertCount = 0L;
+
+ ::com::sun::star::uno::Sequence< sal_Int32 > aVertBuf;
+ ::com::sun::star::uno::Sequence< sal_Int32 > aHorzBuf;
+
+ if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_HORZLINES ) )
+ {
+ aVertBuf.realloc( aDstRect.GetHeight() / nDistY + 2L );
+ aVertBuf[ nVertCount++ ] = nStartY;
+ while( ( nY += nDistY ) <= nBottom )
+ aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
+ }
+
+ if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_VERTLINES ) )
+ {
+ aHorzBuf.realloc( aDstRect.GetWidth() / nDistX + 2L );
+ aHorzBuf[ nHorzCount++ ] = nStartX;
+ while( ( nX += nDistX ) <= nRight )
+ aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
+ }
+
+ if( mbInitLineColor )
+ ImplInitLineColor();
+
+ if( mbInitFillColor )
+ ImplInitFillColor();
+
+#ifndef REMOTE_APPSERVER
+ const BOOL bOldMap = mbMap;
+ mbMap = FALSE;
+
+ if( nFlags & GRID_DOTS )
+ {
+ for( long i = 0L; i < nVertCount; i++ )
+ for( long j = 0L, nY = aVertBuf[ i ]; j < nHorzCount; j++ )
+ mpGraphics->DrawPixel( aHorzBuf[ j ], nY );
+ }
+ else
+ {
+ if( nFlags & GRID_HORZLINES )
+ {
+ for( long i = 0L; i < nVertCount; i++ )
+ {
+ nY = aVertBuf[ i ];
+ mpGraphics->DrawLine( nStartX, nY, nEndX, nY );
+ }
+ }
+
+ if( nFlags & GRID_VERTLINES )
+ {
+ for( long i = 0L; i < nHorzCount; i++ )
+ {
+ nX = aHorzBuf[ i ];
+ mpGraphics->DrawLine( nX, nStartY, nX, nEndY );
+ }
+ }
+ }
+
+ mbMap = bOldMap;
+#else // REMOTE_APPSERVER
+ aHorzBuf.realloc( nHorzCount );
+ aVertBuf.realloc( nVertCount );
+ pGraphics->DrawGrid( nStartX, nEndX, aHorzBuf, nStartY, nEndY, aVertBuf, nFlags );
+#endif // REMOTE_APPSERVER
+}
+
+// ------------------------------------------------------------------------
+
+void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly,
+ USHORT nTransparencePercent )
+{
+ DBG_TRACE( "OutputDevice::DrawTransparent()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if( !mbFillColor || ( 0 == nTransparencePercent ) )
+ DrawPolyPolygon( rPolyPoly );
+ else if( 100 == nTransparencePercent )
+ {
+ Push( PUSH_FILLCOLOR );
+ SetFillColor();
+ DrawPolyPolygon( rPolyPoly );
+ Pop();
+ }
+ else
+ {
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaTransparentAction( rPolyPoly, nTransparencePercent ) );
+
+ if( !IsDeviceOutputNecessary() || ( !mbLineColor && !mbFillColor ) )
+ return;
+
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ mpMetaFile = NULL;
+
+ if( OUTDEV_PRINTER == meOutDevType )
+ {
+ Rectangle aPolyRect( LogicToPixel( rPolyPoly ).GetBoundRect() );
+ const Size aDPISize( LogicToPixel( Size( 1, 1 ), MAP_INCH ) );
+ const long nBaseExtent = Max( FRound( aDPISize.Width() / 300. ), 1L );
+ long nMove;
+ const USHORT nTrans = ( nTransparencePercent < 13 ) ? 0 :
+ ( nTransparencePercent < 38 ) ? 25 :
+ ( nTransparencePercent < 63 ) ? 50 :
+ ( nTransparencePercent < 88 ) ? 75 : 100;
+
+ switch( nTrans )
+ {
+ case( 25 ): nMove = nBaseExtent * 3; break;
+ case( 50 ): nMove = nBaseExtent * 4; break;
+ case( 75 ): nMove = nBaseExtent * 6; break;
+ }
+
+ Push( PUSH_CLIPREGION | PUSH_LINECOLOR );
+ IntersectClipRegion( rPolyPoly );
+ SetLineColor( GetFillColor() );
+
+ Rectangle aRect( aPolyRect.TopLeft(), Size( aPolyRect.GetWidth(), nBaseExtent ) );
+
+ const BOOL bOldMap = mbMap;
+ mbMap = FALSE;
+
+ while( aRect.Top() <= aPolyRect.Bottom() )
+ {
+ DrawRect( aRect );
+ aRect.Move( 0, nMove );
+ }
+
+ aRect = Rectangle( aPolyRect.TopLeft(), Size( nBaseExtent, aPolyRect.GetHeight() ) );
+ while( aRect.Left() <= aPolyRect.Right() )
+ {
+ DrawRect( aRect );
+ aRect.Move( nMove, 0 );
+ }
+
+ mbMap = bOldMap;
+ Pop();
+ }
+ else
+ {
+#ifndef REMOTE_APPSERVER
+ PolyPolygon aPolyPoly( LogicToPixel( rPolyPoly ) );
+ Rectangle aPolyRect( aPolyPoly.GetBoundRect() );
+ Point aPoint;
+ Rectangle aDstRect( aPoint, GetOutputSizePixel() );
+
+ aDstRect.Intersection( aPolyRect );
+
+ if( OUTDEV_WINDOW == meOutDevType )
+ {
+ const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
+
+ if( !aPaintRgn.IsNull() )
+ aDstRect.Intersection( LogicToPixel( aPaintRgn ).GetBoundRect() );
+ }
+
+ if( !aDstRect.IsEmpty() )
+ {
+ VirtualDevice aVDev( *this, 1 );
+ const Size aDstSz( aDstRect.GetSize() );
+ const BYTE cTrans = (BYTE) MinMax( FRound( nTransparencePercent * 2.55 ), 0, 255 );
+
+ if( aDstRect.Left() || aDstRect.Top() )
+ aPolyPoly.Move( -aDstRect.Left(), -aDstRect.Top() );
+
+ if( aVDev.SetOutputSizePixel( aDstSz ) )
+ {
+ const BOOL bOldMap = mbMap;
+
+ mbMap = FALSE;
+
+ aVDev.SetLineColor( COL_BLACK );
+ aVDev.SetFillColor( COL_BLACK );
+ aVDev.DrawPolyPolygon( aPolyPoly );
+
+ Bitmap aPaint( GetBitmap( aDstRect.TopLeft(), aDstSz ) );
+ Bitmap aPolyMask( aVDev.GetBitmap( Point(), aDstSz ) );
+ BitmapWriteAccess* pW = aPaint.AcquireWriteAccess();
+ BitmapReadAccess* pR = aPolyMask.AcquireReadAccess();
+
+ if( pW && pR )
+ {
+ BitmapColor aPixCol;
+ const BitmapColor aFillCol( GetFillColor() );
+ const BitmapColor aWhite( pR->GetBestMatchingColor( Color( COL_WHITE ) ) );
+ const BitmapColor aBlack( pR->GetBestMatchingColor( Color( COL_BLACK ) ) );
+ const long nWidth = pW->Width(), nHeight = pW->Height();
+ const long nR = aFillCol.GetRed(), nG = aFillCol.GetGreen(), nB = aFillCol.GetBlue();
+ long nX, nY;
+
+ if( aPaint.GetBitCount() <= 8 )
+ {
+ const BitmapPalette& rPal = pW->GetPalette();
+ const USHORT nCount = rPal.GetEntryCount();
+ BitmapColor* pMap = (BitmapColor*) new BYTE[ nCount * sizeof( BitmapColor ) ];
+
+ for( USHORT i = 0; i < nCount; i++ )
+ {
+ BitmapColor aCol( rPal[ i ] );
+ pMap[ i ] = BitmapColor( (BYTE) rPal.GetBestIndex( aCol.Merge( aFillCol, cTrans ) ) );
+ }
+
+ if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
+ pW->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
+ {
+ const BYTE cBlack = aBlack.GetIndex();
+
+ for( nY = 0; nY < nHeight; nY++ )
+ {
+ Scanline pWScan = pW->GetScanline( nY );
+ Scanline pRScan = pR->GetScanline( nY );
+ BYTE cBit = 128;
+
+ for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan++ )
+ {
+ if( !cBit )
+ cBit = 128, pRScan++;
+
+ if( ( *pRScan & cBit ) == cBlack )
+ *pWScan = (BYTE) pMap[ *pWScan ].GetIndex();
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0; nY < nHeight; nY++ )
+ for( nX = 0; nX < nWidth; nX++ )
+ if( pR->GetPixel( nY, nX ) == aBlack )
+ pW->SetPixel( nY, nX, pMap[ pW->GetPixel( nY, nX ).GetIndex() ] );
+ }
+
+ delete[] (BYTE*) pMap;
+ }
+ else
+ {
+ if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
+ pW->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
+ {
+ const BYTE cBlack = aBlack.GetIndex();
+
+ for( nY = 0; nY < nHeight; nY++ )
+ {
+ Scanline pWScan = pW->GetScanline( nY );
+ Scanline pRScan = pR->GetScanline( nY );
+ BYTE cBit = 128;
+
+ for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan += 3 )
+ {
+ if( !cBit )
+ cBit = 128, pRScan++;
+
+ if( ( *pRScan & cBit ) == cBlack )
+ {
+ pWScan[ 0 ] = COLOR_CHANNEL_MERGE( pWScan[ 0 ], nB, cTrans );
+ pWScan[ 1 ] = COLOR_CHANNEL_MERGE( pWScan[ 1 ], nG, cTrans );
+ pWScan[ 2 ] = COLOR_CHANNEL_MERGE( pWScan[ 2 ], nR, cTrans );
+ }
+ }
+ }
+ }
+ else
+ {
+ for( nY = 0; nY < nHeight; nY++ )
+ {
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ if( pR->GetPixel( nY, nX ) == aBlack )
+ {
+ aPixCol = pW->GetColor( nY, nX );
+ pW->SetPixel( nY, nX, aPixCol.Merge( aFillCol, cTrans ) );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ aPolyMask.ReleaseAccess( pR );
+ aPaint.ReleaseAccess( pW );
+
+ DrawBitmap( aDstRect.TopLeft(), aPaint );
+
+ mbMap = bOldMap;
+
+ if( mbLineColor )
+ {
+ Push( PUSH_FILLCOLOR );
+ SetFillColor();
+ DrawPolyPolygon( rPolyPoly );
+ Pop();
+ }
+ }
+ else
+ DrawPolyPolygon( rPolyPoly );
+ }
+#else // REMOTE_APPSERVER
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ pGraphics->DrawTransparent( ImplLogicToDevicePixel( rPolyPoly ), nTransparencePercent );
+ }
+#endif // REMOTE_APPSERVER
+ }
+
+ mpMetaFile = pOldMetaFile;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
+ const Size& rSize, const Gradient& rTransparenceGradient )
+{
+ DBG_TRACE( "OutputDevice::DrawTransparent()" );
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ const Color aBlack( COL_BLACK );
+
+ if( mpMetaFile )
+ mpMetaFile->AddAction( new MetaFloatTransparentAction( rMtf, rPos, rSize, rTransparenceGradient ) );
+
+ if( rTransparenceGradient.GetStartColor() == aBlack && rTransparenceGradient.GetEndColor() == aBlack )
+ {
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ ( (GDIMetaFile&) rMtf ).Play( this, rPos, rSize );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ }
+ else
+ {
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ Rectangle aOutRect( LogicToPixel( rPos ), LogicToPixel( rSize ) );
+ Point aPoint;
+ Rectangle aDstRect( aPoint, GetOutputSizePixel() );
+
+ mpMetaFile = NULL;
+ aDstRect.Intersection( aOutRect );
+
+ if( OUTDEV_WINDOW == meOutDevType )
+ {
+ const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
+
+ if( !aPaintRgn.IsNull() )
+ aDstRect.Intersection( LogicToPixel( aPaintRgn.GetBoundRect() ) );
+ }
+
+ if( !aDstRect.IsEmpty() )
+ {
+ VirtualDevice* pVDev = new VirtualDevice;
+
+ pVDev->mnDPIX = mnDPIX;
+ pVDev->mnDPIY = mnDPIY;
+
+ if( pVDev->SetOutputSizePixel( aDstRect.GetSize() ) )
+ {
+ Bitmap aPaint, aMask;
+ AlphaMask aAlpha;
+ MapMode aMap( GetMapMode() );
+ Point aOutPos( PixelToLogic( aDstRect.TopLeft() ) );
+ const BOOL bOldMap = mbMap;
+
+ aMap.SetOrigin( Point( -aOutPos.X(), -aOutPos.Y() ) );
+ pVDev->SetMapMode( aMap );
+
+ // create paint bitmap
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ ( (GDIMetaFile&) rMtf ).Play( pVDev, rPos, rSize );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ pVDev->EnableMapMode( FALSE );
+ aPaint = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
+ pVDev->EnableMapMode( TRUE );
+
+ // create mask bitmap
+ pVDev->SetLineColor( COL_BLACK );
+ pVDev->SetFillColor( COL_BLACK );
+ pVDev->DrawRect( Rectangle( pVDev->PixelToLogic( Point() ), pVDev->GetOutputSize() ) );
+ pVDev->SetDrawMode( DRAWMODE_WHITELINE | DRAWMODE_WHITEFILL | DRAWMODE_WHITETEXT |
+ DRAWMODE_WHITEBITMAP | DRAWMODE_WHITEGRADIENT );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ ( (GDIMetaFile&) rMtf ).Play( pVDev, rPos, rSize );
+ ( (GDIMetaFile&) rMtf ).WindStart();
+ pVDev->EnableMapMode( FALSE );
+ aMask = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
+ pVDev->EnableMapMode( TRUE );
+
+ // create alpha mask from gradient
+ pVDev->SetDrawMode( DRAWMODE_GRAYGRADIENT );
+ pVDev->DrawGradient( Rectangle( rPos, rSize ), rTransparenceGradient );
+ pVDev->SetDrawMode( DRAWMODE_DEFAULT );
+ pVDev->EnableMapMode( FALSE );
+ pVDev->DrawMask( Point(), pVDev->GetOutputSizePixel(), aMask, Color( COL_WHITE ) );
+
+#ifndef REMOTE_APPSERVER
+ aAlpha = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
+#else
+ aAlpha.ImplSetBitmap( pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() ) );
+#endif
+
+ delete pVDev;
+
+ mbMap = FALSE;
+ DrawBitmapEx( aDstRect.TopLeft(), BitmapEx( aPaint, aAlpha ) );
+ mbMap = bOldMap;
+ }
+ else
+ delete pVDev;
+ }
+
+ mpMetaFile = pOldMetaFile;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawColorWallpaper( long nX, long nY,
+ long nWidth, long nHeight,
+ const Wallpaper& rWallpaper )
+{
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+ if ( mbOutputClipped )
+ return;
+
+ // Wallpaper ohne Umrandung zeichnen
+ Color aOldLineColor = GetLineColor();
+ Color aOldFillColor = GetFillColor();
+ SetLineColor();
+ SetFillColor( rWallpaper.GetColor() );
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ mpGraphics->DrawRect( nX+mnOutOffX, nY+mnOutOffY, nWidth, nHeight );
+ SetLineColor( aOldLineColor );
+ SetFillColor( aOldFillColor );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ Color aOldLineColor = GetLineColor();
+ Color aOldFillColor = GetFillColor();
+ SetLineColor();
+ SetFillColor( rWallpaper.GetColor() );
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ if ( mbInitFillColor )
+ ImplInitFillColor();
+ pGraphics->DrawRect( Rectangle( Point( nX+mnOutOffX, nY+mnOutOffY ), Size( nWidth, nHeight ) ) );
+ SetLineColor( aOldLineColor );
+ SetFillColor( aOldFillColor );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawBitmapWallpaper( long nX, long nY,
+ long nWidth, long nHeight,
+ const Wallpaper& rWallpaper )
+{
+ BitmapEx aBmpEx;
+ const BitmapEx* pCached = rWallpaper.ImplGetImpWallpaper()->ImplGetCachedBitmap();
+ Point aPos;
+ Size aSize;
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ const WallpaperStyle eStyle = rWallpaper.GetStyle();
+ const BOOL bOldMap = mbMap;
+ BOOL bDrawn = FALSE;
+ BOOL bDrawGradientBackground = FALSE;
+ BOOL bDrawColorBackground = FALSE;
+
+ if( pCached )
+ aBmpEx = *pCached;
+ else
+ aBmpEx = rWallpaper.GetBitmap();
+
+ const long nBmpWidth = aBmpEx.GetSizePixel().Width();
+ const long nBmpHeight = aBmpEx.GetSizePixel().Height();
+ const BOOL bTransparent = aBmpEx.IsTransparent();
+
+ // draw background
+ if( bTransparent )
+ {
+ if( rWallpaper.IsGradient() )
+ bDrawGradientBackground = TRUE;
+ else
+ {
+ if( !pCached && !rWallpaper.GetColor().GetTransparency() )
+ {
+ VirtualDevice aVDev( *this );
+ aVDev.SetBackground( rWallpaper.GetColor() );
+ aVDev.SetOutputSizePixel( Size( nBmpWidth, nBmpHeight ) );
+ aVDev.DrawBitmapEx( Point(), aBmpEx );
+ aBmpEx = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
+ }
+
+ bDrawColorBackground = TRUE;
+ }
+ }
+ else if( eStyle != WALLPAPER_TILE && eStyle != WALLPAPER_SCALE )
+ {
+ if( rWallpaper.IsGradient() )
+ bDrawGradientBackground = TRUE;
+ else
+ bDrawColorBackground = TRUE;
+ }
+
+ // background of bitmap?
+ if( bDrawGradientBackground )
+ ImplDrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
+ else if( bDrawColorBackground && bTransparent )
+ {
+ ImplDrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
+ bDrawColorBackground = FALSE;
+ }
+
+ // calc pos and size
+ if( rWallpaper.IsRect() )
+ {
+ const Rectangle aBound( LogicToPixel( rWallpaper.GetRect() ) );
+ aPos = aBound.TopLeft();
+ aSize = aBound.GetSize();
+ }
+ else
+ {
+ aPos = Point( nX, nY );
+ aSize = Size( nWidth, nHeight );
+ }
+
+ mpMetaFile = NULL;
+ mbMap = FALSE;
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
+
+ switch( eStyle )
+ {
+ case( WALLPAPER_SCALE ):
+ {
+ if( !pCached || ( pCached->GetSizePixel() != aSize ) )
+ {
+ if( pCached )
+ rWallpaper.ImplGetImpWallpaper()->ImplReleaseCachedBitmap();
+
+ aBmpEx = rWallpaper.GetBitmap();
+ aBmpEx.Scale( aSize );
+ aBmpEx = BitmapEx( aBmpEx.GetBitmap().CreateDisplayBitmap( this ), aBmpEx.GetMask() );
+ }
+ }
+ break;
+
+ case( WALLPAPER_TOPLEFT ):
+ break;
+
+ case( WALLPAPER_TOP ):
+ aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
+ break;
+
+ case( WALLPAPER_TOPRIGHT ):
+ aPos.X() += ( aSize.Width() - nBmpWidth );
+ break;
+
+ case( WALLPAPER_LEFT ):
+ aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
+ break;
+
+ case( WALLPAPER_CENTER ):
+ {
+ aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
+ aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
+ }
+ break;
+
+ case( WALLPAPER_RIGHT ):
+ {
+ aPos.X() += ( aSize.Width() - nBmpWidth );
+ aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
+ }
+ break;
+
+ case( WALLPAPER_BOTTOMLEFT ):
+ aPos.Y() += ( aSize.Height() - nBmpHeight );
+ break;
+
+ case( WALLPAPER_BOTTOM ):
+ {
+ aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
+ aPos.Y() += ( aSize.Height() - nBmpHeight );
+ }
+ break;
+
+ case( WALLPAPER_BOTTOMRIGHT ):
+ {
+ aPos.X() += ( aSize.Width() - nBmpWidth );
+ aPos.Y() += ( aSize.Height() - nBmpHeight );
+ }
+ break;
+
+ default:
+ {
+ const long nRight = nX + nWidth - 1L;
+ const long nBottom = nY + nHeight - 1L;
+ long nFirstX;
+ long nFirstY;
+
+ if( eStyle == WALLPAPER_TILE )
+ {
+ nFirstX = aPos.X();
+ nFirstY = aPos.Y();
+ }
+ else
+ {
+ nFirstX = aPos.X() + ( ( aSize.Width() - nBmpWidth ) >> 1 );
+ nFirstY = aPos.Y() + ( ( aSize.Height() - nBmpHeight ) >> 1 );
+ }
+
+ const long nOffX = ( nFirstX - nX ) % nBmpWidth;
+ const long nOffY = ( nFirstY - nY ) % nBmpHeight;
+ long nStartX = nX + nOffX;
+ long nStartY = nY + nOffY;
+
+ if( nOffX > 0L )
+ nStartX -= nBmpWidth;
+
+ if( nOffY > 0L )
+ nStartY -= nBmpHeight;
+
+ for( long nBmpY = nStartY; nBmpY <= nBottom; nBmpY += nBmpHeight )
+ for( long nBmpX = nStartX; nBmpX <= nRight; nBmpX += nBmpWidth )
+ DrawBitmapEx( Point( nBmpX, nBmpY ), aBmpEx );
+
+ bDrawn = TRUE;
+ }
+ break;
+ }
+
+ if( !bDrawn )
+ {
+ // optimized for non-transparent bitmaps
+ if( bDrawColorBackground )
+ {
+ const Size aBmpSize( aBmpEx.GetSizePixel() );
+ const Point aTmpPoint;
+ const Rectangle aOutRect( aTmpPoint, GetOutputSizePixel() );
+ const Rectangle aColRect( Point( nX, nY ), Size( nWidth, nHeight ) );
+ Rectangle aWorkRect;
+
+ aWorkRect = Rectangle( 0, 0, aOutRect.Right(), aPos.Y() - 1L );
+ aWorkRect.Justify();
+ aWorkRect.Intersection( aColRect );
+ if( !aWorkRect.IsEmpty() )
+ {
+ ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
+ aWorkRect.GetWidth(), aWorkRect.GetHeight(),
+ rWallpaper );
+ }
+
+ aWorkRect = Rectangle( 0, aPos.Y(), aPos.X() - 1L, aPos.Y() + aBmpSize.Height() - 1L );
+ aWorkRect.Justify();
+ aWorkRect.Intersection( aColRect );
+ if( !aWorkRect.IsEmpty() )
+ {
+ ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
+ aWorkRect.GetWidth(), aWorkRect.GetHeight(),
+ rWallpaper );
+ }
+
+ aWorkRect = Rectangle( aPos.X() + aBmpSize.Width(), aPos.Y(), aOutRect.Right(), aPos.Y() + aBmpSize.Height() - 1L );
+ aWorkRect.Justify();
+ aWorkRect.Intersection( aColRect );
+ if( !aWorkRect.IsEmpty() )
+ {
+ ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
+ aWorkRect.GetWidth(), aWorkRect.GetHeight(),
+ rWallpaper );
+ }
+
+ aWorkRect = Rectangle( 0, aPos.Y() + aBmpSize.Height(), aOutRect.Right(), aOutRect.Bottom() );
+ aWorkRect.Justify();
+ aWorkRect.Intersection( aColRect );
+ if( !aWorkRect.IsEmpty() )
+ {
+ ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
+ aWorkRect.GetWidth(), aWorkRect.GetHeight(),
+ rWallpaper );
+ }
+ }
+
+ DrawBitmapEx( aPos, aBmpEx );
+ }
+
+ rWallpaper.ImplGetImpWallpaper()->ImplSetCachedBitmap( aBmpEx );
+
+ Pop();
+ mbMap = bOldMap;
+ mpMetaFile = pOldMetaFile;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawGradientWallpaper( long nX, long nY,
+ long nWidth, long nHeight,
+ const Wallpaper& rWallpaper )
+{
+ Rectangle aBound;
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ const BOOL bOldMap = mbMap;
+
+/*
+ if ( rWallpaper.IsRect() )
+ aBound = LogicToPixel( rWallpaper.GetRect() );
+ else
+*/
+ aBound = Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );
+
+ mpMetaFile = NULL;
+ mbMap = FALSE;
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
+
+ DrawGradient( aBound, rWallpaper.GetGradient() );
+
+ Pop();
+ mbMap = bOldMap;
+ mpMetaFile = pOldMetaFile;
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDrawWallpaper( long nX, long nY,
+ long nWidth, long nHeight,
+ const Wallpaper& rWallpaper )
+{
+ if( rWallpaper.IsBitmap() )
+ ImplDrawBitmapWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
+ else if( rWallpaper.IsGradient() )
+ ImplDrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
+ else
+ ImplDrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawWallpaper( const Rectangle& rRect,
+ const Wallpaper& rWallpaper )
+{
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaWallpaperAction( rRect, rWallpaper ) );
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ if ( rWallpaper.GetStyle() != WALLPAPER_NULL )
+ {
+ Rectangle aRect = LogicToPixel( rRect );
+ aRect.Justify();
+
+ if ( !aRect.IsEmpty() )
+ {
+ ImplDrawWallpaper( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
+ rWallpaper );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::Erase()
+{
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ if ( mbBackground )
+ {
+ RasterOp eRasterOp = GetRasterOp();
+ if ( eRasterOp != ROP_OVERPAINT )
+ SetRasterOp( ROP_OVERPAINT );
+ ImplDrawWallpaper( 0, 0, mnOutWidth, mnOutHeight, maBackground );
+ if ( eRasterOp != ROP_OVERPAINT )
+ SetRasterOp( eRasterOp );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::ImplDraw2ColorFrame( const Rectangle& rRect,
+ const Color& rLeftTopColor,
+ const Color& rRightBottomColor )
+{
+#ifndef REMOTE_APPSERVER
+ SetFillColor( rLeftTopColor );
+ DrawRect( Rectangle( rRect.TopLeft(), Point( rRect.Left(), rRect.Bottom()-1 ) ) );
+ DrawRect( Rectangle( rRect.TopLeft(), Point( rRect.Right()-1, rRect.Top() ) ) );
+ SetFillColor( rRightBottomColor );
+ DrawRect( Rectangle( rRect.BottomLeft(), rRect.BottomRight() ) );
+ DrawRect( Rectangle( rRect.TopRight(), rRect.BottomRight() ) );
+#else
+ if ( mpMetaFile )
+ {
+ BOOL bOutputEnabled = IsOutputEnabled();
+ EnableOutput( FALSE );
+ SetFillColor( rLeftTopColor );
+ DrawRect( Rectangle( rRect.TopLeft(), Point( rRect.Left(), rRect.Bottom()-1 ) ) );
+ DrawRect( Rectangle( rRect.TopLeft(), Point( rRect.Right()-1, rRect.Top() ) ) );
+ SetFillColor( rRightBottomColor );
+ DrawRect( Rectangle( rRect.BottomLeft(), rRect.BottomRight() ) );
+ DrawRect( Rectangle( rRect.TopRight(), rRect.BottomRight() ) );
+ EnableOutput( bOutputEnabled );
+ }
+
+ if ( IsDeviceOutputNecessary() && !rRect.IsEmpty() )
+ {
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ {
+ if ( mbInitLineColor )
+ ImplInitLineColor();
+ Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+ pGraphics->Draw2ColorFrame( aRect, rLeftTopColor, rRightBottomColor );
+ }
+ }
+ SetFillColor( rRightBottomColor );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
+ const GfxLink& rGfxLink, GDIMetaFile* pSubst )
+{
+ if ( mpMetaFile )
+ {
+ GDIMetaFile aSubst;
+
+ if( pSubst )
+ aSubst = *pSubst;
+
+ mpMetaFile->AddAction( new MetaEPSAction( rPoint, rSize, rGfxLink, aSubst ) );
+ }
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) );
+ BOOL bDrawn = FALSE;
+
+ if( !aRect.IsEmpty() )
+ {
+ aRect.Justify();
+
+ if( GetOutDevType() == OUTDEV_PRINTER )
+ {
+#ifndef REMOTE_APPSERVER
+ if( !mpGraphics && !ImplGetGraphics() )
+ return;
+
+ if( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if( !mbOutputClipped )
+ {
+ bDrawn = mpGraphics->DrawEPS( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
+ (BYTE*) rGfxLink.GetData(), rGfxLink.GetDataSize() );
+ }
+#else
+ DBG_ERROR( "No direct EPS-support for remote appserver!" );
+#endif
+ }
+
+ if( !bDrawn && pSubst )
+ {
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+
+ mpMetaFile = NULL;
+ Graphic( *pSubst ).Draw( this, rPoint, rSize );
+ mpMetaFile = pOldMetaFile;
+ }
+ }
+}
diff --git a/vcl/source/gdi/outmap.cxx b/vcl/source/gdi/outmap.cxx
new file mode 100644
index 000000000000..c086efb92bbc
--- /dev/null
+++ b/vcl/source/gdi/outmap.cxx
@@ -0,0 +1,2106 @@
+/*************************************************************************
+ *
+ * $RCSfile: outmap.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <limits.h>
+
+#define _SV_OUTMAP_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+
+#ifndef _BIGINT_HXX
+#include <tools/bigint.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_POLY_H
+#include <poly.h>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_REGION_HXX
+#include <region.hxx>
+#endif
+#ifndef _SV_REGION_H
+#include <region.h>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_CURSOR_HXX
+#include <cursor.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_LINEINFO_HXX
+#include <lineinfo.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+
+// =======================================================================
+
+DBG_NAMEEX( OutputDevice );
+DBG_NAMEEX( Polygon );
+DBG_NAMEEX( PolyPolygon );
+DBG_NAMEEX( Region );
+
+// =======================================================================
+
+static long aImplNumeratorAry[MAP_PIXEL+1] =
+ { 1, 1, 5, 50, 1, 1, 1, 1, 1, 1, 1 };
+static long aImplDenominatorAry[MAP_PIXEL+1] =
+ { 2540, 254, 127, 127, 1000, 100, 10, 1, 72, 1440, 1 };
+
+// -----------------------------------------------------------------------
+
+/*
+Reduziert die Genauigkeit bis eine Fraction draus wird (sollte mal
+ein Fraction ctor werden) koennte man dann auch mit BigInts machen
+*/
+
+static Fraction ImplMakeFraction( long nN1, long nN2, long nD1, long nD2 )
+{
+ long i = 1;
+
+ if ( nN1 < 0 ) { i = -i; nN1 = -nN1; }
+ if ( nN2 < 0 ) { i = -i; nN2 = -nN2; }
+ if ( nD1 < 0 ) { i = -i; nD1 = -nD1; }
+ if ( nD2 < 0 ) { i = -i; nD2 = -nD2; }
+ // alle positiv; i Vorzeichen
+
+ Fraction aF( i*nN1, nD1 );
+ aF *= Fraction( nN2, nD2 );
+
+ while ( aF.GetDenominator() == -1 )
+ {
+ if ( nN1 > nN2 )
+ nN1 = (nN1 + 1) / 2;
+ else
+ nN2 = (nN2 + 1) / 2;
+ if ( nD1 > nD2 )
+ nD1 = (nD1 + 1) / 2;
+ else
+ nD2 = (nD2 + 1) / 2;
+
+ aF = Fraction( i*nN1, nD1 );
+ aF *= Fraction( nN2, nD2 );
+ }
+
+ return aF;
+}
+
+// -----------------------------------------------------------------------
+
+// Fraction.GetNumerator()
+// Fraction.GetDenominator() > 0
+// rOutRes.nPixPerInch? > 0
+// rMapRes.nMapScNum?
+// rMapRes.nMapScDenom? > 0
+
+static void ImplCalcBigIntThreshold( long nDPIX, long nDPIY,
+ const ImplMapRes& rMapRes,
+ ImplThresholdRes& rThresRes )
+{
+ if ( LONG_MAX / nDPIX < Abs( rMapRes.mnMapScNumX ) )
+ {
+ rThresRes.mnThresLogToPixX = 0;
+ rThresRes.mnThresPixToLogX = 0;
+ }
+ else
+ {
+ // Schwellenwerte fuer BigInt Arithmetik berechnen
+ long nDenomHalfX = rMapRes.mnMapScDenomX / 2;
+ ULONG nDenomX = rMapRes.mnMapScDenomX;
+ long nProductX = nDPIX * rMapRes.mnMapScNumX;
+
+ if ( !nProductX )
+ rThresRes.mnThresLogToPixX = LONG_MAX;
+ else
+ rThresRes.mnThresLogToPixX = Abs( (LONG_MAX - nDenomHalfX) / nProductX );
+
+ if ( !nDenomX )
+ rThresRes.mnThresPixToLogX = LONG_MAX;
+ else if ( nProductX >= 0 )
+ rThresRes.mnThresPixToLogX = (long)(((ULONG)LONG_MAX - (ULONG)( nProductX/2)) / nDenomX);
+ else
+ rThresRes.mnThresPixToLogX = (long)(((ULONG)LONG_MAX + (ULONG)(-nProductX/2)) / nDenomX);
+ }
+
+ if ( LONG_MAX / nDPIY < Abs( rMapRes.mnMapScNumY ) )
+ {
+ rThresRes.mnThresLogToPixY = 0;
+ rThresRes.mnThresPixToLogY = 0;
+ }
+ else
+ {
+ // Schwellenwerte fuer BigInt Arithmetik berechnen
+ long nDenomHalfY = rMapRes.mnMapScDenomY / 2;
+ ULONG nDenomY = rMapRes.mnMapScDenomY;
+ long nProductY = nDPIY * rMapRes.mnMapScNumY;
+
+ if ( !nProductY )
+ rThresRes.mnThresLogToPixY = LONG_MAX;
+ else
+ rThresRes.mnThresLogToPixY = Abs( (LONG_MAX - nDenomHalfY) / nProductY );
+
+ if ( !nDenomY )
+ rThresRes.mnThresPixToLogY = LONG_MAX;
+ else if ( nProductY >= 0 )
+ rThresRes.mnThresPixToLogY = (long)(((ULONG)LONG_MAX - (ULONG)( nProductY/2)) / nDenomY);
+ else
+ rThresRes.mnThresPixToLogY = (long)(((ULONG)LONG_MAX + (ULONG)(-nProductY/2)) / nDenomY);
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalcMapResolution( const MapMode& rMapMode,
+ long nDPIX, long nDPIY, ImplMapRes& rMapRes )
+{
+ switch ( rMapMode.GetMapUnit() )
+ {
+ case MAP_RELATIVE:
+ break;
+ case MAP_100TH_MM:
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = 2540;
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = 2540;
+ break;
+ case MAP_10TH_MM:
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = 254;
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = 254;
+ break;
+ case MAP_MM:
+ rMapRes.mnMapScNumX = 5; // 10
+ rMapRes.mnMapScDenomX = 127; // 254
+ rMapRes.mnMapScNumY = 5; // 10
+ rMapRes.mnMapScDenomY = 127; // 254
+ break;
+ case MAP_CM:
+ rMapRes.mnMapScNumX = 50; // 100
+ rMapRes.mnMapScDenomX = 127; // 254
+ rMapRes.mnMapScNumY = 50; // 100
+ rMapRes.mnMapScDenomY = 127; // 254
+ break;
+ case MAP_1000TH_INCH:
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = 1000;
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = 1000;
+ break;
+ case MAP_100TH_INCH:
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = 100;
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = 100;
+ break;
+ case MAP_10TH_INCH:
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = 10;
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = 10;
+ break;
+ case MAP_INCH:
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = 1;
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = 1;
+ break;
+ case MAP_POINT:
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = 72;
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = 72;
+ break;
+ case MAP_TWIP:
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = 1440;
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = 1440;
+ break;
+ case MAP_PIXEL:
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = nDPIX;
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = nDPIY;
+ break;
+ case MAP_SYSFONT:
+ case MAP_APPFONT:
+ case MAP_REALAPPFONT:
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->maGDIData.mnAppFontX )
+ {
+ WorkWindow* pWin = new WorkWindow( NULL, 0 );
+ delete pWin;
+ }
+ if ( rMapMode.GetMapUnit() == MAP_REALAPPFONT )
+ rMapRes.mnMapScNumX = pSVData->maGDIData.mnRealAppFontX;
+ else
+ rMapRes.mnMapScNumX = pSVData->maGDIData.mnAppFontX;
+ rMapRes.mnMapScDenomX = nDPIX * 40;
+ rMapRes.mnMapScNumY = pSVData->maGDIData.mnAppFontY;;
+ rMapRes.mnMapScDenomY = nDPIY * 80;
+ }
+ break;
+ }
+
+ Fraction aScaleX = rMapMode.GetScaleX();
+ Fraction aScaleY = rMapMode.GetScaleY();
+
+ // Offset laut MapMode setzen
+ Point aOrigin = rMapMode.GetOrigin();
+ if ( rMapMode.GetMapUnit() != MAP_RELATIVE )
+ {
+ rMapRes.mnMapOfsX = aOrigin.X();
+ rMapRes.mnMapOfsY = aOrigin.Y();
+ }
+ else
+ {
+ BigInt aX( rMapRes.mnMapOfsX );
+ aX *= BigInt( aScaleX.GetDenominator() );
+ if ( rMapRes.mnMapOfsX >= 0 )
+ {
+ if ( aScaleX.GetNumerator() >= 0 )
+ aX += BigInt( aScaleX.GetNumerator()/2 );
+ else
+ aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
+ }
+ else
+ {
+ if ( aScaleX.GetNumerator() >= 0 )
+ aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
+ else
+ aX += BigInt( aScaleX.GetNumerator()/2 );
+ }
+ aX /= BigInt( aScaleX.GetNumerator() );
+ rMapRes.mnMapOfsX = (long)aX + aOrigin.X();
+ BigInt aY( rMapRes.mnMapOfsY );
+ aY *= BigInt( aScaleY.GetDenominator() );
+ if( rMapRes.mnMapOfsY >= 0 )
+ {
+ if ( aScaleY.GetNumerator() >= 0 )
+ aY += BigInt( aScaleY.GetNumerator()/2 );
+ else
+ aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
+ }
+ else
+ {
+ if ( aScaleY.GetNumerator() >= 0 )
+ aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
+ else
+ aY += BigInt( aScaleY.GetNumerator()/2 );
+ }
+ aY /= BigInt( aScaleY.GetNumerator() );
+ rMapRes.mnMapOfsY = (long)aY + aOrigin.Y();
+ }
+
+ // Scaling Faktor laut MapMode einberechnen
+ // aTemp? = rMapRes.mnMapSc? * aScale?
+ Fraction aTempX = ImplMakeFraction( rMapRes.mnMapScNumX,
+ aScaleX.GetNumerator(),
+ rMapRes.mnMapScDenomX,
+ aScaleX.GetDenominator() );
+ Fraction aTempY = ImplMakeFraction( rMapRes.mnMapScNumY,
+ aScaleY.GetNumerator(),
+ rMapRes.mnMapScDenomY,
+ aScaleY.GetDenominator() );
+ rMapRes.mnMapScNumX = aTempX.GetNumerator();
+ rMapRes.mnMapScDenomX = aTempX.GetDenominator();
+ rMapRes.mnMapScNumY = aTempY.GetNumerator();
+ rMapRes.mnMapScDenomY = aTempY.GetDenominator();
+
+ // hack: 0/n ungef"ahr 1/max
+ if ( !rMapRes.mnMapScNumX )
+ {
+ rMapRes.mnMapScNumX = 1;
+ rMapRes.mnMapScDenomX = LONG_MAX;
+ }
+ if ( !rMapRes.mnMapScNumY )
+ {
+ rMapRes.mnMapScNumY = 1;
+ rMapRes.mnMapScDenomY = LONG_MAX;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline void ImplCalcMapResolution( const MapMode& rMapMode,
+ long nDPIX, long nDPIY,
+ ImplMapRes& rMapRes,
+ ImplThresholdRes& rThresRes )
+{
+ ImplCalcMapResolution( rMapMode, nDPIX, nDPIY, rMapRes );
+ ImplCalcBigIntThreshold( nDPIX, nDPIY, rMapRes, rThresRes );
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetMapMode()
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( mpMetaFile )
+ mpMetaFile->AddAction( new MetaMapModeAction( MapMode() ) );
+
+ if ( mbMap || !maMapMode.IsDefault() )
+ {
+ mbMap = FALSE;
+ maMapMode = MapMode();
+
+ // create new objects (clip region werden nicht neu skaliert)
+ mbNewFont = TRUE;
+ mbInitFont = TRUE;
+ if ( GetOutDevType() == OUTDEV_WINDOW )
+ {
+ if ( ((Window*)this)->mpCursor )
+ ((Window*)this)->mpCursor->ImplNew();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ BOOL bRelMap = (rNewMapMode.GetMapUnit() == MAP_RELATIVE);
+
+ if ( mpMetaFile )
+ {
+ mpMetaFile->AddAction( new MetaMapModeAction( rNewMapMode ) );
+#ifdef DBG_UTIL
+ if ( GetOutDevType() != OUTDEV_PRINTER )
+ DBG_ASSERTWARNING( bRelMap, "Please record only relative MapModes!" );
+#endif
+ }
+
+ // Ist der MapMode der gleiche wie vorher, dann mache nichts
+ if ( maMapMode == rNewMapMode )
+ return;
+
+ // Ist Default-MapMode, dann bereche nichts
+ BOOL bOldMap = mbMap;
+ mbMap = !rNewMapMode.IsDefault();
+ if ( mbMap )
+ {
+ // Falls nur der Orign umgesetzt wird, dann scaliere nichts neu
+ if ( (rNewMapMode.GetMapUnit() == maMapMode.GetMapUnit()) &&
+ (rNewMapMode.GetScaleX() == maMapMode.GetScaleX()) &&
+ (rNewMapMode.GetScaleY() == maMapMode.GetScaleY()) &&
+ (bOldMap == mbMap) )
+ {
+ // Offset setzen
+ Point aOrigin = rNewMapMode.GetOrigin();
+ maMapRes.mnMapOfsX = aOrigin.X();
+ maMapRes.mnMapOfsY = aOrigin.Y();
+ maMapMode = rNewMapMode;
+ return;
+ }
+ if ( !bOldMap && bRelMap )
+ {
+ maMapRes.mnMapScNumX = 1;
+ maMapRes.mnMapScNumY = 1;
+ maMapRes.mnMapScDenomX = mnDPIX;
+ maMapRes.mnMapScDenomY = mnDPIY;
+ maMapRes.mnMapOfsX = 0;
+ maMapRes.mnMapOfsY = 0;
+ }
+
+ // Neue MapMode-Aufloesung berechnen
+ ImplCalcMapResolution( rNewMapMode, mnDPIX, mnDPIY, maMapRes, maThresRes );
+ }
+
+ // Neuen MapMode setzen
+ if ( bRelMap )
+ {
+ Point aOrigin( maMapRes.mnMapOfsX, maMapRes.mnMapOfsY );
+ // aScale? = maMapMode.GetScale?() * rNewMapMode.GetScale?()
+ Fraction aScaleX = ImplMakeFraction( maMapMode.GetScaleX().GetNumerator(),
+ rNewMapMode.GetScaleX().GetNumerator(),
+ maMapMode.GetScaleX().GetDenominator(),
+ rNewMapMode.GetScaleX().GetDenominator() );
+ Fraction aScaleY = ImplMakeFraction( maMapMode.GetScaleY().GetNumerator(),
+ rNewMapMode.GetScaleY().GetNumerator(),
+ maMapMode.GetScaleY().GetDenominator(),
+ rNewMapMode.GetScaleY().GetDenominator() );
+ maMapMode.SetOrigin( aOrigin );
+ maMapMode.SetScaleX( aScaleX );
+ maMapMode.SetScaleY( aScaleY );
+ }
+ else
+ maMapMode = rNewMapMode;
+
+ // create new objects (clip region werden nicht neu skaliert)
+ mbNewFont = TRUE;
+ mbInitFont = TRUE;
+ if ( GetOutDevType() == OUTDEV_WINDOW )
+ {
+ if ( ((Window*)this)->mpCursor )
+ ((Window*)this)->mpCursor->ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void OutputDevice::SetRelativeMapMode( const MapMode& rNewMapMode )
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ // Ist der MapMode der gleiche wie vorher, dann mache nichts
+ if ( maMapMode == rNewMapMode )
+ return;
+
+ MapUnit eOld = maMapMode.GetMapUnit();
+ MapUnit eNew = rNewMapMode.GetMapUnit();
+
+ // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
+ Fraction aXF = ImplMakeFraction( rNewMapMode.GetScaleX().GetNumerator(),
+ maMapMode.GetScaleX().GetDenominator(),
+ rNewMapMode.GetScaleX().GetDenominator(),
+ maMapMode.GetScaleX().GetNumerator() );
+ Fraction aYF = ImplMakeFraction( rNewMapMode.GetScaleY().GetNumerator(),
+ maMapMode.GetScaleY().GetDenominator(),
+ rNewMapMode.GetScaleY().GetDenominator(),
+ maMapMode.GetScaleY().GetNumerator() );
+
+ Point aPt( LogicToLogic( Point(), NULL, &rNewMapMode ) );
+ if ( eNew != eOld )
+ {
+ if ( eOld > MAP_PIXEL )
+ {
+ DBG_ERRORFILE( "Not implemented MapUnit" )
+ }
+ else if ( eNew > MAP_PIXEL )
+ {
+ DBG_ERRORFILE( "Not implemented MapUnit" )
+ }
+ else
+ {
+ Fraction aF( aImplNumeratorAry[eNew] * aImplDenominatorAry[eOld],
+ aImplNumeratorAry[eOld] * aImplDenominatorAry[eNew] );
+
+ // a?F = a?F * aF
+ aXF = ImplMakeFraction( aXF.GetNumerator(), aF.GetNumerator(),
+ aXF.GetDenominator(), aF.GetDenominator() );
+ aYF = ImplMakeFraction( aYF.GetNumerator(), aF.GetNumerator(),
+ aYF.GetDenominator(), aF.GetDenominator() );
+ if ( eOld == MAP_PIXEL )
+ {
+ aXF *= Fraction( mnDPIX, 1 );
+ aYF *= Fraction( mnDPIY, 1 );
+ }
+ else if ( eNew == MAP_PIXEL )
+ {
+ aXF *= Fraction( 1, mnDPIX );
+ aYF *= Fraction( 1, mnDPIY );
+ }
+ }
+ }
+
+ MapMode aNewMapMode( MAP_RELATIVE, Point( -aPt.X(), -aPt.Y() ), aXF, aYF );
+ SetMapMode( aNewMapMode );
+
+ if ( eNew != eOld )
+ maMapMode = rNewMapMode;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplLogicToPixel( long n, long nDPI, long nMapNum, long nMapDenom,
+ long nThres )
+{
+ if ( Abs( n ) < nThres )
+ {
+ n *= nDPI * nMapNum;
+ n += n >= 0 ? nMapDenom/2 : -((nMapDenom-1)/2);
+ return (n / nMapDenom);
+ }
+ else
+ {
+ BigInt aTemp( n );
+ aTemp *= BigInt( nDPI );
+ aTemp *= BigInt( nMapNum );
+
+ if ( aTemp.IsNeg() )
+ {
+ BigInt aMapScDenom2( (nMapDenom-1)/2 );
+ aTemp -= aMapScDenom2;
+ }
+ else
+ {
+ BigInt aMapScDenom2( nMapDenom/2 );
+ aTemp += aMapScDenom2;
+ }
+
+ aTemp /= BigInt( nMapDenom );
+ return (long)aTemp;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplPixelToLogic( long n, long nDPI, long nMapNum, long nMapDenom,
+ long nThres )
+{
+ if ( Abs( n ) < nThres )
+ {
+ long nDenom = nDPI * nMapNum;
+ long nNum = n * nMapDenom;
+ if ( nNum >= 0 )
+ {
+ if ( nDenom >= 0 )
+ nNum += nDenom/2;
+ else
+ nNum -= (nDenom+1)/2;
+ }
+ else
+ {
+ if ( nDenom >= 0 )
+ nNum -= (nDenom-1)/2;
+ else
+ nNum += nDenom/2;
+ }
+ return (nNum / nDenom);
+ }
+ else
+ {
+ BigInt aDenom( nDPI );
+ aDenom *= BigInt( nMapNum );
+
+ BigInt aNum( n );
+ aNum *= BigInt( nMapDenom );
+
+ BigInt aDenom2( aDenom );
+ if ( aNum.IsNeg() )
+ {
+ if ( aDenom.IsNeg() )
+ {
+ aDenom2 /= BigInt(2);
+ aNum += aDenom2;
+ }
+ else
+ {
+ aDenom2 -= 1;
+ aDenom2 /= BigInt(2);
+ aNum -= aDenom2;
+ }
+ }
+ else
+ {
+ if ( aDenom.IsNeg() )
+ {
+ aDenom2 += 1;
+ aDenom2 /= BigInt(2);
+ aNum -= aDenom2;
+ }
+ else
+ {
+ aDenom2 /= BigInt(2);
+ aNum += aDenom2;
+ }
+ }
+
+ aNum /= aDenom;
+ return (long)aNum;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplLogicXToDevicePixel( long nX ) const
+{
+ if ( !mbMap )
+ return nX+mnOutOffX;
+
+ return ImplLogicToPixel( nX + maMapRes.mnMapOfsX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX )+mnOutOffX;
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplLogicYToDevicePixel( long nY ) const
+{
+ if ( !mbMap )
+ return nY+mnOutOffY;
+
+ return ImplLogicToPixel( nY + maMapRes.mnMapOfsY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY )+mnOutOffY;
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplLogicWidthToDevicePixel( long nWidth ) const
+{
+ if ( !mbMap )
+ return nWidth;
+
+ return ImplLogicToPixel( nWidth, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX );
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplLogicHeightToDevicePixel( long nHeight ) const
+{
+ if ( !mbMap )
+ return nHeight;
+
+ return ImplLogicToPixel( nHeight, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY );
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplDevicePixelToLogicWidth( long nWidth ) const
+{
+ if ( !mbMap )
+ return nWidth;
+
+ return ImplPixelToLogic( nWidth, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresPixToLogX );
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::ImplDevicePixelToLogicHeight( long nHeight ) const
+{
+ if ( !mbMap )
+ return nHeight;
+
+ return ImplPixelToLogic( nHeight, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresPixToLogY );
+}
+
+// -----------------------------------------------------------------------
+
+Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const
+{
+ if ( !mbMap )
+ return Point( rLogicPt.X()+mnOutOffX, rLogicPt.Y()+mnOutOffY );
+
+ return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX )+mnOutOffX,
+ ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY )+mnOutOffY );
+}
+
+// -----------------------------------------------------------------------
+
+Size OutputDevice::ImplLogicToDevicePixel( const Size& rLogicSize ) const
+{
+ if ( !mbMap )
+ return rLogicSize;
+
+ return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX ),
+ ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::ImplLogicToDevicePixel( const Rectangle& rLogicRect ) const
+{
+ if ( rLogicRect.IsEmpty() )
+ return rLogicRect;
+
+ if ( !mbMap )
+ {
+ return Rectangle( rLogicRect.Left()+mnOutOffX, rLogicRect.Top()+mnOutOffY,
+ rLogicRect.Right()+mnOutOffX, rLogicRect.Bottom()+mnOutOffY );
+ }
+
+ return Rectangle( ImplLogicToPixel( rLogicRect.Left()+maMapRes.mnMapOfsX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX )+mnOutOffX,
+ ImplLogicToPixel( rLogicRect.Top()+maMapRes.mnMapOfsY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY )+mnOutOffY,
+ ImplLogicToPixel( rLogicRect.Right()+maMapRes.mnMapOfsX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX )+mnOutOffX,
+ ImplLogicToPixel( rLogicRect.Bottom()+maMapRes.mnMapOfsY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY )+mnOutOffY );
+}
+
+// -----------------------------------------------------------------------
+
+Polygon OutputDevice::ImplLogicToDevicePixel( const Polygon& rLogicPoly ) const
+{
+ if ( !mbMap && !mnOutOffX && !mnOutOffY )
+ return rLogicPoly;
+
+ USHORT i;
+ USHORT nPoints = rLogicPoly.GetSize();
+ Polygon aPoly( rLogicPoly );
+
+ // Pointer auf das Point-Array holen (Daten werden kopiert)
+#ifdef WIN
+ Point huge* pPointAry = (Point huge*)aPoly.ImplGetPointAry();
+#else
+ Point* pPointAry = aPoly.ImplGetPointAry();
+#endif
+
+ if ( mbMap )
+ {
+ for ( i = 0; i < nPoints; i++ )
+ {
+ Point* pPt = &(pPointAry[i]);
+ pPt->X() = ImplLogicToPixel( pPt->X()+maMapRes.mnMapOfsX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX )+mnOutOffX;
+ pPt->Y() = ImplLogicToPixel( pPt->Y()+maMapRes.mnMapOfsY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY )+mnOutOffY;
+ }
+ }
+ else
+ {
+ for ( i = 0; i < nPoints; i++ )
+ {
+ Point* pPt = &(pPointAry[i]);
+ pPt->X() += mnOutOffX;
+ pPt->Y() += mnOutOffY;
+ }
+ }
+
+ return aPoly;
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon OutputDevice::ImplLogicToDevicePixel( const PolyPolygon& rLogicPolyPoly ) const
+{
+ if ( !mbMap && !mnOutOffX && !mnOutOffY )
+ return rLogicPolyPoly;
+
+ PolyPolygon aPolyPoly( rLogicPolyPoly );
+ USHORT nPoly = aPolyPoly.Count();
+ for( USHORT i = 0; i < nPoly; i++ )
+ {
+ Polygon& rPoly = aPolyPoly[i];
+ rPoly = ImplLogicToDevicePixel( rPoly );
+ }
+ return aPolyPoly;
+}
+
+// -----------------------------------------------------------------------
+
+LineInfo OutputDevice::ImplLogicToDevicePixel( const LineInfo& rLineInfo ) const
+{
+ LineInfo aInfo( rLineInfo );
+
+ if( aInfo.GetStyle() == LINE_DASH )
+ {
+ if( aInfo.GetDotCount() && aInfo.GetDotLen() )
+ aInfo.SetDotLen( Max( ImplLogicWidthToDevicePixel( aInfo.GetDotLen() ), 1L ) );
+ else
+ aInfo.SetDotCount( 0 );
+
+ if( aInfo.GetDashCount() && aInfo.GetDashLen() )
+ aInfo.SetDashLen( Max( ImplLogicWidthToDevicePixel( aInfo.GetDashLen() ), 1L ) );
+ else
+ aInfo.SetDashCount( 0 );
+
+ aInfo.SetDistance( ImplLogicWidthToDevicePixel( aInfo.GetDistance() ) );
+
+ if( ( !aInfo.GetDashCount() && !aInfo.GetDotCount() ) || !aInfo.GetDistance() )
+ aInfo.SetStyle( LINE_SOLID );
+ }
+
+ aInfo.SetWidth( ImplLogicWidthToDevicePixel( aInfo.GetWidth() ) );
+
+ return aInfo;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::ImplDevicePixelToLogic( const Rectangle& rPixelRect ) const
+{
+ if ( rPixelRect.IsEmpty() )
+ return rPixelRect;
+
+ if ( !mbMap )
+ {
+ return Rectangle( rPixelRect.Left()-mnOutOffX, rPixelRect.Top()-mnOutOffY,
+ rPixelRect.Right()-mnOutOffX, rPixelRect.Bottom()-mnOutOffY );
+ }
+
+ return Rectangle( ImplPixelToLogic( rPixelRect.Left()-mnOutOffX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
+ ImplPixelToLogic( rPixelRect.Top()-mnOutOffY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY,
+ ImplPixelToLogic( rPixelRect.Right()-mnOutOffX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
+ ImplPixelToLogic( rPixelRect.Bottom()-mnOutOffY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY );
+}
+
+// -----------------------------------------------------------------------
+
+Region OutputDevice::ImplPixelToDevicePixel( const Region& rRegion ) const
+{
+ DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
+
+ if ( !mnOutOffX && !mnOutOffY )
+ return rRegion;
+
+ Region aRegion( rRegion );
+ aRegion.Move( mnOutOffX, mnOutOffY );
+ return aRegion;
+}
+
+// -----------------------------------------------------------------------
+
+Point OutputDevice::LogicToPixel( const Point& rLogicPt ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( !mbMap )
+ return rLogicPt;
+
+ return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX ),
+ ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Size OutputDevice::LogicToPixel( const Size& rLogicSize ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( !mbMap )
+ return rLogicSize;
+
+ return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX ),
+ ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( !mbMap || rLogicRect.IsEmpty() )
+ return rLogicRect;
+
+ return Rectangle( ImplLogicToPixel( rLogicRect.Left() + maMapRes.mnMapOfsX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX ),
+ ImplLogicToPixel( rLogicRect.Top() + maMapRes.mnMapOfsY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY ),
+ ImplLogicToPixel( rLogicRect.Right() + maMapRes.mnMapOfsX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX ),
+ ImplLogicToPixel( rLogicRect.Bottom() + maMapRes.mnMapOfsY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
+
+ if ( !mbMap )
+ return rLogicPoly;
+
+ USHORT i;
+ USHORT nPoints = rLogicPoly.GetSize();
+ Polygon aPoly( rLogicPoly );
+
+ // Pointer auf das Point-Array holen (Daten werden kopiert)
+#ifdef WIN
+ Point huge* pPointAry = (Point huge*)aPoly.ImplGetPointAry();
+#else
+ Point* pPointAry = aPoly.ImplGetPointAry();
+#endif
+
+ for ( i = 0; i < nPoints; i++ )
+ {
+ Point* pPt = &(pPointAry[i]);
+ pPt->X() = ImplLogicToPixel( pPt->X() + maMapRes.mnMapOfsX, mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresLogToPixX );
+ pPt->Y() = ImplLogicToPixel( pPt->Y() + maMapRes.mnMapOfsY, mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresLogToPixY );
+ }
+
+ return aPoly;
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
+
+ if ( !mbMap )
+ return rLogicPolyPoly;
+
+ PolyPolygon aPolyPoly( rLogicPolyPoly );
+ USHORT nPoly = aPolyPoly.Count();
+ for( USHORT i = 0; i < nPoly; i++ )
+ {
+ Polygon& rPoly = aPolyPoly[i];
+ rPoly = LogicToPixel( rPoly );
+ }
+ return aPolyPoly;
+}
+
+// -----------------------------------------------------------------------
+
+Region OutputDevice::LogicToPixel( const Region& rLogicRegion ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rLogicRegion, Region, ImplDbgTestRegion );
+
+ RegionType eType = rLogicRegion.GetType();
+
+ if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
+ return rLogicRegion;
+
+ Region aRegion;
+ PolyPolygon* pPolyPoly = rLogicRegion.ImplGetImplRegion()->mpPolyPoly;
+
+ if ( pPolyPoly )
+ aRegion = Region( LogicToPixel( *pPolyPoly ) );
+ else
+ {
+ long nX;
+ long nY;
+ long nWidth;
+ long nHeight;
+ ImplRegionInfo aInfo;
+ BOOL bRegionRect;
+
+ aRegion.ImplBeginAddRect();
+ bRegionRect = rLogicRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+ while ( bRegionRect )
+ {
+ Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
+ aRegion.ImplAddRect( LogicToPixel( aRect ) );
+ bRegionRect = rLogicRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+ }
+ aRegion.ImplEndAddRect();
+ }
+
+ return aRegion;
+}
+
+// -----------------------------------------------------------------------
+
+Point OutputDevice::LogicToPixel( const Point& rLogicPt,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( rMapMode.IsDefault() )
+ return rLogicPt;
+
+ // MapMode-Aufloesung berechnen und Umrechnen
+ ImplMapRes aMapRes;
+ ImplThresholdRes aThresRes;
+ ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
+
+ return Point( ImplLogicToPixel( rLogicPt.X() + aMapRes.mnMapOfsX, mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresLogToPixX ),
+ ImplLogicToPixel( rLogicPt.Y() + aMapRes.mnMapOfsY, mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresLogToPixY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Size OutputDevice::LogicToPixel( const Size& rLogicSize,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( rMapMode.IsDefault() )
+ return rLogicSize;
+
+ // MapMode-Aufloesung berechnen und Umrechnen
+ ImplMapRes aMapRes;
+ ImplThresholdRes aThresRes;
+ ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
+
+ return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresLogToPixX ),
+ ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresLogToPixY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( rMapMode.IsDefault() || rLogicRect.IsEmpty() )
+ return rLogicRect;
+
+ // MapMode-Aufloesung berechnen und Umrechnen
+ ImplMapRes aMapRes;
+ ImplThresholdRes aThresRes;
+ ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
+
+ return Rectangle( ImplLogicToPixel( rLogicRect.Left() + aMapRes.mnMapOfsX, mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresLogToPixX ),
+ ImplLogicToPixel( rLogicRect.Top() + aMapRes.mnMapOfsY, mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresLogToPixY ),
+ ImplLogicToPixel( rLogicRect.Right() + aMapRes.mnMapOfsX, mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresLogToPixX ),
+ ImplLogicToPixel( rLogicRect.Bottom() + aMapRes.mnMapOfsY, mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresLogToPixY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
+
+ if ( rMapMode.IsDefault() )
+ return rLogicPoly;
+
+ // MapMode-Aufloesung berechnen und Umrechnen
+ ImplMapRes aMapRes;
+ ImplThresholdRes aThresRes;
+ ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
+
+ USHORT i;
+ USHORT nPoints = rLogicPoly.GetSize();
+ Polygon aPoly( rLogicPoly );
+
+ // Pointer auf das Point-Array holen (Daten werden kopiert)
+#ifdef WIN
+ Point huge* pPointAry = (Point huge*)aPoly.ImplGetPointAry();
+#else
+ Point* pPointAry = aPoly.ImplGetPointAry();
+#endif
+
+ for ( i = 0; i < nPoints; i++ )
+ {
+ Point* pPt = &(pPointAry[i]);
+ pPt->X() = ImplLogicToPixel( pPt->X() + aMapRes.mnMapOfsX, mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresLogToPixX );
+ pPt->Y() = ImplLogicToPixel( pPt->Y() + aMapRes.mnMapOfsY, mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresLogToPixY );
+ }
+
+ return aPoly;
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
+
+ if ( rMapMode.IsDefault() )
+ return rLogicPolyPoly;
+
+ PolyPolygon aPolyPoly( rLogicPolyPoly );
+ USHORT nPoly = aPolyPoly.Count();
+ for( USHORT i = 0; i < nPoly; i++ )
+ {
+ Polygon& rPoly = aPolyPoly[i];
+ rPoly = LogicToPixel( rPoly, rMapMode );
+ }
+ return aPolyPoly;
+}
+
+// -----------------------------------------------------------------------
+
+Region OutputDevice::LogicToPixel( const Region& rLogicRegion,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rLogicRegion, Region, ImplDbgTestRegion );
+
+ RegionType eType = rLogicRegion.GetType();
+
+ if ( rMapMode.IsDefault() || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
+ return rLogicRegion;
+
+ Region aRegion;
+ PolyPolygon* pPolyPoly = rLogicRegion.ImplGetImplRegion()->mpPolyPoly;
+
+ if( pPolyPoly )
+ aRegion = Region( LogicToPixel( *pPolyPoly, rMapMode ) );
+ else
+ {
+ long nX;
+ long nY;
+ long nWidth;
+ long nHeight;
+ ImplRegionInfo aInfo;
+ BOOL bRegionRect;
+
+ aRegion.ImplBeginAddRect();
+ bRegionRect = rLogicRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+ while ( bRegionRect )
+ {
+ Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
+ aRegion.ImplAddRect( LogicToPixel( aRect, rMapMode ) );
+ bRegionRect = rLogicRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+ }
+ aRegion.ImplEndAddRect();
+ }
+
+ return aRegion;
+}
+
+// -----------------------------------------------------------------------
+
+Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( !mbMap )
+ return rDevicePt;
+
+ return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX,
+ ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY );
+}
+
+// -----------------------------------------------------------------------
+
+Size OutputDevice::PixelToLogic( const Size& rDeviceSize ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( !mbMap )
+ return rDeviceSize;
+
+ return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresPixToLogX ),
+ ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresPixToLogY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ if ( !mbMap || rDeviceRect.IsEmpty() )
+ return rDeviceRect;
+
+ return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX,
+ ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY,
+ ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX,
+ ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY );
+}
+
+// -----------------------------------------------------------------------
+
+Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
+
+ if ( !mbMap )
+ return rDevicePoly;
+
+ USHORT i;
+ USHORT nPoints = rDevicePoly.GetSize();
+ Polygon aPoly( rDevicePoly );
+
+ // Pointer auf das Point-Array holen (Daten werden kopiert)
+#ifdef WIN
+ Point huge* pPointAry = (Point huge*)aPoly.ImplGetPointAry();
+#else
+ Point* pPointAry = aPoly.ImplGetPointAry();
+#endif
+
+ for ( i = 0; i < nPoints; i++ )
+ {
+ Point* pPt = &(pPointAry[i]);
+ pPt->X() = ImplPixelToLogic( pPt->X(), mnDPIX,
+ maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
+ maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX;
+ pPt->Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
+ maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
+ maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY;
+ }
+
+ return aPoly;
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
+
+ if ( !mbMap )
+ return rDevicePolyPoly;
+
+ PolyPolygon aPolyPoly( rDevicePolyPoly );
+ USHORT nPoly = aPolyPoly.Count();
+ for( USHORT i = 0; i < nPoly; i++ )
+ {
+ Polygon& rPoly = aPolyPoly[i];
+ rPoly = PixelToLogic( rPoly );
+ }
+ return aPolyPoly;
+}
+
+// -----------------------------------------------------------------------
+
+Region OutputDevice::PixelToLogic( const Region& rDeviceRegion ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rDeviceRegion, Region, ImplDbgTestRegion );
+
+ RegionType eType = rDeviceRegion.GetType();
+
+ if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
+ return rDeviceRegion;
+
+ Region aRegion;
+ PolyPolygon* pPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
+
+ if ( pPolyPoly )
+ aRegion = Region( PixelToLogic( *pPolyPoly ) );
+ else
+ {
+ long nX;
+ long nY;
+ long nWidth;
+ long nHeight;
+ ImplRegionInfo aInfo;
+ BOOL bRegionRect;
+
+ aRegion.ImplBeginAddRect();
+ bRegionRect = rDeviceRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+ while ( bRegionRect )
+ {
+ Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
+ aRegion.ImplAddRect( PixelToLogic( aRect ) );
+ bRegionRect = rDeviceRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+ }
+ aRegion.ImplEndAddRect();
+ }
+
+ return aRegion;
+}
+
+// -----------------------------------------------------------------------
+
+Point OutputDevice::PixelToLogic( const Point& rDevicePt,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ // Ist Default-MapMode, dann bereche nichts
+ if ( rMapMode.IsDefault() )
+ return rDevicePt;
+
+ // MapMode-Aufloesung berechnen und Umrechnen
+ ImplMapRes aMapRes;
+ ImplThresholdRes aThresRes;
+ ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
+
+ return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX,
+ ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY );
+}
+
+// -----------------------------------------------------------------------
+
+Size OutputDevice::PixelToLogic( const Size& rDeviceSize,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ // Ist Default-MapMode, dann bereche nichts
+ if ( rMapMode.IsDefault() )
+ return rDeviceSize;
+
+ // MapMode-Aufloesung berechnen und Umrechnen
+ ImplMapRes aMapRes;
+ ImplThresholdRes aThresRes;
+ ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
+
+ return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresPixToLogX ),
+ ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresPixToLogY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+ // Ist Default-MapMode, dann bereche nichts
+ if ( rMapMode.IsDefault() || rDeviceRect.IsEmpty() )
+ return rDeviceRect;
+
+ // MapMode-Aufloesung berechnen und Umrechnen
+ ImplMapRes aMapRes;
+ ImplThresholdRes aThresRes;
+ ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
+
+ return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX,
+ ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY,
+ ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX,
+ ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY );
+}
+
+// -----------------------------------------------------------------------
+
+Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
+
+ // Ist Default-MapMode, dann bereche nichts
+ if ( rMapMode.IsDefault() )
+ return rDevicePoly;
+
+ // MapMode-Aufloesung berechnen und Umrechnen
+ ImplMapRes aMapRes;
+ ImplThresholdRes aThresRes;
+ ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
+
+ USHORT i;
+ USHORT nPoints = rDevicePoly.GetSize();
+ Polygon aPoly( rDevicePoly );
+
+ // Pointer auf das Point-Array holen (Daten werden kopiert)
+#ifdef WIN
+ Point huge* pPointAry = (Point huge*)aPoly.ImplGetPointAry();
+#else
+ Point* pPointAry = aPoly.ImplGetPointAry();
+#endif
+
+ for ( i = 0; i < nPoints; i++ )
+ {
+ Point* pPt = &(pPointAry[i]);
+ pPt->X() = ImplPixelToLogic( pPt->X(), mnDPIX,
+ aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
+ aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX;
+ pPt->Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
+ aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
+ aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY;
+ }
+
+ return aPoly;
+}
+
+// -----------------------------------------------------------------------
+
+PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
+
+ if ( rMapMode.IsDefault() )
+ return rDevicePolyPoly;
+
+ PolyPolygon aPolyPoly( rDevicePolyPoly );
+ USHORT nPoly = aPolyPoly.Count();
+ for( USHORT i = 0; i < nPoly; i++ )
+ {
+ Polygon& rPoly = aPolyPoly[i];
+ rPoly = PixelToLogic( rPoly, rMapMode );
+ }
+ return aPolyPoly;
+}
+
+// -----------------------------------------------------------------------
+
+Region OutputDevice::PixelToLogic( const Region& rDeviceRegion,
+ const MapMode& rMapMode ) const
+{
+ DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DBG_CHKOBJ( &rDeviceRegion, Region, ImplDbgTestRegion );
+
+ RegionType eType = rDeviceRegion.GetType();
+
+ if ( rMapMode.IsDefault() || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
+ return rDeviceRegion;
+
+ Region aRegion;
+ PolyPolygon* pPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
+
+ if ( pPolyPoly )
+ aRegion = Region( PixelToLogic( *pPolyPoly, rMapMode ) );
+ else
+ {
+ long nX;
+ long nY;
+ long nWidth;
+ long nHeight;
+ ImplRegionInfo aInfo;
+ BOOL bRegionRect;
+
+ aRegion.ImplBeginAddRect();
+ bRegionRect = rDeviceRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+ while ( bRegionRect )
+ {
+ Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
+ aRegion.ImplAddRect( PixelToLogic( aRect, rMapMode ) );
+ bRegionRect = rDeviceRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+ }
+ aRegion.ImplEndAddRect();
+ }
+
+ return aRegion;
+}
+
+// -----------------------------------------------------------------------
+
+#define ENTER0( rSource, pMapModeSource, pMapModeDest ) \
+ if ( !pMapModeSource ) \
+ pMapModeSource = &maMapMode; \
+ if ( !pMapModeDest ) \
+ pMapModeDest = &maMapMode; \
+ if ( *pMapModeSource == *pMapModeDest ) \
+ return rSource
+
+// -----------------------------------------------------------------------
+
+#define ENTER1( rSource, pMapModeSource, pMapModeDest ) \
+ ENTER0( rSource, pMapModeSource, pMapModeDest ); \
+ \
+ ImplMapRes aMapResSource; \
+ ImplMapRes aMapResDest; \
+ \
+ if ( !mbMap || pMapModeSource != &maMapMode ) \
+ { \
+ if ( pMapModeSource->GetMapUnit() == MAP_RELATIVE ) \
+ aMapResSource = maMapRes; \
+ ImplCalcMapResolution( *pMapModeSource, \
+ mnDPIX, mnDPIY, aMapResSource ); \
+ } \
+ else \
+ aMapResSource = maMapRes; \
+ if ( !mbMap || pMapModeDest != &maMapMode ) \
+ { \
+ if ( pMapModeDest->GetMapUnit() == MAP_RELATIVE ) \
+ aMapResDest = maMapRes; \
+ ImplCalcMapResolution( *pMapModeDest, \
+ mnDPIX, mnDPIY, aMapResDest ); \
+ } \
+ else \
+ aMapResDest = maMapRes
+
+// -----------------------------------------------------------------------
+
+#define ENTER2( eUnitSource, eUnitDest ) \
+ DBG_ASSERT( eUnitSource != MAP_SYSFONT \
+ && eUnitSource != MAP_APPFONT \
+ && eUnitSource != MAP_RELATIVE, \
+ "Source MapUnit nicht erlaubt" ); \
+ DBG_ASSERT( eUnitDest != MAP_SYSFONT \
+ && eUnitDest != MAP_APPFONT \
+ && eUnitDest != MAP_RELATIVE, \
+ "Destination MapUnit nicht erlaubt" ); \
+ DBG_ASSERTWARNING( eUnitSource != MAP_PIXEL, \
+ "MAP_PIXEL mit 72dpi angenaehert" ); \
+ DBG_ASSERTWARNING( eUnitDest != MAP_PIXEL, \
+ "MAP_PIXEL mit 72dpi angenaehert" )
+
+// -----------------------------------------------------------------------
+
+#define ENTER3( eUnitSource, eUnitDest ) \
+ long nNumerator = aImplNumeratorAry[eUnitSource] * \
+ aImplDenominatorAry[eUnitDest]; \
+ long nDenominator = aImplNumeratorAry[eUnitDest] * \
+ aImplDenominatorAry[eUnitSource]; \
+ if ( eUnitSource == MAP_PIXEL ) \
+ nDenominator *= 72; \
+ else if( eUnitDest == MAP_PIXEL ) \
+ nNumerator *= 72
+
+// -----------------------------------------------------------------------
+
+#define ENTER4( rMapModeSource, rMapModeDest ) \
+ ImplMapRes aMapResSource; \
+ ImplMapRes aMapResDest; \
+ \
+ ImplCalcMapResolution( rMapModeSource, 72, 72, aMapResSource ); \
+ ImplCalcMapResolution( rMapModeDest, 72, 72, aMapResDest )
+
+// -----------------------------------------------------------------------
+
+// return (n1 * n2 * n3) / (n4 * n5)
+static long fn5( const long n1,
+ const long n2,
+ const long n3,
+ const long n4,
+ const long n5 )
+{
+ if ( n1 == 0 || n2 == 0 || n3 == 0 || n4 == 0 || n5 == 0 )
+ return 0;
+ if ( LONG_MAX / Abs(n2) < Abs(n3) )
+ {
+ // a6 wird "ubersprungen
+ BigInt a7 = n2;
+ a7 *= n3;
+ a7 *= n1;
+
+ if ( LONG_MAX / Abs(n4) < Abs(n5) )
+ {
+ BigInt a8 = n4;
+ a8 *= n5;
+
+ BigInt a9 = a8;
+ a9 /= 2;
+ if ( a7.IsNeg() )
+ a7 -= a9;
+ else
+ a7 += a9;
+
+ a7 /= a8;
+ } // of if
+ else
+ {
+ long n8 = n4 * n5;
+
+ if ( a7.IsNeg() )
+ a7 -= n8 / 2;
+ else
+ a7 += n8 / 2;
+
+ a7 /= n8;
+ } // of else
+ return (long)a7;
+ } // of if
+ else
+ {
+ long n6 = n2 * n3;
+
+ if ( LONG_MAX / Abs(n1) < Abs(n6) )
+ {
+ BigInt a7 = n1;
+ a7 *= n6;
+
+ if ( LONG_MAX / Abs(n4) < Abs(n5) )
+ {
+ BigInt a8 = n4;
+ a8 *= n5;
+
+ BigInt a9 = a8;
+ a9 /= 2;
+ if ( a7.IsNeg() )
+ a7 -= a9;
+ else
+ a7 += a9;
+
+ a7 /= a8;
+ } // of if
+ else
+ {
+ long n8 = n4 * n5;
+
+ if ( a7.IsNeg() )
+ a7 -= n8 / 2;
+ else
+ a7 += n8 / 2;
+
+ a7 /= n8;
+ } // of else
+ return (long)a7;
+ } // of if
+ else
+ {
+ long n7 = n1 * n6;
+
+ if ( LONG_MAX / Abs(n4) < Abs(n5) )
+ {
+ BigInt a7 = n7;
+ BigInt a8 = n4;
+ a8 *= n5;
+
+ BigInt a9 = a8;
+ a9 /= 2;
+ if ( a7.IsNeg() )
+ a7 -= a9;
+ else
+ a7 += a9;
+
+ a7 /= a8;
+ return (long)a7;
+ } // of if
+ else
+ {
+ const long n8 = n4 * n5;
+ const long n8_2 = n8 / 2;
+
+ if( n7 < 0 )
+ {
+ if( ( n7 - LONG_MIN ) >= n8_2 )
+ n7 -= n8_2;
+ }
+ else if( ( LONG_MAX - n7 ) >= n8_2 )
+ n7 += n8_2;
+
+ return n7 / n8;
+ } // of else
+ } // of else
+ } // of else
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+// return (n1 * n2) / n3
+static long fn3( const long n1, const long n2, const long n3 )
+{
+ if ( n1 == 0 || n2 == 0 || n3 == 0 )
+ return 0;
+ if ( LONG_MAX / Abs(n1) < Abs(n2) )
+ {
+ BigInt a4 = n1;
+ a4 *= n2;
+
+ if ( a4.IsNeg() )
+ a4 -= n3 / 2;
+ else
+ a4 += n3 / 2;
+
+ a4 /= n3;
+ return (long)a4;
+ } // of if
+ else
+ {
+ long n4 = n1 * n2;
+ const long n3_2 = n3 / 2;
+
+ if( n4 < 0 )
+ {
+ if( ( n4 - LONG_MIN ) >= n3_2 )
+ n4 -= n3_2;
+ }
+ else if( ( LONG_MAX - n4 ) >= n3_2 )
+ n4 += n3_2;
+
+ return n4 / n3;
+ } // of else
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Point OutputDevice::LogicToLogic( const Point& rPtSource,
+ const MapMode* pMapModeSource,
+ const MapMode* pMapModeDest ) const
+{
+ ENTER1( rPtSource, pMapModeSource, pMapModeDest );
+
+ return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
+ aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
+ aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
+ aMapResDest.mnMapOfsX,
+ fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
+ aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
+ aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
+ aMapResDest.mnMapOfsY );
+}
+
+// -----------------------------------------------------------------------
+
+Size OutputDevice::LogicToLogic( const Size& rSzSource,
+ const MapMode* pMapModeSource,
+ const MapMode* pMapModeDest ) const
+{
+ ENTER1( rSzSource, pMapModeSource, pMapModeDest );
+
+ return Size( fn5( rSzSource.Width(),
+ aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
+ aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
+ fn5( rSzSource.Height(),
+ aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
+ aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
+ const MapMode* pMapModeSource,
+ const MapMode* pMapModeDest ) const
+{
+ ENTER1( rRectSource, pMapModeSource, pMapModeDest );
+
+ return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
+ aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
+ aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
+ aMapResDest.mnMapOfsX,
+ fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
+ aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
+ aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
+ aMapResDest.mnMapOfsY,
+ fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
+ aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
+ aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
+ aMapResDest.mnMapOfsX,
+ fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
+ aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
+ aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
+ aMapResDest.mnMapOfsY );
+}
+
+// -----------------------------------------------------------------------
+
+long* OutputDevice::LogicToLogic( long* pX, USHORT nCount,
+ const MapMode* pMapModeSource,
+ const MapMode* pMapModeDest ) const
+{
+ ENTER1( pX, pMapModeSource, pMapModeDest );
+
+ for( ; nCount; nCount--, pX++ )
+ {
+ *pX = fn5( *pX,
+ aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
+ aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX );
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+Point OutputDevice::LogicToLogic( const Point& rPtSource,
+ const MapMode& rMapModeSource,
+ const MapMode& rMapModeDest )
+{
+ if ( rMapModeSource == rMapModeDest )
+ return rPtSource;
+
+ MapUnit eUnitSource = rMapModeSource.GetMapUnit();
+ MapUnit eUnitDest = rMapModeDest.GetMapUnit();
+ ENTER2( eUnitSource, eUnitDest );
+
+ if ( rMapModeSource.mpImplMapMode->mbSimple &&
+ rMapModeDest.mpImplMapMode->mbSimple )
+ {
+ ENTER3( eUnitSource, eUnitDest );
+
+ return Point( fn3( rPtSource.X(), nNumerator, nDenominator ),
+ fn3( rPtSource.Y(), nNumerator, nDenominator ) );
+ }
+ else
+ {
+ ENTER4( rMapModeSource, rMapModeDest );
+
+ return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
+ aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
+ aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
+ aMapResDest.mnMapOfsX,
+ fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
+ aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
+ aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
+ aMapResDest.mnMapOfsY );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size OutputDevice::LogicToLogic( const Size& rSzSource,
+ const MapMode& rMapModeSource,
+ const MapMode& rMapModeDest )
+{
+ if ( rMapModeSource == rMapModeDest )
+ return rSzSource;
+
+ MapUnit eUnitSource = rMapModeSource.GetMapUnit();
+ MapUnit eUnitDest = rMapModeDest.GetMapUnit();
+ ENTER2( eUnitSource, eUnitDest );
+
+ if ( rMapModeSource.mpImplMapMode->mbSimple &&
+ rMapModeDest.mpImplMapMode->mbSimple )
+ {
+ ENTER3( eUnitSource, eUnitDest );
+
+ return Size( fn3( rSzSource.Width(), nNumerator, nDenominator ),
+ fn3( rSzSource.Height(), nNumerator, nDenominator ) );
+ }
+ else
+ {
+ ENTER4( rMapModeSource, rMapModeDest );
+
+ return Size( fn5( rSzSource.Width(),
+ aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
+ aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
+ fn5( rSzSource.Height(),
+ aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
+ aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
+ const MapMode& rMapModeSource,
+ const MapMode& rMapModeDest )
+{
+ if ( rMapModeSource == rMapModeDest )
+ return rRectSource;
+
+ MapUnit eUnitSource = rMapModeSource.GetMapUnit();
+ MapUnit eUnitDest = rMapModeDest.GetMapUnit();
+ ENTER2( eUnitSource, eUnitDest );
+
+ if ( rMapModeSource.mpImplMapMode->mbSimple &&
+ rMapModeDest.mpImplMapMode->mbSimple )
+ {
+ ENTER3( eUnitSource, eUnitDest );
+
+ return Rectangle( fn3( rRectSource.Left(), nNumerator, nDenominator ),
+ fn3( rRectSource.Top(), nNumerator, nDenominator ),
+ fn3( rRectSource.Right(), nNumerator, nDenominator ),
+ fn3( rRectSource.Bottom(), nNumerator, nDenominator ) );
+ }
+ else
+ {
+ ENTER4( rMapModeSource, rMapModeDest );
+
+ return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
+ aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
+ aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
+ aMapResDest.mnMapOfsX,
+ fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
+ aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
+ aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
+ aMapResDest.mnMapOfsY,
+ fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
+ aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
+ aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
+ aMapResDest.mnMapOfsX,
+ fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
+ aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
+ aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
+ aMapResDest.mnMapOfsY );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long OutputDevice::LogicToLogic( long nLongSource,
+ MapUnit eUnitSource, MapUnit eUnitDest )
+{
+ if ( eUnitSource == eUnitDest )
+ return nLongSource;
+
+ ENTER2( eUnitSource, eUnitDest );
+ ENTER3( eUnitSource, eUnitDest );
+
+ return fn3( nLongSource, nNumerator, nDenominator );
+}
+
+// -----------------------------------------------------------------------
+
+long Window::ImplLogicUnitToPixelX( long nX, MapUnit eUnit )
+{
+ if ( eUnit != MAP_PIXEL )
+ {
+ ImplFrameData* pFrameData = mpFrameData;
+
+ // Map-Einheit verschieden, dann neu berechnen
+ if ( pFrameData->meMapUnit != eUnit )
+ {
+ pFrameData->meMapUnit = eUnit;
+ ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
+ pFrameData->maMapUnitRes );
+ }
+
+ // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
+ // von Fensterposition benutzt wird
+ nX = nX * mnDPIX * pFrameData->maMapUnitRes.mnMapScNumX;
+ nX += nX >= 0 ? (pFrameData->maMapUnitRes.mnMapScDenomX/2) :
+ -((pFrameData->maMapUnitRes.mnMapScDenomX-1)/2);
+ nX /= pFrameData->maMapUnitRes.mnMapScDenomX;
+ }
+
+ return nX;
+}
+
+// -----------------------------------------------------------------------
+
+long Window::ImplLogicUnitToPixelY( long nY, MapUnit eUnit )
+{
+ if ( eUnit != MAP_PIXEL )
+ {
+ ImplFrameData* pFrameData = mpFrameData;
+
+ // Map-Einheit verschieden, dann neu berechnen
+ if ( pFrameData->meMapUnit != eUnit )
+ {
+ pFrameData->meMapUnit = eUnit;
+ ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
+ pFrameData->maMapUnitRes );
+ }
+
+ // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
+ // von Fensterposition benutzt wird
+ nY = nY * mnDPIY * pFrameData->maMapUnitRes.mnMapScNumY;
+ nY += nY >= 0 ? (pFrameData->maMapUnitRes.mnMapScDenomY/2) :
+ -((pFrameData->maMapUnitRes.mnMapScDenomY-1)/2);
+ nY /= pFrameData->maMapUnitRes.mnMapScDenomY;
+ }
+
+ return nY;
+}
diff --git a/vcl/source/gdi/polyscan.cxx b/vcl/source/gdi/polyscan.cxx
new file mode 100644
index 000000000000..cb9714d51765
--- /dev/null
+++ b/vcl/source/gdi/polyscan.cxx
@@ -0,0 +1,389 @@
+/*************************************************************************
+ *
+ * $RCSfile: polyscan.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <tools/new.hxx>
+#include "salbtype.hxx"
+#include "poly.hxx"
+#include "polyscan.hxx"
+
+// ----------------
+// - PolyScanline -
+// ----------------
+
+PolyScanline::PolyScanline() :
+ mpFirst ( NULL ),
+ mpLast ( NULL ),
+ mpAct ( NULL ),
+ mnLeft ( 0L ),
+ mnRight ( 0L )
+{
+}
+
+// ------------------------------------------------------------------------
+
+PolyScanline::~PolyScanline()
+{
+ ImplDelete();
+}
+
+// ------------------------------------------------------------------------
+
+void PolyScanline::ImplDelete()
+{
+ ScanlinePoint* pAct = mpFirst;
+
+ while( pAct )
+ {
+ ScanlinePoint* pNext = pAct->mpNext;
+ delete pAct;
+ pAct = pNext;
+ }
+
+ mnLeft = mnRight = 0L;
+ mpFirst = mpAct = mpLast = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+void PolyScanline::Insert( long nX )
+{
+ // first point to insert?
+ if( !mpFirst )
+ mpLast = mpFirst = new ScanlinePoint( mnLeft = mnRight = nX, NULL );
+ else
+ {
+ // insert at the beginning of the scanline
+ if( nX <= mpFirst->mnX )
+ mpFirst = new ScanlinePoint( mnLeft = nX, mpFirst );
+ else if( nX >= mnRight )
+ mpLast = mpLast->mpNext = new ScanlinePoint( mnRight = nX, NULL );
+ else
+ {
+ ScanlinePoint* pLast = mpFirst;
+ ScanlinePoint* pAct = mpFirst->mpNext;
+
+ while( pAct )
+ {
+ // insert in the midlle of the scanline?
+ if( nX <= pAct->mnX )
+ {
+ pLast->mpNext = new ScanlinePoint( nX, pAct );
+ break;
+ }
+
+ pLast = pAct;
+ pAct = pAct->mpNext;
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void PolyScanline::Set( long nStart, long nEnd )
+{
+ if( mpFirst )
+ ImplDelete();
+
+ if( nStart <= nEnd )
+ mpFirst = new ScanlinePoint( mnLeft = nStart, mpLast = new ScanlinePoint( mnRight = nEnd, NULL ) );
+ else
+ mpFirst = new ScanlinePoint( mnLeft = nEnd, mpLast = new ScanlinePoint( mnRight = nStart, NULL ) );
+}
+
+// ------------------------------------------------------------------------
+
+BOOL PolyScanline::GetFirstSegment( PolyScanSegment& rSegment )
+{
+ BOOL bRet = GetFirstX( rSegment.mnStart );
+
+ if( bRet && !GetNextX( rSegment.mnEnd ) )
+ rSegment.mnEnd = rSegment.mnStart;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL PolyScanline::GetNextSegment( PolyScanSegment& rSegment )
+{
+ BOOL bRet = GetNextX( rSegment.mnStart );
+
+ if( bRet && !GetNextX( rSegment.mnEnd ) )
+ rSegment.mnEnd = rSegment.mnStart;
+
+ return bRet;
+}
+
+// ---------------
+// - PolyScanner -
+// ---------------
+
+PolyScanner::PolyScanner( const Rectangle& rRect )
+{
+ if( !rRect.IsEmpty() )
+ {
+ Rectangle aRect( rRect );
+ ULONG nHeight;
+
+ aRect.Justify();
+ mnLeft = aRect.Left();
+ mnTop = aRect.Top();
+ mnRight = aRect.Right();
+ mnBottom = aRect.Bottom();
+ mpArray = new PolyScanline[ nHeight = Height() ];
+
+ for( ULONG i = 0UL; i < nHeight; i++ )
+ mpArray[ i ].Set( mnLeft, mnRight );
+ }
+ else
+ {
+ mnLeft = mnTop = mnRight = mnBottom = 0L;
+ mpArray = NULL;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+PolyScanner::PolyScanner( const Polygon& rPoly )
+{
+ const long nCount = rPoly.GetSize();
+
+ if( nCount )
+ {
+ long nLast = nCount - 1;
+ Point aFirst( rPoly[ 0 ] );
+ Point aLast( rPoly[ (USHORT) nLast ] );
+
+ while( nLast && ( aLast == aFirst ) )
+ aLast = rPoly[ (USHORT) --nLast ];
+
+ if( !nLast )
+ {
+ aLast = rPoly[ 0 ];
+ mnLeft = mnRight = aLast.X();
+ mnTop = mnBottom = aLast.Y();
+ mpArray = new PolyScanline[ 1UL ];
+ mpArray[ 0 ].Set( mnLeft, mnRight );
+ }
+ else
+ {
+ const Rectangle aRect( rPoly.GetBoundRect() );
+ ULONG nHeight;
+
+ mnLeft = aRect.Left();
+ mnTop = aRect.Top();
+ mnRight = aRect.Right();
+ mnBottom = aRect.Bottom();
+ aLast = aFirst;
+ mpArray = new PolyScanline[ nHeight = Height() ];
+
+ for( long i = 1L; i <= nLast; i++ )
+ {
+ const Point& rPt = rPoly[ (USHORT) i ];
+
+ if( rPt != aLast )
+ {
+ InsertLine( aLast, rPt );
+ aLast = rPt;
+ }
+ }
+
+ InsertLine( aLast, aFirst );
+ }
+ }
+ else
+ mpArray = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+PolyScanner::PolyScanner( const PolyPolygon& rPolyPoly )
+{
+ mpArray = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+PolyScanner::~PolyScanner()
+{
+ delete[] mpArray;
+}
+
+// ------------------------------------------------------------------------
+
+PolyScanline* PolyScanner::operator[]( ULONG nPos ) const
+{
+ DBG_ASSERT( nPos < Count(), "nPos out of range!" );
+ return( mpArray ? ( mpArray + nPos ) : NULL );
+}
+
+// ------------------------------------------------------------------------
+
+void PolyScanner::InsertLine( const Point& rStart, const Point& rEnd )
+{
+ long nX, nY;
+
+ if( rStart.Y() == rEnd.Y() )
+ mpArray[ rStart.Y() - mnTop ].Insert( rStart.X() );
+ else if( rStart.X() == rEnd.X() )
+ {
+ // vertical line
+ const long nEndY = rEnd.Y();
+
+ nX = rStart.X();
+ nY = rStart.Y();
+
+ if( nEndY > nY )
+ while( nY < nEndY )
+ mpArray[ nY++ - mnTop ].Insert( nX );
+ else
+ while( nY > nEndY )
+ mpArray[ nY-- - mnTop ].Insert( nX );
+ }
+ else
+ {
+ const long nDX = labs( rEnd.X() - rStart.X() );
+ const long nDY = labs( rEnd.Y() - rStart.Y() );
+ const long nStartX = rStart.X();
+ const long nStartY = rStart.Y();
+ const long nEndX = rEnd.X();
+ const long nEndY = rEnd.Y();
+ const long nXInc = ( nStartX < nEndX ) ? 1L : -1L;
+ const long nYInc = ( nStartY < nEndY ) ? 1L : -1L;
+ long nLastX = nStartX;
+ long nLastY = nStartY;
+ BOOL bLast = FALSE;
+
+ mpArray[ nStartY - mnTop ].Insert( nStartX );
+
+ if( nDX >= nDY )
+ {
+ const long nDYX = ( nDY - nDX ) << 1;
+ const long nDY2 = nDY << 1;
+ long nD = nDY2 - nDX;
+
+ for( nX = nStartX, nY = nLastY = nStartY; nX != nEndX; )
+ {
+ if( nY != nLastY )
+ {
+ if( bLast )
+ mpArray[ nLastY - mnTop ].Insert( nLastX );
+
+ mpArray[ nY - mnTop ].Insert( nX );
+ bLast = FALSE;
+ }
+ else
+ bLast = TRUE;
+
+ nLastX = nX;
+ nLastY = nY;
+
+ if( nD < 0L )
+ nD += nDY2;
+ else
+ {
+ nD += nDYX;
+ nY += nYInc;
+ }
+
+ nX += nXInc;
+ }
+ }
+ else
+ {
+ const long nDYX = ( nDX - nDY ) << 1;
+ const long nDY2 = nDX << 1;
+ long nD = nDY2 - nDY;
+
+ for( nX = nStartX, nY = nStartY; nY != nEndY; )
+ {
+ if( nY != nLastY )
+ {
+ if( bLast )
+ mpArray[ nLastY - mnTop ].Insert( nLastX );
+
+ mpArray[ nY - mnTop ].Insert( nX );
+ bLast = FALSE;
+ }
+ else
+ bLast = TRUE;
+
+ nLastX = nX;
+ nLastY = nY;
+
+ if( nD < 0L )
+ nD += nDY2;
+ else
+ {
+ nD += nDYX;
+ nX += nXInc;
+ }
+
+ nY += nYInc;
+ }
+ }
+
+ if( bLast )
+ mpArray[ nLastY - mnTop ].Insert( nLastX );
+ }
+}
diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx
new file mode 100644
index 000000000000..84c54f0cc5b2
--- /dev/null
+++ b/vcl/source/gdi/print.cxx
@@ -0,0 +1,1979 @@
+/*************************************************************************
+ *
+ * $RCSfile: print.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_PRINT_CXX
+#define _SPOOLPRINTER_EXT
+#define _RMPRINTER_EXT
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+
+#ifndef REMOTE_APPSERVER
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALPTYPE_HXX
+#include <salptype.hxx>
+#endif
+#ifndef _SV_SALPRN_HXX
+#include <salprn.hxx>
+#endif
+
+#else
+
+#include "rmoutdev.hxx"
+#include "rmprint.hxx"
+#include "rmwindow.hxx"
+#include "rvp.hxx"
+#include <vos/mutex.hxx>
+
+using namespace ::com::sun::star::uno;
+
+struct SalPrinterQueueInfo
+{
+ XubString maPrinterName;
+ XubString maDriver;
+ XubString maLocation;
+ XubString maComment;
+ ULONG mnStatus;
+ ULONG mnJobs;
+ void* mpSysData;
+
+ SalPrinterQueueInfo();
+ ~SalPrinterQueueInfo();
+};
+
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_JOBSET_H
+#include <jobset.h>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_PRINT_H
+#include <print.h>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_IMPPRN_HXX
+#include <impprn.hxx>
+#endif
+#ifndef _SV_PRINT_HXX
+#include <print.hxx>
+#endif
+
+int nImplSysDialog = 0;
+
+#define PRINTERSEQ_GET( _def_Seq, _def_Obj ) \
+{ \
+ SvMemoryStream* _def_pStm = new SvMemoryStream( (char*)_def_Seq.getConstArray(), _def_Seq.getLength(), STREAM_READ ); \
+ _def_pStm->SetCompressMode( COMPRESSMODE_FULL ); \
+ *_def_pStm >> _def_Obj; \
+ delete _def_pStm; \
+}
+
+#define PRINTERSEQ_SET( _def_Obj, _def_Seq, _def_Type ) \
+{ \
+ SvMemoryStream* _def_pStm = new SvMemoryStream( 8192, 8192 ); \
+ _def_pStm->SetCompressMode( COMPRESSMODE_FULL ); \
+ *_def_pStm << _def_Obj; \
+ _def_Seq = _def_Type( (sal_Int8*) (_def_pStm)->GetData(), (_def_pStm)->Tell() ); \
+ delete _def_pStm; \
+}
+
+// =======================================================================
+
+#define PAPER_SLOPPY 20
+#define PAPER_COUNT 9
+
+static long ImplPaperFormats[PAPER_COUNT*2] =
+{
+ 29700, 42000, // A3
+ 21000, 29700, // A4
+ 14800, 21000, // A5
+ 25000, 35300, // B4
+ 17600, 25000, // B5
+ 21600, 27900, // Letter
+ 21600, 35600, // Legal
+ 27900, 43100, // Tabloid
+ 0, 0 // USER
+};
+
+// =======================================================================
+
+Paper ImplGetPaperFormat( long nWidth100thMM, long nHeight100thMM )
+{
+ USHORT i;
+
+ for( i = 0; i < PAPER_COUNT; i++ )
+ {
+ if ( (ImplPaperFormats[i*2] == nWidth100thMM) &&
+ (ImplPaperFormats[i*2+1] == nHeight100thMM) )
+ return (Paper)i;
+ }
+
+ for( i = 0; i < PAPER_COUNT; i++ )
+ {
+ if ( (Abs( ImplPaperFormats[i*2]-nWidth100thMM ) < PAPER_SLOPPY) &&
+ (Abs( ImplPaperFormats[i*2+1]-nHeight100thMM ) < PAPER_SLOPPY) )
+ return (Paper)i;
+ }
+
+ return PAPER_USER;
+}
+
+// =======================================================================
+
+void ImplUpdateJobSetupPaper( JobSetup& rJobSetup )
+{
+ const ImplJobSetup* pConstData = rJobSetup.ImplGetConstData();
+
+ if ( !pConstData->mnPaperWidth || !pConstData->mnPaperHeight )
+ {
+ if ( pConstData->mePaperFormat != PAPER_USER )
+ {
+ ImplJobSetup* pData = rJobSetup.ImplGetData();
+ pData->mnPaperWidth = ImplPaperFormats[((USHORT)pConstData->mePaperFormat)*2];
+ pData->mnPaperHeight = ImplPaperFormats[((USHORT)pConstData->mePaperFormat)*2+1];
+ }
+ }
+ else if ( pConstData->mePaperFormat == PAPER_USER )
+ {
+ Paper ePaper = ImplGetPaperFormat( pConstData->mnPaperWidth, pConstData->mnPaperHeight );
+ if ( ePaper != PAPER_USER )
+ rJobSetup.ImplGetData()->mePaperFormat = ePaper;
+ }
+}
+
+// =======================================================================
+
+QueueInfo::QueueInfo()
+{
+ mnStatus = 0;
+ mnJobs = 0;
+}
+
+// -----------------------------------------------------------------------
+
+QueueInfo::QueueInfo( const QueueInfo& rInfo ) :
+ maPrinterName( rInfo.maPrinterName ),
+ maDriver( rInfo.maDriver ),
+ maLocation( rInfo.maLocation ),
+ maComment( rInfo.maComment ),
+ mnStatus( rInfo.mnStatus ),
+ mnJobs( rInfo.mnJobs )
+{
+}
+
+// -----------------------------------------------------------------------
+
+QueueInfo::~QueueInfo()
+{
+}
+
+// -----------------------------------------------------------------------
+
+const QueueInfo& QueueInfo::operator==( const QueueInfo& rInfo )
+{
+ maPrinterName = rInfo.maPrinterName;
+ maDriver = rInfo.maDriver;
+ maLocation = rInfo.maLocation;
+ maComment = rInfo.maComment;
+ mnStatus = rInfo.mnStatus;
+ mnJobs = rInfo.mnJobs;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStream, const QueueInfo& rInfo )
+{
+ VersionCompat aCompat( rOStream, STREAM_WRITE, 1 );
+
+ rOStream.WriteByteString( rInfo.maPrinterName, RTL_TEXTENCODING_UTF8 );
+ rOStream.WriteByteString( rInfo.maDriver, RTL_TEXTENCODING_UTF8 );
+ rOStream.WriteByteString( rInfo.maLocation, RTL_TEXTENCODING_UTF8 );
+ rOStream.WriteByteString( rInfo.maComment, RTL_TEXTENCODING_UTF8 );
+ rOStream << rInfo.mnStatus;
+ rOStream << rInfo.mnJobs;
+
+ return rOStream;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStream, QueueInfo& rInfo )
+{
+ VersionCompat aCompat( rIStream, STREAM_READ );
+
+ rIStream.ReadByteString( rInfo.maPrinterName, RTL_TEXTENCODING_UTF8 );
+ rIStream.ReadByteString( rInfo.maDriver, RTL_TEXTENCODING_UTF8 );
+ rIStream.ReadByteString( rInfo.maLocation, RTL_TEXTENCODING_UTF8 );
+ rIStream.ReadByteString( rInfo.maComment, RTL_TEXTENCODING_UTF8 );
+ rIStream >> rInfo.mnStatus;
+ rIStream >> rInfo.mnJobs;
+
+ return rIStream;
+}
+
+// =======================================================================
+
+SalPrinterQueueInfo::SalPrinterQueueInfo()
+{
+ mnStatus = 0;
+ mnJobs = QUEUE_JOBS_DONTKNOW;
+ mpSysData = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+SalPrinterQueueInfo::~SalPrinterQueueInfo()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ImplPrnQueueList::Add( SalPrinterQueueInfo* pData )
+{
+ ImplPrnQueueData* pInfo = new ImplPrnQueueData;
+ pInfo->mpQueueInfo = NULL;
+ pInfo->mpSalQueueInfo = pData;
+ List::Insert( (void*)pInfo, LIST_APPEND );
+}
+
+// =======================================================================
+
+static void ImplInitPrnQueueList()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ pSVData->maGDIData.mpPrinterQueueList = new ImplPrnQueueList;
+
+#ifndef REMOTE_APPSERVER
+ pSVData->mpDefInst->GetPrinterQueueInfo( pSVData->maGDIData.mpPrinterQueueList );
+#else
+ if ( pSVData->mpRemotePrinterList && pSVData->mpRemotePrinterList->GetPrinterCount() )
+ {
+ const ULONG nCount = pSVData->mpRemotePrinterList->GetPrinterCount();
+ for( ULONG i = 0; i < nCount; i++ )
+ {
+ NMSP_CLIENT::RmQueueInfo aRmQInfo;
+ QueueInfo aQInfo;
+ SalPrinterQueueInfo* pNewInfo = new SalPrinterQueueInfo;
+
+ RemotePrinterInfo* pPrinterInfo = pSVData->mpRemotePrinterList->GetPrinter( i );
+ REF( NMSP_CLIENT::XRmPrinterEnvironment ) xPrinterEnv( pSVData->mpRemotePrinterList->GetPrinterEnv( pPrinterInfo->aServerName ) );
+
+ if ( xPrinterEnv.is() && xPrinterEnv->GetPrinterInfo(
+ pPrinterInfo->aPrinterName.GetBuffer(), aRmQInfo ) )
+ {
+ PRINTERSEQ_GET( aRmQInfo, aQInfo );
+ pNewInfo->maPrinterName = pPrinterInfo->GetFullName();
+ pNewInfo->maDriver = aQInfo.GetDriver();
+ pNewInfo->maLocation = aQInfo.GetLocation();
+ pNewInfo->maComment = aQInfo.GetComment();
+ pNewInfo->mnStatus = aQInfo.GetStatus();
+ pNewInfo->mnJobs = aQInfo.GetJobs();
+ pNewInfo->mpSysData = NULL;
+ pSVData->maGDIData.mpPrinterQueueList->Add( pNewInfo );
+ }
+ }
+ }
+ if ( !pSVData->maGDIData.mpPrinterQueueList->Count() )
+ {
+ SalPrinterQueueInfo* pNewInfo = new SalPrinterQueueInfo;
+ pNewInfo->maPrinterName = String::CreateFromAscii("No Printer");
+ pNewInfo->mpSysData = NULL;
+ pSVData->maGDIData.mpPrinterQueueList->Add( pNewInfo );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDeletePrnQueueList()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplPrnQueueList* pPrnList = pSVData->maGDIData.mpPrinterQueueList;
+
+ if ( pPrnList )
+ {
+ ImplPrnQueueData* pInfo = pPrnList->First();
+ while ( pInfo )
+ {
+ if ( pInfo->mpQueueInfo )
+ delete pInfo->mpQueueInfo;
+
+#ifndef REMOTE_APPSERVER
+ pSVData->mpDefInst->DeletePrinterQueueInfo( pInfo->mpSalQueueInfo );
+#else
+ delete pInfo->mpSalQueueInfo;
+#endif
+
+ delete pInfo;
+ pInfo = pPrnList->Next();
+ }
+
+ delete pPrnList;
+ pSVData->maGDIData.mpPrinterQueueList = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Printer::GetQueueCount()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( !pSVData->maGDIData.mpPrinterQueueList )
+ ImplInitPrnQueueList();
+
+ return (USHORT)(pSVData->maGDIData.mpPrinterQueueList->Count());
+}
+
+// -----------------------------------------------------------------------
+
+const QueueInfo& Printer::GetQueueInfo( USHORT nQueue )
+{
+ return GetQueueInfo( nQueue, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+const QueueInfo& Printer::GetQueueInfo( USHORT nQueue, BOOL bStatus )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( !pSVData->maGDIData.mpPrinterQueueList )
+ ImplInitPrnQueueList();
+
+ DBG_ASSERT( nQueue < pSVData->maGDIData.mpPrinterQueueList->Count(),
+ "Printer::GetQueueInfo() - nQueue > QueueCount" );
+
+ ImplPrnQueueData* pInfo = pSVData->maGDIData.mpPrinterQueueList->Get( nQueue );
+
+#ifndef REMOTE_APPSERVER
+ if ( bStatus )
+ pSVData->mpDefInst->GetPrinterQueueState( pInfo->mpSalQueueInfo );
+#else
+ // ???
+#endif
+
+ if ( !pInfo->mpQueueInfo )
+ pInfo->mpQueueInfo = new QueueInfo;
+
+ pInfo->mpQueueInfo->maPrinterName = pInfo->mpSalQueueInfo->maPrinterName;
+ pInfo->mpQueueInfo->maDriver = pInfo->mpSalQueueInfo->maDriver;
+ pInfo->mpQueueInfo->maLocation = pInfo->mpSalQueueInfo->maLocation;
+ pInfo->mpQueueInfo->maComment = pInfo->mpSalQueueInfo->maComment;
+ pInfo->mpQueueInfo->mnStatus = pInfo->mpSalQueueInfo->mnStatus;
+ pInfo->mpQueueInfo->mnJobs = pInfo->mpSalQueueInfo->mnJobs;
+ return *pInfo->mpQueueInfo;
+}
+
+// -----------------------------------------------------------------------
+
+XubString Printer::GetDefaultPrinterName()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+#ifndef REMOTE_APPSERVER
+ return pSVData->mpDefInst->GetDefaultPrinter();
+#else
+ XubString aDefPrinterName;
+ if ( pSVData->mpRemotePrinterList )
+ {
+ RemotePrinterInfo* pDefPrinter = pSVData->mpRemotePrinterList->GetDefaultPrinter();
+ if ( pDefPrinter )
+ aDefPrinterName = pDefPrinter->GetFullName();
+
+ }
+ return aDefPrinterName;
+#endif
+}
+
+// =======================================================================
+
+void Printer::ImplInitData()
+{
+ mbDevOutput = FALSE;
+ meOutDevType = OUTDEV_PRINTER;
+
+ mbDefPrinter = FALSE;
+ mnError = 0;
+ mnCurPage = 0;
+ mnCurPrintPage = 0;
+ mnPageQueueSize = 0;
+ mnCopyCount = 1;
+ mbCollateCopy = FALSE;
+ mbPrinting = FALSE;
+ mbJobActive = FALSE;
+ mbPrintFile = FALSE;
+ mbInPrintPage = FALSE;
+ mbNewJobSetup = FALSE;
+ mpInfoPrinter = NULL;
+ mpPrinter = NULL;
+ mpDisplayDev = NULL;
+ mpQPrinter = NULL;
+ mpQMtf = NULL;
+ mbIsQueuePrinter = FALSE;
+
+ // Printer in die Liste eintragen
+ ImplSVData* pSVData = ImplGetSVData();
+ mpNext = pSVData->maGDIData.mpFirstPrinter;
+ mpPrev = NULL;
+ if ( mpNext )
+ mpNext->mpPrev = this;
+ else
+ pSVData->maGDIData.mpLastPrinter = this;
+ pSVData->maGDIData.mpFirstPrinter = this;
+}
+
+// -----------------------------------------------------------------------
+
+void Printer::ImplInit( SalPrinterQueueInfo* pInfo )
+{
+ // Testen, ob Treiber ueberhaupt mit dem JobSetup uebereinstimmt
+ ImplJobSetup* pJobSetup = maJobSetup.ImplGetData();
+
+ if ( pJobSetup->mpDriverData )
+ {
+ if ( (pJobSetup->maPrinterName != pInfo->maPrinterName) ||
+ (pJobSetup->maDriver != pInfo->maDriver) )
+ {
+ delete pJobSetup->mpDriverData;
+ pJobSetup->mpDriverData = NULL;
+ pJobSetup->mnDriverDataLen = 0;
+ }
+ }
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Printernamen merken
+ maPrinterName = pInfo->maPrinterName;
+ maDriver = pInfo->maDriver;
+
+ // In JobSetup den Printernamen eintragen
+ pJobSetup->maPrinterName = maPrinterName;
+ pJobSetup->maDriver = maDriver;
+
+#ifndef REMOTE_APPSERVER
+ mpInfoPrinter = pSVData->mpDefInst->CreateInfoPrinter( pInfo, pJobSetup );
+ mpPrinter = NULL;
+ mpJobPrinter = NULL;
+ mpJobGraphics = NULL;
+ ImplUpdateJobSetupPaper( maJobSetup );
+
+ if ( !mpInfoPrinter )
+ {
+ ImplInitDisplay( NULL );
+ return;
+ }
+
+ // we need a graphics
+ if ( !ImplGetGraphics() )
+ {
+ ImplInitDisplay( NULL );
+ return;
+ }
+#else
+
+ String aPrinterName( maPrinterName.GetToken( 0, '@' ) );
+ String aPrintServerName( maPrinterName.GetToken( 1, '@' ) );
+
+
+ mpInfoPrinter = new RmPrinter;
+
+ Reference< ::com::sun::star::lang::XMultiServiceFactory > xPrinterFactory;
+ Reference< NMSP_CLIENT::XRmPrinter > xPrinter;
+
+ if (pSVData->mpRemotePrinterList)
+ {
+// if ( !aPrintServerName.Len() )
+// aPrintServerName = pSVData->mpRemotePrinterList->FindLocalPrintServer( aPrinterName );
+
+ xPrinterFactory = pSVData->mpRemotePrinterList->GetServerFactory( aPrintServerName );
+ if( xPrinterFactory.is() )
+ {
+ xPrinter = Reference< NMSP_CLIENT::XRmPrinter >( xPrinterFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OfficePrinter.stardiv.de" ) ) ), NMSP_UNO::UNO_QUERY );
+ mpInfoPrinter->SetInterface( xPrinter );
+ }
+ }
+
+ if ( ! xPrinter.is() )
+ {
+ delete mpInfoPrinter;
+ mpInfoPrinter = NULL;
+ ImplInitDisplay( NULL );
+ return;
+ }
+ else
+ {
+ QueueInfo aQInfo;
+ NMSP_CLIENT::RmQueueInfo aRmQInfo;
+ NMSP_CLIENT::RmJobSetup aRmJobSetup;
+ const REF( NMSP_CLIENT::XRmPrinter )& rxPrinter = mpInfoPrinter->GetInterface();
+
+ aQInfo.maPrinterName = aPrinterName;
+ aQInfo.maDriver = pInfo->maDriver;
+ aQInfo.maLocation = pInfo->maLocation;
+ aQInfo.maComment = pInfo->maComment;
+ aQInfo.mnStatus = pInfo->mnStatus;
+ aQInfo.mnJobs = pInfo->mnJobs;
+
+ PRINTERSEQ_SET( aQInfo, aRmQInfo, NMSP_CLIENT::RmQueueInfo );
+ mpInfoPrinter->Create( aRmQInfo, aRmJobSetup );
+ PRINTERSEQ_GET( aRmJobSetup, maJobSetup );
+
+ if( rxPrinter.is() )
+ {
+ mpGraphics = new ImplServerGraphics( pSVData->mpRemotePrinterList->GetServerAtoms( aPrintServerName ) );
+ mpGraphics->SetInterface( REF( NMSP_CLIENT::XRmOutputDevice )( rxPrinter, NMSP_UNO::UNO_QUERY ) );
+ }
+
+ if( !mpGraphics->GetInterface().is() )
+ {
+ delete mpGraphics, mpGraphics = NULL;
+ delete mpInfoPrinter, mpInfoPrinter = NULL;
+ ImplInitDisplay( NULL );
+ return;
+ }
+ }
+#endif
+
+ // Daten initialisieren
+ ImplUpdatePageData();
+ mpFontList = new ImplDevFontList;
+ mpFontCache = new ImplFontCache( TRUE );
+ mpGraphics->GetDevFontList( mpFontList );
+ mpFontList->InitStdFonts();
+}
+
+// -----------------------------------------------------------------------
+
+void Printer::ImplInitDisplay( const Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ mpInfoPrinter = NULL;
+ mpPrinter = NULL;
+ mpJobPrinter = NULL;
+ mpJobGraphics = NULL;
+
+ if ( pWindow )
+ mpDisplayDev = new VirtualDevice( *pWindow );
+ else
+ mpDisplayDev = new VirtualDevice();
+ mpFontList = pSVData->maGDIData.mpScreenFontList;
+ mpFontCache = pSVData->maGDIData.mpScreenFontCache;
+ mnDPIX = mpDisplayDev->mnDPIX;
+ mnDPIY = mpDisplayDev->mnDPIY;
+
+#ifdef REMOTE_APPSERVER
+ mpGraphics = mpDisplayDev->mpGraphics;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+SalPrinterQueueInfo* Printer::ImplGetQueueInfo( const XubString& rPrinterName,
+ const XubString* pDriver )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->maGDIData.mpPrinterQueueList )
+ ImplInitPrnQueueList();
+
+ ImplPrnQueueList* pPrnList = pSVData->maGDIData.mpPrinterQueueList;
+ if ( pPrnList && pPrnList->Count() )
+ {
+ // Zuerst suchen wir nach dem Printer-Namen
+ ImplPrnQueueData* pBestInfo = NULL;
+ ImplPrnQueueData* pInfo = pPrnList->First();
+ while ( pInfo )
+ {
+ if ( pInfo->mpSalQueueInfo->maPrinterName == rPrinterName )
+ {
+ pBestInfo = pInfo;
+ if ( !pDriver || (pInfo->mpSalQueueInfo->maDriver == *pDriver) )
+ return pInfo->mpSalQueueInfo;
+ }
+ pInfo = pPrnList->Next();
+ }
+
+ // Wenn wir einen PrinterNamen gefunden haben und nur der Treiber
+ // nicht passt, nehmen wir diesen
+ if ( pBestInfo )
+ return pBestInfo->mpSalQueueInfo;
+
+ // Dann suchen wir caseinsensitiv
+ pInfo = pPrnList->First();
+ while ( pInfo )
+ {
+ if ( pInfo->mpSalQueueInfo->maPrinterName.EqualsIgnoreCaseAscii( rPrinterName ) )
+ {
+ pBestInfo = pInfo;
+ if ( !pDriver || pInfo->mpSalQueueInfo->maDriver.EqualsIgnoreCaseAscii( *pDriver ) )
+ return pInfo->mpSalQueueInfo;
+ }
+ pInfo = pPrnList->Next();
+ }
+
+ // Wenn wir einen PrinterNamen gefunden haben und nur der Treiber
+ // nicht passt, nehmen wir diesen
+ if ( pBestInfo )
+ return pBestInfo->mpSalQueueInfo;
+
+ // Und wenn wir immer noch keinen gefunden haben, suchen wir
+ // noch nach einem passenden Treiber
+ if ( pDriver )
+ {
+ pInfo = pPrnList->First();
+ while ( pInfo )
+ {
+ if ( pInfo->mpSalQueueInfo->maDriver == *pDriver )
+ return pInfo->mpSalQueueInfo;
+ pInfo = pPrnList->Next();
+ }
+ }
+
+ // Und wenn wir immer noch keinen gefunden, dann wir der
+ // Default-Drucker genommen
+ XubString aPrinterName = GetDefaultPrinterName();
+ pInfo = pPrnList->First();
+ while ( pInfo )
+ {
+ if ( pInfo->mpSalQueueInfo->maPrinterName == aPrinterName )
+ return pInfo->mpSalQueueInfo;
+ pInfo = pPrnList->Next();
+ }
+
+ // Und wenn wir diesen auch nicht finden, nehmen wir den ersten
+ // in der Liste, denn einige Installationen zerstoeren den
+ // Namen und andere Programme weichen dann normalerweise noch
+ // auf irgendeinen Drucker aus
+ pInfo = pPrnList->First();
+ if ( pInfo )
+ return pInfo->mpSalQueueInfo;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void Printer::ImplUpdatePageData()
+{
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !ImplGetGraphics() )
+ return;
+
+ mpGraphics->GetResolution( mnDPIX, mnDPIY );
+ mpInfoPrinter->GetPageInfo( maJobSetup.ImplGetConstData(),
+ mnOutWidth, mnOutHeight,
+ maPageOffset.X(), maPageOffset.Y(),
+ maPaperSize.Width(), maPaperSize.Height() );
+#else
+ if ( mpInfoPrinter && mpGraphics )
+ {
+ mpGraphics->GetResolution( mnDPIX, mnDPIY );
+ mpInfoPrinter->GetPageInfo( mnOutWidth, mnOutHeight,
+ maPageOffset.X(), maPageOffset.Y(),
+ maPaperSize.Width(), maPaperSize.Height() );
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Printer::ImplUpdateFontList()
+{
+ ImplUpdateFontData( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+Printer::Printer()
+{
+ ImplInitData();
+ SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( GetDefaultPrinterName(), NULL );
+ if ( pInfo )
+ {
+ ImplInit( pInfo );
+ if ( !IsDisplayPrinter() )
+ mbDefPrinter = TRUE;
+ }
+ else
+ ImplInitDisplay( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+Printer::Printer( const Window* pWindow )
+{
+ ImplInitData();
+ ImplInitDisplay( pWindow );
+}
+
+// -----------------------------------------------------------------------
+
+Printer::Printer( const JobSetup& rJobSetup ) :
+ maJobSetup( rJobSetup )
+{
+ ImplInitData();
+ SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rJobSetup.mpData->maPrinterName,
+ &rJobSetup.mpData->maDriver );
+ if ( pInfo )
+ {
+ ImplInit( pInfo );
+ SetJobSetup( rJobSetup );
+ }
+ else
+ {
+ ImplInitDisplay( NULL );
+ maJobSetup = JobSetup();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Printer::Printer( const QueueInfo& rQueueInfo )
+{
+ ImplInitData();
+ SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rQueueInfo.GetPrinterName(),
+ &rQueueInfo.GetDriver() );
+ if ( pInfo )
+ ImplInit( pInfo );
+ else
+ ImplInitDisplay( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+Printer::Printer( const XubString& rPrinterName )
+{
+ ImplInitData();
+ SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rPrinterName, NULL );
+ if ( pInfo )
+ ImplInit( pInfo );
+ else
+ ImplInitDisplay( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+Printer::~Printer()
+{
+ DBG_ASSERT( !IsPrinting(), "Printer::~Printer() - Job is printing" );
+ DBG_ASSERT( !IsJobActive(), "Printer::~Printer() - Job is active" );
+ DBG_ASSERT( !mpQPrinter, "Printer::~Printer() - QueuePrinter not destroyed" );
+ DBG_ASSERT( !mpQMtf, "Printer::~Printer() - QueueMetafile not destroyed" );
+
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+ if ( mpInfoPrinter )
+ ImplGetSVData()->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
+#else
+ if ( mpInfoPrinter )
+ {
+ if( mpGraphics )
+ mpGraphics->SetInterface( REF( NMSP_CLIENT::XRmOutputDevice )() );
+
+ ImplReleaseServerGraphics();
+
+ if ( mpGetDevFontList )
+ {
+ delete mpGetDevFontList;
+ mpGetDevFontList = NULL;
+ }
+ if ( mpGetDevSizeList )
+ {
+ delete mpGetDevSizeList;
+ mpGetDevSizeList = NULL;
+ }
+ delete mpGraphics, mpGraphics = NULL;
+ delete mpInfoPrinter, mpInfoPrinter = NULL;
+ }
+#endif
+ if ( mpDisplayDev )
+ delete mpDisplayDev;
+ else
+ {
+ // OutputDevice-Dtor versucht das gleiche, deshalb muss hier
+ // der FontEntry auch auf NULL gesetzt werden
+ if ( mpFontEntry )
+ {
+ mpFontCache->Release( mpFontEntry );
+ mpFontEntry = NULL;
+ }
+ if ( mpGetDevFontList )
+ {
+ delete mpGetDevFontList;
+ mpGetDevFontList = NULL;
+ }
+ if ( mpGetDevSizeList )
+ {
+ delete mpGetDevSizeList;
+ mpGetDevSizeList = NULL;
+ }
+ delete mpFontList;
+ delete mpFontCache;
+ }
+
+ // Printer aus der Liste eintragen
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ pSVData->maGDIData.mpFirstPrinter = mpNext;
+ if ( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ pSVData->maGDIData.mpLastPrinter = mpPrev;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Printer::GetCapabilities( USHORT nType ) const
+{
+ if ( IsDisplayPrinter() )
+ return FALSE;
+
+#ifndef REMOTE_APPSERVER
+ return mpInfoPrinter->GetCapabilities( maJobSetup.ImplGetConstData(), nType );
+#else
+ return mpInfoPrinter->GetCapabilities( nType );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::HasSupport( PrinterSupport eFeature, BOOL bInJob ) const
+{
+ switch ( eFeature )
+ {
+ case SUPPORT_SET_ORIENTATION:
+ return (BOOL)GetCapabilities( PRINTER_CAPABILITIES_SETORIENTATION );
+ case SUPPORT_SET_PAPERBIN:
+ return (BOOL)GetCapabilities( PRINTER_CAPABILITIES_SETPAPERBIN );
+ case SUPPORT_SET_PAPERSIZE:
+ return (BOOL)GetCapabilities( PRINTER_CAPABILITIES_SETPAPERSIZE );
+ case SUPPORT_SET_PAPER:
+ return (BOOL)GetCapabilities( PRINTER_CAPABILITIES_SETPAPER );
+ case SUPPORT_COPY:
+ return (GetCapabilities( PRINTER_CAPABILITIES_COPIES ) != 0);
+ case SUPPORT_COLLATECOPY:
+ return (GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES ) != 0);
+ case SUPPORT_SETUPDIALOG:
+ return (BOOL)GetCapabilities( PRINTER_CAPABILITIES_SUPPORTDIALOG );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::SetJobSetup( const JobSetup& rSetup )
+{
+ if ( IsDisplayPrinter() || mbInPrintPage )
+ return FALSE;
+
+ JobSetup aJobSetup = rSetup;
+
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+ if ( mpInfoPrinter->SetPrinterData( aJobSetup.ImplGetData() ) )
+ {
+ ImplUpdateJobSetupPaper( aJobSetup );
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ ImplUpdatePageData();
+ ImplUpdateFontList();
+ return TRUE;
+ }
+
+ return FALSE;
+#else
+ if ( mpInfoPrinter )
+ {
+ NMSP_CLIENT::RmJobSetup aRmJobSetup;
+
+ PRINTERSEQ_SET( aJobSetup, aRmJobSetup, NMSP_CLIENT::RmJobSetup );
+ if ( mpInfoPrinter->SetJobSetup( aRmJobSetup ) )
+ {
+ PRINTERSEQ_GET( aRmJobSetup, aJobSetup );
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ ImplUpdatePageData();
+ ImplUpdateFontList();
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+ return FALSE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef REMOTE_APPSERVER
+IMPL_LINK( Printer, UserSetupCompleted, ::com::sun::star::uno::Any*, pResult )
+{
+ ::vos::OGuard guard( Application::GetSolarMutex( ) );
+
+ if( pResult->hasValue() )
+ {
+ mbUserSetupResult = TRUE;
+
+ ::com::sun::star::portal::client::RmJobSetup aRmJobSetup;
+ *pResult >>= aRmJobSetup;
+ JobSetup aJobSetup;
+ PRNSEQ_GET( aRmJobSetup, aJobSetup );
+
+ ImplUpdateJobSetupPaper( aJobSetup );
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ ImplUpdatePageData();
+ ImplUpdateFontList();
+ }
+ else
+ mbUserSetupResult = FALSE;
+
+ mbUserSetupCompleted = TRUE;
+ return 0;
+}
+#endif
+
+BOOL Printer::Setup( Window* pWindow )
+{
+ if ( IsDisplayPrinter() )
+ return FALSE;
+
+ if ( IsJobActive() || IsPrinting() )
+ return FALSE;
+
+#ifndef REMOTE_APPSERVER
+ JobSetup aJobSetup = maJobSetup;
+ SalFrame* pFrame;
+ if ( !pWindow )
+ pFrame = ImplGetDefaultWindow()->ImplGetFrame();
+ else
+ pFrame = pWindow->ImplGetFrame();
+ ImplReleaseGraphics();
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->maAppData.mnModalMode++;
+ nImplSysDialog++;
+ BOOL bSetup = mpInfoPrinter->Setup( pFrame, aJobSetup.ImplGetData() );
+ pSVData->maAppData.mnModalMode--;
+ nImplSysDialog--;
+ if ( bSetup )
+ {
+ ImplUpdateJobSetupPaper( aJobSetup );
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ ImplUpdatePageData();
+ ImplUpdateFontList();
+ return TRUE;
+ }
+ return FALSE;
+#else
+ NMSP_CLIENT::RmJobSetup aRmJobSetup;
+ PRNSEQ_SET( aRmJobSetup, maJobSetup );
+ mpInfoPrinter->SetJobSetup( aRmJobSetup );
+ RmFrameWindow* pFrame;
+ if ( !pWindow )
+ pFrame = ImplGetDefaultWindow()->ImplGetFrame();
+ else
+ pFrame = pWindow->ImplGetFrame();
+ mbUserSetupCompleted = FALSE;
+ mpInfoPrinter->UserSetup( pFrame->GetFrameInterface(), pFrame->InsertUserEventLink( LINK( this, Printer, UserSetupCompleted ) ) );
+ while( ! mbUserSetupCompleted )
+ Application::Reschedule();
+ return mbUserSetupResult;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::SetPrinterProps( const Printer* pPrinter )
+{
+ if ( IsJobActive() || IsPrinting() )
+ return FALSE;
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ mbDefPrinter = pPrinter->mbDefPrinter;
+ maPrintFile = pPrinter->maPrintFile;
+ mbPrintFile = pPrinter->mbPrintFile;
+ mnCopyCount = pPrinter->mnCopyCount;
+ mbCollateCopy = pPrinter->mbCollateCopy;
+ mnPageQueueSize = pPrinter->mnPageQueueSize;
+
+ if ( pPrinter->IsDisplayPrinter() )
+ {
+ // Alten Printer zerstoeren
+ if ( !IsDisplayPrinter() )
+ {
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+ pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
+#else
+ if ( mpInfoPrinter )
+ {
+ if( mpGraphics )
+ mpGraphics->SetInterface( REF( NMSP_CLIENT::XRmOutputDevice )() );
+
+ ImplReleaseServerGraphics();
+ delete mpGraphics, mpGraphics = NULL;
+ delete mpInfoPrinter, mpInfoPrinter = NULL;
+ }
+#endif
+ if ( mpFontEntry )
+ {
+ mpFontCache->Release( mpFontEntry );
+ mpFontEntry = NULL;
+ }
+ if ( mpGetDevFontList )
+ {
+ delete mpGetDevFontList;
+ mpGetDevFontList = NULL;
+ }
+ if ( mpGetDevSizeList )
+ {
+ delete mpGetDevSizeList;
+ mpGetDevSizeList = NULL;
+ }
+ delete mpFontList;
+ delete mpFontCache;
+ mbInitFont = TRUE;
+ mbNewFont = TRUE;
+ mpInfoPrinter = NULL;
+ }
+
+ // Neuen Printer bauen
+ ImplInitDisplay( NULL );
+ return TRUE;
+ }
+
+ // Alten Printer zerstoeren?
+ if ( GetName() != pPrinter->GetName() )
+ {
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+#endif
+ if ( mpDisplayDev )
+ {
+ delete mpDisplayDev;
+ mpDisplayDev = NULL;
+ }
+ else
+ {
+#ifndef REMOTE_APPSERVER
+ pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
+#else
+ if ( mpInfoPrinter )
+ {
+ if( mpGraphics )
+ mpGraphics->SetInterface( REF( NMSP_CLIENT::XRmOutputDevice )() );
+
+ ImplReleaseServerGraphics();
+ delete mpGraphics, mpGraphics = NULL;
+ delete mpInfoPrinter, mpInfoPrinter = NULL;
+ }
+#endif
+
+ if ( mpFontEntry )
+ {
+ mpFontCache->Release( mpFontEntry );
+ mpFontEntry = NULL;
+ }
+ if ( mpGetDevFontList )
+ {
+ delete mpGetDevFontList;
+ mpGetDevFontList = NULL;
+ }
+ if ( mpGetDevSizeList )
+ {
+ delete mpGetDevSizeList;
+ mpGetDevSizeList = NULL;
+ }
+ delete mpFontList;
+ delete mpFontCache;
+ mbInitFont = TRUE;
+ mbNewFont = TRUE;
+ mpInfoPrinter = NULL;
+ }
+
+ // Neuen Printer bauen
+ XubString maDriver = pPrinter->GetDriverName();
+ SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( pPrinter->GetName(), &maDriver );
+ if ( pInfo )
+ {
+ ImplInit( pInfo );
+ SetJobSetup( pPrinter->GetJobSetup() );
+ }
+ else
+ ImplInitDisplay( NULL );
+ }
+ else
+ SetJobSetup( pPrinter->GetJobSetup() );
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::SetOrientation( Orientation eOrientation )
+{
+ if ( mbInPrintPage )
+ return FALSE;
+
+ if ( maJobSetup.ImplGetConstData()->meOrientation != eOrientation )
+ {
+ JobSetup aJobSetup = maJobSetup;
+ ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
+ pSetupData->meOrientation = eOrientation;
+
+ if ( IsDisplayPrinter() )
+ {
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ return TRUE;
+ }
+
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+ if ( mpInfoPrinter->SetData( SAL_JOBSET_ORIENTATION, pSetupData ) )
+ {
+ ImplUpdateJobSetupPaper( aJobSetup );
+#else
+ NMSP_CLIENT::RmJobSetup aRmJobSetup;
+ PRINTERSEQ_SET( aJobSetup, aRmJobSetup, NMSP_CLIENT::RmJobSetup );
+ if ( mpInfoPrinter->SetOrientation( (unsigned short)eOrientation, aRmJobSetup ) )
+ {
+ PRINTERSEQ_GET( aRmJobSetup, aJobSetup );
+#endif
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ ImplUpdatePageData();
+ ImplUpdateFontList();
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Orientation Printer::GetOrientation() const
+{
+ return maJobSetup.ImplGetConstData()->meOrientation;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::SetPaperBin( USHORT nPaperBin )
+{
+ if ( mbInPrintPage )
+ return FALSE;
+
+ if ( (maJobSetup.ImplGetConstData()->mnPaperBin != nPaperBin) &&
+ (nPaperBin < GetPaperBinCount()) )
+ {
+ JobSetup aJobSetup = maJobSetup;
+ ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
+ pSetupData->mnPaperBin = nPaperBin;
+
+ if ( IsDisplayPrinter() )
+ {
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ return TRUE;
+ }
+
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+ if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERBIN, pSetupData ) )
+ {
+ ImplUpdateJobSetupPaper( aJobSetup );
+#else
+ NMSP_CLIENT::RmJobSetup aRmJobSetup;
+ PRINTERSEQ_SET( aJobSetup, aRmJobSetup, NMSP_CLIENT::RmJobSetup );
+ if ( mpInfoPrinter->SetPaperBin( nPaperBin, aRmJobSetup ) )
+ {
+ PRINTERSEQ_GET( aRmJobSetup, aJobSetup );
+#endif
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ ImplUpdatePageData();
+ ImplUpdateFontList();
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Printer::GetPaperBin() const
+{
+ return maJobSetup.ImplGetConstData()->mnPaperBin;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::SetPaper( Paper ePaper )
+{
+ if ( mbInPrintPage )
+ return FALSE;
+
+ if ( maJobSetup.ImplGetConstData()->mePaperFormat != ePaper )
+ {
+ JobSetup aJobSetup = maJobSetup;
+ ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
+ pSetupData->mePaperFormat = ePaper;
+ if ( ePaper != PAPER_USER )
+ {
+ pSetupData->mnPaperWidth = ImplPaperFormats[((USHORT)ePaper)*2];
+ pSetupData->mnPaperHeight = ImplPaperFormats[((USHORT)ePaper)*2+1];
+ }
+
+ if ( IsDisplayPrinter() )
+ {
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ return TRUE;
+ }
+
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+ if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE, pSetupData ) )
+ {
+ ImplUpdateJobSetupPaper( aJobSetup );
+#else
+ NMSP_CLIENT::RmJobSetup aRmJobSetup;
+ PRINTERSEQ_SET( aJobSetup, aRmJobSetup, NMSP_CLIENT::RmJobSetup );
+ if ( mpInfoPrinter->SetPaper( (unsigned short)ePaper, aRmJobSetup ) )
+ {
+ PRINTERSEQ_GET( aRmJobSetup, aJobSetup );
+#endif
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ ImplUpdatePageData();
+ ImplUpdateFontList();
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::SetPaperSizeUser( const Size& rSize )
+{
+ if ( mbInPrintPage )
+ return FALSE;
+
+ MapMode aMap100thMM( MAP_100TH_MM );
+ Size aPixSize = LogicToPixel( rSize );
+ Size aPageSize = PixelToLogic( aPixSize, aMap100thMM );
+ if ( (maJobSetup.ImplGetConstData()->mePaperFormat != PAPER_USER) ||
+ (maJobSetup.ImplGetConstData()->mnPaperWidth != aPageSize.Width()) ||
+ (maJobSetup.ImplGetConstData()->mnPaperHeight != aPageSize.Height()) )
+ {
+ JobSetup aJobSetup = maJobSetup;
+ ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
+ pSetupData->mePaperFormat = PAPER_USER;
+ pSetupData->mnPaperWidth = aPageSize.Width();
+ pSetupData->mnPaperHeight = aPageSize.Height();
+
+ if ( IsDisplayPrinter() )
+ {
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ return TRUE;
+ }
+
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+ if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE, pSetupData ) )
+ {
+ ImplUpdateJobSetupPaper( aJobSetup );
+#else
+ NMSP_CLIENT::RmJobSetup aRmJobSetup;
+ PRINTERSEQ_SET( aJobSetup, aRmJobSetup, NMSP_CLIENT::RmJobSetup );
+ if ( mpInfoPrinter->SetPaperSizeUser( aPixSize.Width(), aPixSize.Height(), aRmJobSetup ) )
+ {
+ PRINTERSEQ_GET( aRmJobSetup, aJobSetup );
+#endif
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ ImplUpdatePageData();
+ ImplUpdateFontList();
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Paper Printer::GetPaper() const
+{
+ return maJobSetup.ImplGetConstData()->mePaperFormat;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Printer::GetPaperBinCount() const
+{
+ if ( IsDisplayPrinter() )
+ return 0;
+
+#ifndef REMOTE_APPSERVER
+ return (USHORT)mpInfoPrinter->GetPaperBinCount( maJobSetup.ImplGetConstData() );
+#else
+ if ( mpInfoPrinter )
+ return mpInfoPrinter->GetPaperBinCount();
+ else
+ return 0;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+XubString Printer::GetPaperBinName( USHORT nPaperBin ) const
+{
+ if ( IsDisplayPrinter() )
+ return ImplGetSVEmptyStr();
+
+#ifndef REMOTE_APPSERVER
+ if ( nPaperBin < GetPaperBinCount() )
+ return mpInfoPrinter->GetPaperBinName( maJobSetup.ImplGetConstData(), nPaperBin );
+ else
+ return ImplGetSVEmptyStr();
+#else
+ if ( mpInfoPrinter )
+ return (String)mpInfoPrinter->GetPaperBinName( nPaperBin );
+ else
+ return ImplGetSVEmptyStr();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::SetCopyCount( USHORT nCopy, BOOL bCollate )
+{
+ mnCopyCount = nCopy;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Printer::Error()
+{
+ maErrorHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Printer::StartPrint()
+{
+ maStartPrintHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Printer::EndPrint()
+{
+ maEndPrintHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Printer::PrintPage()
+{
+ maPrintPageHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+#ifndef REMOTE_APPSERVER
+
+ULONG ImplSalPrinterErrorCodeToVCL( ULONG nError )
+{
+ ULONG nVCLError;
+ switch ( nError )
+ {
+ case 0:
+ nVCLError = PRINTER_OK;
+ break;
+ case SAL_PRINTER_ERROR_ABORT:
+ nVCLError = PRINTER_ABORT;
+ break;
+ default:
+ nVCLError = PRINTER_GENERALERROR;
+ break;
+ }
+
+ return nVCLError;
+}
+
+// -----------------------------------------------------------------------
+
+void Printer::ImplEndPrint()
+{
+ mbPrinting = FALSE;
+ mnCurPrintPage = 0;
+ maJobName.Erase();
+ mpQPrinter->Destroy();
+ mpQPrinter = NULL;
+ EndPrint();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Printer, ImplDestroyPrinterAsync, void*, pSalPrinter )
+{
+ SalPrinter* pPrinter = (SalPrinter*)pSalPrinter;
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->mpDefInst->DestroyPrinter( pPrinter );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+#else
+
+// -----------------------------------------------------------------------
+
+static void ImplDeletePrintSpooler( PrintSpooler* pPrintSpooler )
+{
+ if( pPrintSpooler != 0 )
+ {
+ pPrintSpooler->mxPrintSpooler = REF( NMSP_CLIENT::XRmPrintSpooler )();
+ }
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::StartJob( const XubString& rJobName )
+{
+ mnError = PRINTER_OK;
+
+ if ( IsDisplayPrinter() )
+ return FALSE;
+
+ if ( IsJobActive() || IsPrinting() )
+ return FALSE;
+
+#ifndef REMOTE_APPSERVER
+ ULONG nCopies = mnCopyCount;
+ BOOL bCollateCopy = mbCollateCopy;
+ BOOL bUserCopy = FALSE;
+ if ( IsQueuePrinter() )
+ {
+ if ( ((ImplQPrinter*)this)->IsUserCopy() )
+ {
+ nCopies = 1;
+ bCollateCopy = FALSE;
+ }
+ }
+ else if ( nCopies > 1 )
+ {
+ ULONG nDevCopy;
+ if ( bCollateCopy )
+ nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES );
+ else
+ nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COPIES );
+ // Muessen Kopien selber gemacht werden?
+ if ( nCopies > nDevCopy )
+ {
+ bUserCopy = TRUE;
+ nCopies = 1;
+ bCollateCopy = FALSE;
+ if ( !mnPageQueueSize )
+ mnPageQueueSize = 1;
+ }
+ }
+ else
+ bCollateCopy = FALSE;
+
+ if ( !mnPageQueueSize )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter );
+
+ if ( !mpPrinter )
+ return FALSE;
+
+ XubString* pPrintFile;
+ if ( mbPrintFile )
+ pPrintFile = &maPrintFile;
+ else
+ pPrintFile = NULL;
+
+ if ( !mpPrinter->StartJob( pPrintFile, rJobName, Application::GetDisplayName(),
+ nCopies, bCollateCopy,
+ maJobSetup.ImplGetConstData() ) )
+ {
+ mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() );
+ if ( !mnError )
+ mnError = PRINTER_GENERALERROR;
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->mpDefInst->DestroyPrinter( mpPrinter );
+ mpPrinter = NULL;
+ return FALSE;
+ }
+
+ mbNewJobSetup = FALSE;
+ maJobName = rJobName;
+ mnCurPage = 1;
+ mnCurPrintPage = 1;
+ mbJobActive = TRUE;
+ mbPrinting = TRUE;
+ StartPrint();
+ }
+ else
+ {
+ mpQPrinter = new ImplQPrinter( this );
+ mpQPrinter->SetUserCopy( bUserCopy );
+ if ( mpQPrinter->StartJob( rJobName ) )
+ {
+ mbNewJobSetup = FALSE;
+ maJobName = rJobName;
+ mnCurPage = 1;
+ mbJobActive = TRUE;
+ mbPrinting = TRUE;
+ StartPrint();
+ mpQPrinter->StartQueuePrint();
+ }
+ else
+ {
+ mnError = mpQPrinter->GetErrorCode();
+ mpQPrinter->Destroy();
+ mpQPrinter = NULL;
+ return FALSE;
+ }
+ }
+#else
+ BOOL bResult = FALSE;
+ ImplSVData* pSVData = ImplGetSVData();
+
+ String aServerName( maPrinterName.GetToken( 1, '@' ) );
+
+ // build a new connection if not client
+ Reference< ::com::sun::star::lang::XMultiServiceFactory > xServerFactory;
+ Reference< ::com::sun::star::connection::XConnection > xConnection;
+ Reference< ::com::sun::star::bridge::XBridgeFactory > xBridgeFactory;
+
+ if( ! aServerName.EqualsAscii( RVP_CLIENT_SERVER_NAME ) )
+ pSVData->mpRemotePrinterList->CreateNewPrinterConnection( maPrinterName.GetToken( 1, '@' ), xServerFactory, xConnection, xBridgeFactory );
+ else
+ xServerFactory = pSVData->mxClientFactory;
+ if( xServerFactory.is() )
+ {
+ REF( NMSP_CLIENT::XRmSpoolLauncher ) xLauncher( xServerFactory->createInstance( ::rtl::OUString::createFromAscii( "OfficeSpoolLauncher.stardiv.de" ) ), NMSP_UNO::UNO_QUERY );
+ if( xLauncher.is() &&
+ xLauncher->LaunchSpooler( pSVData->mpUserInfo->sName,
+ pSVData->mpUserInfo->sPassword ) )
+ {
+ if( xBridgeFactory.is() ) // else this a the client connection
+ {
+ // get objects from transferred sospool connection
+ xServerFactory = Reference< ::com::sun::star::lang::XMultiServiceFactory >();
+ Reference< ::com::sun::star::bridge::XBridge >
+ xBridge( xBridgeFactory->createBridge( ::rtl::OUString(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "iiop" ) ), xConnection, Reference< ::com::sun::star::bridge::XInstanceProvider >() ) );
+ xServerFactory = Reference< ::com::sun::star::lang::XMultiServiceFactory >( xBridge->getInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SpoolMultiServiceFactory.sprintd.daemons.stardiv.de" ) ) ), UNO_QUERY );
+ }
+
+ mpPrinter = new PrintSpooler();
+ mpPrinter->mxPrintSpooler = REF( NMSP_CLIENT::XRmPrintSpooler )( xServerFactory->createInstance( ::rtl::OUString::createFromAscii( "OfficePrintSpooler.stardiv.de" ) ), NMSP_UNO::UNO_QUERY );
+ if( mpPrinter->mxPrintSpooler.is() )
+ {
+ NMSP_CLIENT::RmJobSetup aRmJobSetup;
+ PRNSEQ_SET( aRmJobSetup, maJobSetup );
+ mpPrinter->mxPrintSpooler->Create( aRmJobSetup );
+ bResult = mpPrinter->mxPrintSpooler->StartJob( mnCopyCount, mbCollateCopy, rJobName, maPrintFile, mbPrintFile );
+ }
+ }
+
+ if ( bResult )
+ {
+ mbNewJobSetup = FALSE;
+ maJobName = rJobName;
+ mnCurPage = 1;
+ mnCurPrintPage = 1;
+ mbJobActive = TRUE;
+ mbPrinting = TRUE;
+ }
+ else if ( mpPrinter && mpPrinter->mxPrintSpooler.is() )
+ {
+ ImplDeletePrintSpooler( mpPrinter );
+ mpPrinter = NULL;
+ }
+ }
+
+ if ( !bResult )
+ mnError = PRINTER_GENERALERROR;
+
+ return bResult;
+#endif
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::EndJob()
+{
+ if ( !IsJobActive() )
+ return FALSE;
+
+ DBG_ASSERT( !mbInPrintPage, "Printer::EndJob() - StartPage() without EndPage() called" );
+
+ mbJobActive = FALSE;
+
+#ifndef REMOTE_APPSERVER
+ if ( mpPrinter || mpQPrinter )
+ {
+ ImplReleaseGraphics();
+
+ mnCurPage = 0;
+
+ if ( mpPrinter )
+ {
+ mbPrinting = FALSE;
+ mnCurPrintPage = 0;
+ maJobName.Erase();
+
+ mbDevOutput = FALSE;
+ mpPrinter->EndJob();
+ // Hier den Drucker nicht asyncron zerstoeren, da es
+ // W95 nicht verkraftet, wenn gleichzeitig gedruckt wird
+ // und ein Druckerobjekt zerstoert wird
+ ImplGetSVData()->mpDefInst->DestroyPrinter( mpPrinter );
+ mpPrinter = NULL;
+ EndPrint();
+ }
+ else
+ mpQPrinter->EndQueuePrint();
+
+ return TRUE;
+ }
+#else
+ if ( mpPrinter )
+ {
+ mpPrinter->mxPrintSpooler->EndJob();
+ mbPrinting = FALSE;
+ mnCurPage = 0;
+ mnCurPrintPage = 0;
+ maJobName.Erase();
+ EndPrint();
+
+ ImplDeletePrintSpooler( mpPrinter );
+ mpPrinter = NULL;
+
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::AbortJob()
+{
+ // Wenn wir einen Queue-Printer haben, kann man diesen noch mit
+ // AbortJob() abbrechen, solange dieser noch am Drucken ist
+ if ( !IsJobActive() && !IsPrinting() )
+ return FALSE;
+
+ mbJobActive = FALSE;
+ mbInPrintPage = FALSE;
+ mpJobGraphics = NULL;
+
+#ifndef REMOTE_APPSERVER
+ if ( mpPrinter || mpQPrinter )
+ {
+ mbPrinting = FALSE;
+ mnCurPage = 0;
+ mnCurPrintPage = 0;
+ maJobName.Erase();
+
+ if ( mpPrinter )
+ {
+ ImplReleaseGraphics();
+ mbDevOutput = FALSE;
+ mpPrinter->AbortJob();
+ Application::PostUserEvent( LINK( this, Printer, ImplDestroyPrinterAsync ), mpPrinter );
+ mpPrinter = NULL;
+ EndPrint();
+ }
+ else
+ {
+ mpQPrinter->AbortQueuePrint();
+ mpQPrinter->Destroy();
+ mpQPrinter = NULL;
+ if ( mpQMtf )
+ {
+ mpQMtf->Clear();
+ delete mpQMtf;
+ mpQMtf = NULL;
+ }
+ EndPrint();
+ }
+
+ return TRUE;
+ }
+#else
+ if ( mpPrinter )
+ {
+ mpPrinter->mxPrintSpooler->AbortJob();
+ if ( mpQMtf )
+ {
+ mpQMtf->Clear();
+ delete mpQMtf;
+ mpQMtf = NULL;
+ }
+
+ mbPrinting = FALSE;
+ mnCurPage = 0;
+ mnCurPrintPage = 0;
+ maJobName.Erase();
+ ImplDeletePrintSpooler( mpPrinter );
+ mpPrinter = NULL;
+ EndPrint();
+
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::StartPage()
+{
+ if ( !IsJobActive() )
+ return FALSE;
+
+#ifndef REMOTE_APPSERVER
+ if ( mpPrinter || mpQPrinter )
+ {
+ if ( mpPrinter )
+ {
+ SalGraphics* pGraphics = mpPrinter->StartPage( maJobSetup.ImplGetConstData(), mbNewJobSetup );
+ if ( pGraphics )
+ {
+ ImplReleaseGraphics();
+ mpJobGraphics = pGraphics;
+ }
+ mbDevOutput = TRUE;
+ }
+ else
+ {
+ ImplGetGraphics();
+ mpJobGraphics = mpGraphics;
+ }
+
+ // PrintJob not aborted ???
+ if ( IsJobActive() )
+ {
+ mbInPrintPage = TRUE;
+ mnCurPage++;
+ if ( mpQPrinter )
+ {
+ mpQMtf = new GDIMetaFile;
+ mpQMtf->Record( this );
+ mpQMtf->SaveStatus();
+ }
+ else
+ {
+ mnCurPrintPage++;
+ PrintPage();
+ }
+ }
+
+ return TRUE;
+ }
+#else
+ if ( mpPrinter )
+ {
+ mpQMtf = new GDIMetaFile;
+ mpQMtf->Record( this );
+ mpQMtf->SaveStatus();
+
+ mbInPrintPage = TRUE;
+ mnCurPage++;
+ mnCurPrintPage++;
+ PrintPage();
+
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::EndPage()
+{
+ if ( !IsJobActive() )
+ return FALSE;
+
+ mbInPrintPage = FALSE;
+
+#ifndef REMOTE_APPSERVER
+ if ( mpPrinter || mpQPrinter )
+ {
+ if ( mpPrinter )
+ {
+ mpPrinter->EndPage();
+ ImplReleaseGraphics();
+ mbDevOutput = FALSE;
+ }
+ else if ( mpQPrinter )
+ {
+ // Eigentuemeruebergang an QPrinter
+ mpQMtf->Stop();
+ mpQMtf->WindStart();
+ GDIMetaFile* pPage = mpQMtf;
+ mpQMtf = NULL;
+ mpQPrinter->AddQueuePage( pPage, mnCurPage, mbNewJobSetup );
+ }
+
+ mpJobGraphics = NULL;
+ mbNewJobSetup = FALSE;
+
+ return TRUE;
+ }
+#else
+ if ( mpPrinter && mpQMtf )
+ {
+ mpQMtf->Stop();
+ mpQMtf->WindStart();
+
+ PrinterPage aPage( mpQMtf, mbNewJobSetup, GetJobSetup() );
+ NMSP_CLIENT::RmPrinterPage aRmPage;
+ PRINTERSEQ_SET( aPage, aRmPage, NMSP_CLIENT::RmPrinterPage );
+ mpPrinter->mxPrintSpooler->SpoolPage( aRmPage );
+ mpQMtf = NULL;
+ mbNewJobSetup = FALSE;
+
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
diff --git a/vcl/source/gdi/print2.cxx b/vcl/source/gdi/print2.cxx
new file mode 100644
index 000000000000..9e301b906012
--- /dev/null
+++ b/vcl/source/gdi/print2.cxx
@@ -0,0 +1,543 @@
+/*************************************************************************
+ *
+ * $RCSfile: print2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_PRINT_CXX
+#define _SPOOLPRINTER_EXT
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_METAACT_HXX
+#include <metaact.hxx>
+#endif
+#ifndef _SV_GDIMTF_HXX
+#include <gdimtf.hxx>
+#endif
+#ifndef _SV_PRINT_H
+#include <print.h>
+#endif
+#ifndef _SV_PRINT_HXX
+#include <print.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define MAX_BANDWIDTH 1000000
+
+// -----------
+// - statics -
+// -----------
+
+static USHORT aSpecialPrintActions[] =
+{
+ META_TRANSPARENT_ACTION,
+ META_FLOATTRANSPARENT_ACTION
+};
+
+// -----------------
+// - ImplCheckRect -
+// -----------------
+
+struct ImplCheckRect
+{
+ Rectangle* mpRect;
+ MetaAction* mpAct;
+ ImplCheckRect* mpNext;
+ BOOL mbSpecialOutput;
+
+ ImplCheckRect() { }
+ ~ImplCheckRect() { delete mpRect; }
+ void ImplCreate( MetaAction* pAct, OutputDevice* pOut, BOOL bSpecial );
+ BOOL Intersects( const ImplCheckRect& rRect )
+ {
+ return( mpRect && rRect.mpRect ) ? mpRect->IsOver( *rRect.mpRect ) : FALSE;
+ }
+};
+
+// -----------------------------------------------------------------------------
+
+void ImplCheckRect::ImplCreate( MetaAction* pAct, OutputDevice* pOut, BOOL bSpecial )
+{
+ mpAct = pAct;
+ mpNext = NULL;
+
+ switch( mpAct->GetType() )
+ {
+ case( META_PIXEL_ACTION ):
+ mpRect = new Rectangle( ( (MetaPixelAction*) mpAct )->GetPoint(), Size( 1, 1 ) );
+ break;
+
+ case( META_POINT_ACTION ):
+ mpRect = new Rectangle( ( (MetaPointAction*) mpAct )->GetPoint(), Size( 1, 1 ) );
+ break;
+
+ case( META_LINE_ACTION ):
+ {
+ MetaLineAction* pA = (MetaLineAction*) mpAct;
+ mpRect = new Rectangle( pA->GetStartPoint(), pA->GetEndPoint() );
+ }
+ break;
+
+ case( META_RECT_ACTION ):
+ mpRect = new Rectangle( ( (MetaRectAction*) mpAct )->GetRect() );
+ break;
+
+ case( META_ROUNDRECT_ACTION ):
+ {
+ MetaRoundRectAction* pA = (MetaRoundRectAction*) mpAct;
+ mpRect = new Rectangle( Polygon( pA->GetRect(),
+ pA->GetHorzRound(),
+ pA->GetVertRound() ).GetBoundRect() );
+ }
+ break;
+
+ case( META_ELLIPSE_ACTION ):
+ {
+ MetaEllipseAction* pA = (MetaEllipseAction*) mpAct;
+ const Rectangle& rRect = pA->GetRect();
+ mpRect = new Rectangle( Polygon( rRect.Center(),
+ rRect.GetWidth() >> 1,
+ rRect.GetHeight() >> 1 ).GetBoundRect() );
+ }
+ break;
+
+ case( META_ARC_ACTION ):
+ {
+ MetaArcAction* pA = (MetaArcAction*) mpAct;
+ mpRect = new Rectangle( Polygon( pA->GetRect(),
+ pA->GetStartPoint(),
+ pA->GetEndPoint(), POLY_ARC ).GetBoundRect() );
+ }
+ break;
+
+ case( META_PIE_ACTION ):
+ {
+ MetaPieAction* pA = (MetaPieAction*) mpAct;
+ mpRect = new Rectangle( Polygon( pA->GetRect(),
+ pA->GetStartPoint(),
+ pA->GetEndPoint(), POLY_PIE ).GetBoundRect() );
+ }
+ break;
+
+ case( META_CHORD_ACTION ):
+ {
+ MetaChordAction* pA = (MetaChordAction*) mpAct;
+ mpRect = new Rectangle( Polygon( pA->GetRect(),
+ pA->GetStartPoint(),
+ pA->GetEndPoint(), POLY_CHORD ).GetBoundRect() );
+ }
+ break;
+
+ case( META_POLYLINE_ACTION ):
+ {
+ MetaPolyLineAction* pA = (MetaPolyLineAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPolygon().GetBoundRect() );
+ }
+ break;
+
+ case( META_POLYGON_ACTION ):
+ {
+ MetaPolygonAction* pA = (MetaPolygonAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPolygon().GetBoundRect() );
+ }
+ break;
+
+ case( META_POLYPOLYGON_ACTION ):
+ {
+ MetaPolyPolygonAction* pA = (MetaPolyPolygonAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPolyPolygon().GetBoundRect() );
+ }
+ break;
+
+ case( META_BMP_ACTION ):
+ {
+ MetaBmpAction* pA = (MetaBmpAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPoint(), pOut->PixelToLogic( pA->GetBitmap().GetSizePixel() ) );
+ }
+ break;
+
+ case( META_BMPSCALE_ACTION ):
+ {
+ MetaBmpScaleAction* pA = (MetaBmpScaleAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPoint(), pA->GetSize() );
+ }
+ break;
+
+ case( META_BMPSCALEPART_ACTION ):
+ {
+ MetaBmpScalePartAction* pA = (MetaBmpScalePartAction*) mpAct;
+ mpRect = new Rectangle( pA->GetDestPoint(), pA->GetDestSize() );
+ }
+ break;
+
+ case( META_BMPEX_ACTION ):
+ {
+ MetaBmpExAction* pA = (MetaBmpExAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPoint(), pOut->PixelToLogic( pA->GetBitmapEx().GetSizePixel() ) );
+ }
+ break;
+
+ case( META_BMPEXSCALE_ACTION ):
+ {
+ MetaBmpExScaleAction* pA = (MetaBmpExScaleAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPoint(), pA->GetSize() );
+ }
+ break;
+
+ case( META_BMPEXSCALEPART_ACTION ):
+ {
+ MetaBmpExScalePartAction* pA = (MetaBmpExScalePartAction*) mpAct;
+ mpRect = new Rectangle( pA->GetDestPoint(), pA->GetDestSize() );
+ }
+ break;
+
+ case( META_MASK_ACTION ):
+ {
+ MetaMaskAction* pA = (MetaMaskAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPoint(), pOut->PixelToLogic( pA->GetBitmap().GetSizePixel() ) );
+ }
+ break;
+
+ case( META_MASKSCALE_ACTION ):
+ {
+ MetaMaskScaleAction* pA = (MetaMaskScaleAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPoint(), pA->GetSize() );
+ }
+ break;
+
+ case( META_MASKSCALEPART_ACTION ):
+ {
+ MetaMaskScalePartAction* pA = (MetaMaskScalePartAction*) mpAct;
+ mpRect = new Rectangle( pA->GetDestPoint(), pA->GetDestSize() );
+ }
+ break;
+
+ case( META_GRADIENT_ACTION ):
+ mpRect = new Rectangle( ( (MetaGradientAction*) mpAct )->GetRect() );
+ break;
+
+ case( META_HATCH_ACTION ):
+ mpRect = new Rectangle( ( (MetaHatchAction*) mpAct )->GetPolyPolygon().GetBoundRect() );
+ break;
+
+ case( META_WALLPAPER_ACTION ):
+ mpRect = new Rectangle( ( (MetaWallpaperAction*) mpAct )->GetRect() );
+ break;
+
+ case( META_TRANSPARENT_ACTION ):
+ mpRect = new Rectangle( ( (MetaTransparentAction*) mpAct )->GetPolyPolygon().GetBoundRect() );
+ break;
+
+ case( META_FLOATTRANSPARENT_ACTION ):
+ {
+ MetaFloatTransparentAction* pA = (MetaFloatTransparentAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPoint(), pA->GetSize() );
+ }
+ break;
+
+ case( META_EPS_ACTION ):
+ {
+ MetaEPSAction* pA = (MetaEPSAction*) mpAct;
+ mpRect = new Rectangle( pA->GetPoint(), pA->GetSize() );
+ }
+ break;
+
+ case( META_TEXT_ACTION ):
+ {
+ MetaTextAction* pA = (MetaTextAction*) mpAct;
+ const Point aPt( pOut->LogicToPixel( pA->GetPoint() ) );
+ const XubString aString( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+ mpRect = new Rectangle( pOut->PixelToLogic( pOut->ImplGetTextBoundRect( aPt.X(), aPt.Y(), aString.GetBuffer(), aString.Len(), NULL ) ) );
+ }
+ break;
+
+ case( META_TEXTARRAY_ACTION ):
+ {
+ MetaTextArrayAction* pA = (MetaTextArrayAction*) mpAct;
+ const Point aPt( pOut->LogicToPixel( pA->GetPoint() ) );
+ const XubString aString( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+ mpRect = new Rectangle( pOut->PixelToLogic( pOut->ImplGetTextBoundRect( aPt.X(), aPt.Y(), aString.GetBuffer(), aString.Len(), pA->GetDXArray() ) ) );
+ }
+ break;
+
+ case( META_TEXTRECT_ACTION ):
+ {
+ MetaTextRectAction* pA = (MetaTextRectAction*) mpAct;
+ mpRect = new Rectangle( pA->GetRect() );
+ }
+ break;
+
+ case( META_STRETCHTEXT_ACTION ):
+ case( META_TEXTLINE_ACTION ):
+ mpRect = NULL;
+ // !!! DBG_ERROR( "Missing" );
+ break;
+
+ default:
+ mpRect = NULL;
+ break;
+ }
+
+ if( mpRect )
+ {
+ *mpRect = pOut->LogicToPixel( *mpRect );
+ mbSpecialOutput = bSpecial;
+ }
+ else
+ mbSpecialOutput = FALSE;
+}
+
+// -----------
+// - Printer -
+// -----------
+
+void Printer::GetPreparedMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutMtf, ULONG nFlags )
+{
+ const ULONG nSpecialCount = sizeof( aSpecialPrintActions ) / sizeof( aSpecialPrintActions[ 0 ] );
+ MetaAction* pAct;
+ ULONG i, j;
+ BOOL bSpecial = FALSE;
+
+ rOutMtf.Clear();
+
+ // look, if we've got special actions
+ for( pAct = ( (GDIMetaFile&) rInMtf ).FirstAction(); pAct && !bSpecial; pAct = ( (GDIMetaFile&) rInMtf ).NextAction() )
+ for( i = 0; i < nSpecialCount; i++ )
+ if( pAct->GetType() == aSpecialPrintActions[ i ] )
+ bSpecial = TRUE;
+
+ // separate actions which are special actions or which are affected by special actions
+ if( bSpecial )
+ {
+ Rectangle aBoundPixel;
+ const ULONG nCount = rInMtf.GetActionCount();
+ VirtualDevice aPaintVDev;
+ ImplCheckRect* pRects = new ImplCheckRect[ nCount ];
+ ImplCheckRect* pIListFirst = NULL;
+ ImplCheckRect* pIListPrev = NULL;
+ ImplCheckRect* pIListAct = NULL;
+ ImplCheckRect* pOListFirst = NULL;
+ ImplCheckRect* pOListLast = NULL;
+ ImplCheckRect* pOListAct = NULL;
+ ImplCheckRect* pO;
+
+ aPaintVDev.mnDPIX = mnDPIX;
+ aPaintVDev.mnDPIY = mnDPIY;
+ aPaintVDev.mbOutput = FALSE;
+
+ // create list of special action rects
+ for( i = 0, pO = pRects, pAct = ( (GDIMetaFile&) rInMtf ).FirstAction(); pAct;
+ pAct = ( (GDIMetaFile&) rInMtf ).NextAction(), i++, pO++ )
+ {
+ for( j = 0, bSpecial = FALSE; j < nSpecialCount && !bSpecial; j++ )
+ if( pAct->GetType() == aSpecialPrintActions[ j ] )
+ bSpecial = TRUE;
+
+ // execute action to get correct MapMode's etc.
+ pAct->Execute( &aPaintVDev );
+
+ // create (bounding) rect object
+ pO->ImplCreate( pAct, &aPaintVDev, bSpecial );
+
+ // add object to one of the lists
+ if( pO->mbSpecialOutput )
+ {
+ if( !pOListFirst )
+ pOListFirst = pOListAct = pOListLast = pO;
+ else
+ pOListAct = pOListAct->mpNext = pOListLast = pO;
+ }
+ else
+ {
+ if( !pIListFirst )
+ pIListFirst = pIListAct = pO;
+ else
+ pIListAct = pIListAct->mpNext = pO;
+ }
+ }
+
+ // find all intersections and create list of (bitmap)
+ for( pO = pOListFirst; pO; pO = pO->mpNext )
+ {
+ pIListPrev = NULL, pIListAct = pIListFirst;
+
+ while( pIListAct )
+ {
+ // move act object from in list to out list?
+ if( pIListAct->Intersects( *pO ) )
+ {
+ // mark it as special object
+ pIListAct->mbSpecialOutput = TRUE;
+
+ if( pIListPrev )
+ pIListPrev->mpNext = pIListAct->mpNext;
+ else
+ pIListFirst = pIListAct->mpNext;
+
+ pOListLast = pOListLast->mpNext = pIListAct;
+ }
+ else
+ pIListPrev = pIListAct;
+
+ pIListAct = pIListAct->mpNext;
+ pOListLast->mpNext = NULL;
+ }
+ }
+
+ // calculate bounding rectangle of special actions
+ for( pO = pOListFirst; pO; pO = pO->mpNext )
+ aBoundPixel.Union( *pO->mpRect );
+
+ const Size aSzPix( aBoundPixel.GetSize() );
+
+ // create new bitmap action first
+ if( aSzPix.Width() && aSzPix.Height() )
+ {
+ Point aDstPtPix( aBoundPixel.TopLeft() );
+ Size aDstSzPix( aSzPix.Width(), Max( MAX_BANDWIDTH / aSzPix.Width(), 2L ) );
+ const long nLastY = aDstPtPix.Y() + aSzPix.Height() - 1L;
+ VirtualDevice aMapVDev;
+
+ rOutMtf.AddAction( new MetaPushAction( PUSH_MAPMODE ) );
+ rOutMtf.AddAction( new MetaMapModeAction() );
+
+ aPaintVDev.mbOutput = TRUE;
+ aMapVDev.mbOutput = FALSE;
+
+ while( aDstPtPix.Y() <= nLastY )
+ {
+ if( ( aDstPtPix.Y() + aDstSzPix.Height() - 1L ) > nLastY )
+ aDstSzPix.Height() = nLastY - aDstPtPix.Y() + 1L;
+
+ if( aPaintVDev.SetOutputSizePixel( aDstSzPix ) )
+ {
+ aPaintVDev.Push();
+ aMapVDev.Push();
+
+ aMapVDev.mnDPIX = aPaintVDev.mnDPIX = mnDPIX;
+ aMapVDev.mnDPIY = aPaintVDev.mnDPIY = mnDPIY;
+
+ for( i = 0, pO = pRects; i < nCount; i++, pO++ )
+ {
+ MetaAction* pAction = pO->mpAct;
+ const USHORT nType = pAction->GetType();
+
+ if( META_MAPMODE_ACTION == nType )
+ {
+ pAction->Execute( &aMapVDev );
+
+ MapMode aMtfMap( aMapVDev.GetMapMode() );
+ const Point aNewOrg( aMapVDev.PixelToLogic( aDstPtPix ) );
+
+ aMtfMap.SetOrigin( Point( -aNewOrg.X(), -aNewOrg.Y() ) );
+ aPaintVDev.SetMapMode( aMtfMap );
+ }
+ else if( ( META_PUSH_ACTION == nType ) || ( META_POP_ACTION ) == nType )
+ {
+ pAction->Execute( &aMapVDev );
+ pAction->Execute( &aPaintVDev );
+ }
+ else
+ pAction->Execute( &aPaintVDev );
+
+ if( !( i % 4 ) )
+ Application::Reschedule();
+ }
+
+ aPaintVDev.mbMap = FALSE;
+ Bitmap aBandBmp( aPaintVDev.GetBitmap( Point(), aDstSzPix ) );
+#ifdef DEBUG
+ aBandBmp.Invert();
+#endif
+ rOutMtf.AddAction( new MetaBmpScaleAction( aDstPtPix, aDstSzPix, aBandBmp ) );
+ aPaintVDev.mbMap = TRUE;
+
+ aMapVDev.Pop();
+ aPaintVDev.Pop();
+ }
+
+ // overlapping bands to avoid missing lines (e.g. PostScript)
+ aDstPtPix.Y() += aDstSzPix.Height();
+ }
+
+ rOutMtf.AddAction( new MetaPopAction() );
+ }
+
+ // add normal actions
+ for( i = 0, pO = pRects; i < nCount; i++, pO++ )
+ if( !pO->mbSpecialOutput )
+ rOutMtf.AddAction( ( pO->mpAct->Duplicate(), pO->mpAct ) );
+
+ rOutMtf.SetPrefMapMode( rInMtf.GetPrefMapMode() );
+ rOutMtf.SetPrefSize( rInMtf.GetPrefSize() );
+ delete[] pRects;
+ }
+ else
+ rOutMtf = rInMtf;
+}
diff --git a/vcl/source/gdi/regband.cxx b/vcl/source/gdi/regband.cxx
new file mode 100644
index 000000000000..51a0a366727b
--- /dev/null
+++ b/vcl/source/gdi/regband.cxx
@@ -0,0 +1,785 @@
+/*************************************************************************
+ *
+ * $RCSfile: regband.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_REGBAND_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_REGBAND_HXX
+#include <regband.hxx>
+#endif
+
+// =======================================================================
+//
+// ImplRegionBand
+//
+// Jedes Band enthaelt die zwischen der enthaltenen Ober- und Untergrenze
+// enthaltenen Rechtecke. Bei den Operationen Union, Intersect, XOr und
+// Exclude werden immer Rechtecke der gleichen Hoehe ausgewerte; die
+// Grenzen der Baender sind immer so zu waehlen, dasz dies moeglich ist.
+//
+// Die Rechtecke in den Baendern werden nach Moeglichkeit zusammengefaszt.
+//
+// Bei der Umwandlung von Polygonen werden alle Punkte des Polygons
+// in die einzelnen Baender eingetragen (sie stehen fuer jedes Band als
+// Punkte in einer Liste). Nach dem Eintragen der Punkte werden diese
+// in Rechtecke umgewandelt und die Liste der Punkte geloescht.
+//
+// -----------------------------------------------------------------------
+
+ImplRegionBand::ImplRegionBand( long nTop, long nBottom )
+{
+ // save boundaries
+ mnYTop = nTop;
+ mnYBottom = nBottom;
+
+ // initialize lists
+ mpNextBand = NULL;
+ mpPrevBand = NULL;
+ mpFirstSep = NULL;
+ mpFirstBandPoint = NULL;
+ mbTouched = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplRegionBand::ImplRegionBand( const ImplRegionBand& rRegionBand )
+{
+ // copy boundaries
+ mnYTop = rRegionBand.mnYTop;
+ mnYBottom = rRegionBand.mnYBottom;
+ mbTouched = rRegionBand.mbTouched;
+
+ // initialisation
+ mpNextBand = NULL;
+ mpPrevBand = NULL;
+ mpFirstSep = NULL;
+ mpFirstBandPoint = NULL;
+
+ // copy all elements of the list with separations
+ ImplRegionBandSep* pNewSep;
+ ImplRegionBandSep* pPrevSep;
+ ImplRegionBandSep* pSep = rRegionBand.mpFirstSep;
+ while ( pSep )
+ {
+ // create new and copy data
+ pNewSep = new ImplRegionBandSep;
+ pNewSep->mnXLeft = pSep->mnXLeft;
+ pNewSep->mnXRight = pSep->mnXRight;
+ pNewSep->mbRemoved = pSep->mbRemoved;
+ pNewSep->mpNextSep = NULL;
+ if ( pSep == rRegionBand.mpFirstSep )
+ mpFirstSep = pNewSep;
+ else
+ pPrevSep->mpNextSep = pNewSep;
+
+ pPrevSep = pNewSep;
+ pSep = pSep->mpNextSep;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ImplRegionBand::~ImplRegionBand()
+{
+ DBG_ASSERT( mpFirstBandPoint == NULL, "ImplRegionBand::~ImplRegionBand -> pointlist not empty" );
+
+ // delete elements of the list
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ ImplRegionBandSep* pTempSep = pSep->mpNextSep;
+ delete pSep;
+ pSep = pTempSep;
+ }
+
+ // delete elements of the list
+ ImplRegionBandPoint* pPoint = mpFirstBandPoint;
+ while ( pPoint )
+ {
+ ImplRegionBandPoint* pTempPoint = pPoint->mpNextBandPoint;
+ delete pPoint;
+ pPoint = pTempPoint;
+ }
+}
+
+// -----------------------------------------------------------------------
+//
+// generate separations from lines and process union with existing
+// separations
+
+void ImplRegionBand::ProcessPoints()
+{
+ // check Pointlist
+ ImplRegionBandPoint* pRegionBandPoint = mpFirstBandPoint;
+ while ( pRegionBandPoint )
+ {
+ // within list?
+ if ( pRegionBandPoint && pRegionBandPoint->mpNextBandPoint )
+ {
+ // start/stop?
+ if ( pRegionBandPoint->mbEndPoint && pRegionBandPoint->mpNextBandPoint->mbEndPoint )
+ {
+ // same direction? -> remove next point!
+ if ( pRegionBandPoint->meLineType == pRegionBandPoint->mpNextBandPoint->meLineType )
+ {
+ ImplRegionBandPoint* pSaveRegionBandPoint = pRegionBandPoint->mpNextBandPoint;
+ pRegionBandPoint->mpNextBandPoint = pRegionBandPoint->mpNextBandPoint->mpNextBandPoint;
+ delete pSaveRegionBandPoint;
+ }
+ }
+ }
+
+ // continue with next element in the list
+ pRegionBandPoint = pRegionBandPoint->mpNextBandPoint;
+ }
+
+ pRegionBandPoint = mpFirstBandPoint;
+ while ( pRegionBandPoint && pRegionBandPoint->mpNextBandPoint )
+ {
+ Union( pRegionBandPoint->mnX, pRegionBandPoint->mpNextBandPoint->mnX );
+
+ ImplRegionBandPoint* pNextBandPoint = pRegionBandPoint->mpNextBandPoint->mpNextBandPoint;
+
+ // remove allready processed points
+ delete pRegionBandPoint->mpNextBandPoint;
+ delete pRegionBandPoint;
+
+ // continue with next element in the list
+ pRegionBandPoint = pNextBandPoint;
+ }
+
+ // remove last element if necessary
+ if ( pRegionBandPoint )
+ delete pRegionBandPoint;
+
+ // list is now empty
+ mpFirstBandPoint = NULL;
+}
+
+// -----------------------------------------------------------------------
+//
+// generate separations from lines and process union with existing
+// separations
+
+BOOL ImplRegionBand::InsertPoint( long nX, long nLineId,
+ BOOL bEndPoint, LineType eLineType )
+{
+ if ( !mpFirstBandPoint )
+ {
+ mpFirstBandPoint = new ImplRegionBandPoint;
+ mpFirstBandPoint->mnX = nX;
+ mpFirstBandPoint->mnLineId = nLineId;
+ mpFirstBandPoint->mbEndPoint = bEndPoint;
+ mpFirstBandPoint->meLineType = eLineType;
+ mpFirstBandPoint->mpNextBandPoint = NULL;
+ return TRUE;
+ }
+
+ // look if line allready touched the band
+ ImplRegionBandPoint* pRegionBandPoint = mpFirstBandPoint;
+ ImplRegionBandPoint* pLastTestedRegionBandPoint = NULL;
+ while( pRegionBandPoint )
+ {
+ if ( pRegionBandPoint->mnLineId == nLineId )
+ {
+ if ( bEndPoint )
+ {
+ if( !pRegionBandPoint->mbEndPoint )
+ {
+ // remove old band point
+ if( !mpFirstBandPoint->mpNextBandPoint )
+ {
+ // if we've only got one point => replace first point
+ pRegionBandPoint->mnX = nX;
+ pRegionBandPoint->mbEndPoint = TRUE;
+ return TRUE;
+ }
+ else
+ {
+ // remove current point
+ if( !pLastTestedRegionBandPoint )
+ {
+ // remove and delete old first point
+ ImplRegionBandPoint* pSaveBandPoint = mpFirstBandPoint;
+ mpFirstBandPoint = mpFirstBandPoint->mpNextBandPoint;
+ delete pSaveBandPoint;
+ }
+ else
+ {
+ // remove and delete current band point
+ pLastTestedRegionBandPoint->mpNextBandPoint = pRegionBandPoint->mpNextBandPoint;
+ delete pRegionBandPoint;
+ }
+
+ break;
+ }
+ }
+ }
+ else
+ return FALSE;
+ }
+
+ // use next element
+ pLastTestedRegionBandPoint = pRegionBandPoint;
+ pRegionBandPoint = pRegionBandPoint->mpNextBandPoint;
+ }
+
+ // search appropriate position and insert point into the list
+ ImplRegionBandPoint* pNewRegionBandPoint;
+
+ pRegionBandPoint = mpFirstBandPoint;
+ pLastTestedRegionBandPoint = NULL;
+ while ( pRegionBandPoint )
+ {
+ // new point completly left? -> insert as first point
+ if ( nX <= pRegionBandPoint->mnX )
+ {
+ pNewRegionBandPoint = new ImplRegionBandPoint;
+ pNewRegionBandPoint->mnX = nX;
+ pNewRegionBandPoint->mnLineId = nLineId;
+ pNewRegionBandPoint->mbEndPoint = bEndPoint;
+ pNewRegionBandPoint->meLineType = eLineType;
+ pNewRegionBandPoint->mpNextBandPoint = pRegionBandPoint;
+
+ // connections to the new point
+ if ( !pLastTestedRegionBandPoint )
+ mpFirstBandPoint = pNewRegionBandPoint;
+ else
+ pLastTestedRegionBandPoint->mpNextBandPoint = pNewRegionBandPoint;
+
+ return TRUE;
+ }
+
+ // use next element
+ pLastTestedRegionBandPoint = pRegionBandPoint;
+ pRegionBandPoint = pRegionBandPoint->mpNextBandPoint;
+ }
+
+ // not inserted -> add to the end of the list
+ pNewRegionBandPoint = new ImplRegionBandPoint;
+ pNewRegionBandPoint->mnX = nX;
+ pNewRegionBandPoint->mnLineId = nLineId;
+ pNewRegionBandPoint->mbEndPoint = bEndPoint;
+ pNewRegionBandPoint->meLineType = eLineType;
+ pNewRegionBandPoint->mpNextBandPoint = NULL;
+
+ // connections to the new point
+ pLastTestedRegionBandPoint->mpNextBandPoint = pNewRegionBandPoint;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplRegionBand::MoveX( long nHorzMove )
+{
+ // move all x-separations
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ pSep->mnXLeft += nHorzMove;
+ pSep->mnXRight += nHorzMove;
+ pSep = pSep->mpNextSep;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplRegionBand::ScaleX( double fHorzScale )
+{
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ pSep->mnXLeft = FRound( pSep->mnXLeft * fHorzScale );
+ pSep->mnXRight = FRound( pSep->mnXRight * fHorzScale );
+ pSep = pSep->mpNextSep;
+ }
+}
+
+// -----------------------------------------------------------------------
+//
+// combine overlaping sparations
+
+BOOL ImplRegionBand::OptimizeBand()
+{
+ ImplRegionBandSep* pPrevSep;
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ // remove?
+ if ( pSep->mbRemoved || (pSep->mnXRight < pSep->mnXLeft) )
+ {
+ ImplRegionBandSep* pOldSep = pSep;
+ if ( pSep == mpFirstSep )
+ mpFirstSep = pSep->mpNextSep;
+ else
+ pPrevSep->mpNextSep = pSep->mpNextSep;
+ pSep = pSep->mpNextSep;
+ delete pOldSep;
+ continue;
+ }
+
+ // overlaping separations? -> combine!
+ if ( pSep->mpNextSep )
+ {
+ if ( (pSep->mnXRight+1) >= pSep->mpNextSep->mnXLeft )
+ {
+ if ( pSep->mpNextSep->mnXRight > pSep->mnXRight )
+ pSep->mnXRight = pSep->mpNextSep->mnXRight;
+
+ ImplRegionBandSep* pOldSep = pSep->mpNextSep;
+ pSep->mpNextSep = pOldSep->mpNextSep;
+ delete pOldSep;
+ continue;
+ }
+ }
+
+ pPrevSep = pSep;
+ pSep = pSep->mpNextSep;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplRegionBand::Union( long nXLeft, long nXRight )
+{
+ DBG_ASSERT( nXLeft <= nXRight, "ImplRegionBand::Union(): nxLeft > nXRight" );
+
+ // band empty? -> add element
+ if ( !mpFirstSep )
+ {
+ mpFirstSep = new ImplRegionBandSep;
+ mpFirstSep->mnXLeft = nXLeft;
+ mpFirstSep->mnXRight = nXRight;
+ mpFirstSep->mbRemoved = FALSE;
+ mpFirstSep->mpNextSep = NULL;
+ return;
+ }
+
+ // process real union
+ ImplRegionBandSep* pNewSep;
+ ImplRegionBandSep* pPrevSep;
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ // new separation completely inside? nothing to do!
+ if ( (nXLeft >= pSep->mnXLeft) && (nXRight <= pSep->mnXRight) )
+ return;
+
+ // new separation completly left? -> new separation!
+ if ( nXRight < pSep->mnXLeft )
+ {
+ pNewSep = new ImplRegionBandSep;
+ pNewSep->mnXLeft = nXLeft;
+ pNewSep->mnXRight = nXRight;
+ pNewSep->mbRemoved = FALSE;
+
+ pNewSep->mpNextSep = pSep;
+ if ( pSep == mpFirstSep )
+ mpFirstSep = pNewSep;
+ else
+ pPrevSep->mpNextSep = pNewSep;
+ break;
+ }
+
+ // new separation overlaping from left? -> extend boundary
+ if ( (nXRight >= pSep->mnXLeft) && (nXLeft <= pSep->mnXLeft) )
+ pSep->mnXLeft = nXLeft;
+
+ // new separation overlaping from right? -> extend boundary
+ if ( (nXLeft <= pSep->mnXRight) && (nXRight > pSep->mnXRight) )
+ {
+ pSep->mnXRight = nXRight;
+ break;
+ }
+
+ // not inserted, but last element? -> add to the end of the list
+ if ( !pSep->mpNextSep && (nXLeft > pSep->mnXRight) )
+ {
+ pNewSep = new ImplRegionBandSep;
+ pNewSep->mnXLeft = nXLeft;
+ pNewSep->mnXRight = nXRight;
+ pNewSep->mbRemoved = FALSE;
+
+ pSep->mpNextSep = pNewSep;
+ pNewSep->mpNextSep = NULL;
+ break;
+ }
+
+ pPrevSep = pSep;
+ pSep = pSep->mpNextSep;
+ }
+
+ OptimizeBand();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplRegionBand::Intersect( long nXLeft, long nXRight )
+{
+ DBG_ASSERT( nXLeft <= nXRight, "ImplRegionBand::Intersect(): nxLeft > nXRight" );
+
+ // band has been touched
+ mbTouched = TRUE;
+
+ // band empty? -> nothing to do
+ if ( !mpFirstSep )
+ return;
+
+ // process real intersection
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ // new separation completly outside? -> remove separation
+ if ( (nXRight < pSep->mnXLeft) || (nXLeft > pSep->mnXRight) )
+ // will be removed from the optimizer
+ pSep->mbRemoved = TRUE;
+
+ // new separation overlaping from left? -> reduce right boundary
+ if ( (nXLeft <= pSep->mnXLeft) &&
+ (nXRight <= pSep->mnXRight) &&
+ (nXRight >= pSep->mnXLeft) )
+ pSep->mnXRight = nXRight;
+
+ // new separation overlaping from right? -> reduce right boundary
+ if ( (nXLeft >= pSep->mnXLeft) &&
+ (nXLeft <= pSep->mnXRight) &&
+ (nXRight >= pSep->mnXRight) )
+ pSep->mnXLeft = nXLeft;
+
+ // new separation within the actual one? -> reduce both boundaries
+ if ( (nXLeft >= pSep->mnXLeft) && (nXRight <= pSep->mnXRight) )
+ {
+ pSep->mnXRight = nXRight;
+ pSep->mnXLeft = nXLeft;
+ }
+
+ pSep = pSep->mpNextSep;
+ }
+
+ OptimizeBand();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplRegionBand::Exclude( long nXLeft, long nXRight )
+{
+ DBG_ASSERT( nXLeft <= nXRight, "ImplRegionBand::Exclude(): nxLeft > nXRight" );
+
+ // band has been touched
+ mbTouched = TRUE;
+
+ // band empty? -> nothing to do
+ if ( !mpFirstSep )
+ return;
+
+ // process real exclusion
+ ImplRegionBandSep* pNewSep;
+ ImplRegionBandSep* pPrevSep;
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ BOOL bSepProcessed = FALSE;
+
+ // new separation completely overlapping? -> remove separation
+ if ( (nXLeft <= pSep->mnXLeft) && (nXRight >= pSep->mnXRight) )
+ {
+ // will be removed from the optimizer
+ pSep->mbRemoved = TRUE;
+ bSepProcessed = TRUE;
+ }
+
+ // new separation overlaping from left? -> reduce boundary
+ if ( !bSepProcessed )
+ {
+ if ( (nXRight >= pSep->mnXLeft) && (nXLeft <= pSep->mnXLeft) )
+ {
+ pSep->mnXLeft = nXRight+1;
+ bSepProcessed = TRUE;
+ }
+ }
+
+ // new separation overlaping from right? -> reduce boundary
+ if ( !bSepProcessed )
+ {
+ if ( (nXLeft <= pSep->mnXRight) && (nXRight > pSep->mnXRight) )
+ {
+ pSep->mnXRight = nXLeft-1;
+ bSepProcessed = TRUE;
+ }
+ }
+
+ // new separation within the actual one? -> reduce boundary
+ // and add new entry for reminder
+ if ( !bSepProcessed )
+ {
+ if ( (nXLeft >= pSep->mnXLeft) && (nXRight <= pSep->mnXRight) )
+ {
+ pNewSep = new ImplRegionBandSep;
+ pNewSep->mnXLeft = pSep->mnXLeft;
+ pNewSep->mnXRight = nXLeft-1;
+ pNewSep->mbRemoved = FALSE;
+
+ pSep->mnXLeft = nXRight+1;
+
+ // connections from the new separation
+ pNewSep->mpNextSep = pSep;
+
+ // connections to the new separation
+ if ( pSep == mpFirstSep )
+ mpFirstSep = pNewSep;
+ else
+ pPrevSep->mpNextSep = pNewSep;
+ }
+ }
+
+ pPrevSep = pSep;
+ pSep = pSep->mpNextSep;
+ }
+
+ OptimizeBand();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplRegionBand::XOr( long nXLeft, long nXRight )
+{
+ DBG_ASSERT( nXLeft <= nXRight, "ImplRegionBand::XOr(): nxLeft > nXRight" );
+
+ // band empty? -> add element
+ if ( !mpFirstSep )
+ {
+ mpFirstSep = new ImplRegionBandSep;
+ mpFirstSep->mnXLeft = nXLeft;
+ mpFirstSep->mnXRight = nXRight;
+ mpFirstSep->mbRemoved = FALSE;
+ mpFirstSep->mpNextSep = NULL;
+ return;
+ }
+
+ // process real xor
+ ImplRegionBandSep* pNewSep;
+ ImplRegionBandSep* pPrevSep;
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ // new separation completely overlapping?
+ // -> move boundaries to left remainder
+ // -> reduce boundaries of new separation
+ if ( (nXLeft <= pSep->mnXLeft) && (nXRight >= pSep->mnXRight) )
+ {
+ int iOldXRight = pSep->mnXRight;
+ pSep->mnXRight = pSep->mnXLeft;
+ pSep->mnXLeft = nXLeft;
+ nXLeft = pSep->mnXRight;
+ }
+
+ // new separation overlaping from left?
+ // -> move boundaries to left remainder
+ // -> set boundaries of new separation to right remainder
+ if ( (nXRight >= pSep->mnXLeft) && (nXLeft <= pSep->mnXLeft) )
+ {
+ int iOldXRight = pSep->mnXRight;
+ pSep->mnXRight = pSep->mnXLeft;
+ pSep->mnXLeft = nXLeft;
+ nXLeft = pSep->mnXRight;
+ }
+
+ // new separation overlaping from right? -> reduce boundary
+ if ( (nXLeft <= pSep->mnXRight) && (nXRight > pSep->mnXRight) )
+ pSep->mnXRight = nXLeft;
+
+ // new separation within the actual one? -> reduce boundary
+ // and add new entry for reminder
+ if ( (nXLeft >= pSep->mnXLeft) && (nXRight <= pSep->mnXRight) )
+ {
+ pNewSep = new ImplRegionBandSep;
+ pNewSep->mnXLeft = pSep->mnXLeft;
+ pNewSep->mnXRight = nXLeft;
+
+ pSep->mnXLeft = nXRight;
+
+ // connections from the new separation
+ pNewSep->mpNextSep = pSep;
+
+ // connections to the new separation
+ if ( pSep == mpFirstSep )
+ mpFirstSep = pNewSep;
+ else
+ pPrevSep->mpNextSep = pNewSep;
+ }
+
+ pPrevSep = pSep;
+ pSep = pSep->mpNextSep;
+ }
+
+ OptimizeBand();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplRegionBand::IsInside( long nX )
+{
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ if ( (pSep->mnXLeft <= nX) && (pSep->mnXRight >= nX) )
+ return TRUE;
+
+ pSep = pSep->mpNextSep;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplRegionBand::IsOver( long nLeft, long nRight )
+{
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ if ( (pSep->mnXLeft < nRight) && (pSep->mnXRight > nLeft) )
+ return TRUE;
+
+ pSep = pSep->mpNextSep;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplRegionBand::IsInside( long nLeft, long nRight )
+{
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep )
+ {
+ if ( (pSep->mnXLeft >= nLeft) && (nRight <= pSep->mnXRight) )
+ return TRUE;
+
+ pSep = pSep->mpNextSep;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplRegionBand::GetXLeftBoundary() const
+{
+ DBG_ASSERT( mpFirstSep != NULL, "ImplRegionBand::XLeftBoundary -> no separation in band!" );
+
+ return mpFirstSep->mnXLeft;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplRegionBand::GetXRightBoundary() const
+{
+ DBG_ASSERT( mpFirstSep != NULL, "ImplRegionBand::XRightBoundary -> no separation in band!" );
+
+ // search last separation
+ ImplRegionBandSep* pSep = mpFirstSep;
+ while ( pSep->mpNextSep )
+ pSep = pSep->mpNextSep;
+ return pSep->mnXRight;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplRegionBand::operator==( const ImplRegionBand& rRegionBand ) const
+{
+ ImplRegionBandSep* pOwnRectBandSep = mpFirstSep;
+ ImplRegionBandSep* pSecondRectBandSep = rRegionBand.mpFirstSep;
+ while ( pOwnRectBandSep && pSecondRectBandSep )
+ {
+ // get boundaries of current rectangle
+ long nOwnXLeft = pOwnRectBandSep->mnXLeft;
+ long nSecondXLeft = pSecondRectBandSep->mnXLeft;
+ if ( nOwnXLeft != nSecondXLeft )
+ return FALSE;
+
+ long nOwnXRight = pOwnRectBandSep->mnXRight;
+ long nSecondXRight = pSecondRectBandSep->mnXRight;
+ if ( nOwnXRight != nSecondXRight )
+ return FALSE;
+
+ // get next separation from current band
+ pOwnRectBandSep = pOwnRectBandSep->mpNextSep;
+
+ // get next separation from current band
+ pSecondRectBandSep = pSecondRectBandSep->mpNextSep;
+ }
+
+ // differnt number of separations?
+ if ( pOwnRectBandSep || pSecondRectBandSep )
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/vcl/source/gdi/region.cxx b/vcl/source/gdi/region.cxx
new file mode 100644
index 000000000000..000cad2a909b
--- /dev/null
+++ b/vcl/source/gdi/region.cxx
@@ -0,0 +1,2458 @@
+/*************************************************************************
+ *
+ * $RCSfile: region.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_REGION_CXX
+
+#include <limits.h>
+
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _REGION_H
+#include <region.h>
+#endif
+#ifndef _REGION_HXX
+#include <region.hxx>
+#endif
+#ifndef _REGBAND_HXX
+#include <regband.hxx>
+#endif
+
+// =======================================================================
+//
+// ImplRegionBand
+//
+// Die Klassen RegionBand/ImplRegionBand speichert Regionen in Form von
+// Rechtecken ab. Die Region ist in Y-Richtung in Baendern unterteilt, die
+// wiederum ein oder mehrere Rechtecke mit der Hoehe des Bandes enthalten.
+//
+// Leere Baender werden entfernt.
+//
+// Polygone und PolyPolygone werden ebenfalls in Rechtecke zerlegt und in
+// der Baendern abgelegt. Hierzu werden alle Punkte der einzelnen Polygone
+// mit dem Bresenham-Algorithmus berechnet und in die Baender eingetragen.
+// Nach der vollstaendigen Berechung aller Kanten werden die entsprechenden
+// Rechntecke berechnet
+
+// =======================================================================
+
+static ImplRegionBase aImplNullRegion = { 0, 0, NULL };
+static ImplRegionBase aImplEmptyRegion = { 0, 0, NULL };
+
+// =======================================================================
+
+DBG_NAME( Region );
+DBG_NAMEEX( Polygon );
+DBG_NAMEEX( PolyPolygon );
+
+// -----------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+const char* ImplDbgTestRegion( const void* pObj )
+{
+ Region* pRegion = (Region*)pObj;
+ ImplRegion* pImplRegion = pRegion->ImplGetImplRegion();
+
+ if ( aImplNullRegion.mnRefCount )
+ return "Null-Region-RefCount modified";
+ if ( aImplNullRegion.mnRectCount )
+ return "Null-Region-RectCount modified";
+ if ( aImplNullRegion.mpPolyPoly )
+ return "Null-Region-PolyPoly modified";
+ if ( aImplEmptyRegion.mnRefCount )
+ return "Emptry-Region-RefCount modified";
+ if ( aImplEmptyRegion.mnRectCount )
+ return "Emptry-Region-RectCount modified";
+ if ( aImplEmptyRegion.mpPolyPoly )
+ return "Emptry-Region-PolyPoly modified";
+
+ if ( (pImplRegion != &aImplEmptyRegion) && (pImplRegion != &aImplNullRegion) )
+ {
+ ULONG nCount = 0;
+ const ImplRegionBand* pBand = pImplRegion->ImplGetFirstRegionBand();
+ while ( pBand )
+ {
+ if ( pBand->mnYBottom < pBand->mnYTop )
+ return "YBottom < YTop";
+ if ( pBand->mpNextBand )
+ {
+ if ( pBand->mnYBottom >= pBand->mpNextBand->mnYTop )
+ return "overlapping bands in region";
+ }
+ if ( pBand->mbTouched > 1 )
+ return "Band-mbTouched overwrite";
+
+ ImplRegionBandSep* pSep = pBand->mpFirstSep;
+ while ( pSep )
+ {
+ if ( pSep->mnXRight < pSep->mnXLeft )
+ return "XLeft < XRight";
+ if ( pSep->mpNextSep )
+ {
+ if ( pSep->mnXRight >= pSep->mpNextSep->mnXLeft )
+ return "overlapping separations in region";
+ }
+ if ( pSep->mbRemoved > 1 )
+ return "Sep-mbRemoved overwrite";
+
+ nCount++;
+ pSep = pSep->mpNextSep;
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+
+ if ( pImplRegion->mnRectCount != nCount )
+ return "mnRetCount is not valid";
+ }
+
+ return NULL;
+}
+#endif
+
+// =======================================================================
+
+inline void Region::ImplPolyPolyRegionToBandRegion()
+{
+ if ( mpImplRegion->mpPolyPoly )
+ ImplPolyPolyRegionToBandRegionFunc();
+}
+
+// =======================================================================
+
+ImplRegion::ImplRegion()
+{
+ mnRefCount = 1;
+ mnRectCount = 0;
+ mpPolyPoly = NULL;
+ mpFirstBand = NULL;
+ mpLastCheckedBand = NULL;
+}
+
+// ------------------------------------------------------------------------
+
+ImplRegion::ImplRegion( const PolyPolygon& rPolyPoly )
+{
+ mnRefCount = 1;
+ mnRectCount = 0;
+ mpFirstBand = NULL;
+ mpLastCheckedBand = NULL;
+ mpPolyPoly = new PolyPolygon( rPolyPoly );
+}
+
+// -----------------------------------------------------------------------
+
+ImplRegion::ImplRegion( const ImplRegion& rImplRegion )
+{
+ mnRefCount = 1;
+ mnRectCount = rImplRegion.mnRectCount;
+ mpFirstBand = NULL;
+ mpLastCheckedBand = NULL;
+ if ( rImplRegion.mpPolyPoly )
+ mpPolyPoly = new PolyPolygon( *rImplRegion.mpPolyPoly );
+ else
+ mpPolyPoly = NULL;
+
+ // insert band(s) into the list
+ ImplRegionBand* pNewBand;
+ ImplRegionBand* pPrevBand;
+ ImplRegionBand* pBand = rImplRegion.mpFirstBand;
+ while ( pBand )
+ {
+ pNewBand = new ImplRegionBand( *pBand );
+
+ // first element? -> set as first into the list
+ if ( pBand == rImplRegion.mpFirstBand )
+ mpFirstBand = pNewBand;
+ else
+ pPrevBand->mpNextBand = pNewBand;
+
+ pPrevBand = pNewBand;
+ pBand = pBand->mpNextBand;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ImplRegion::~ImplRegion()
+{
+ DBG_ASSERT( (this != &aImplEmptyRegion) && (this != &aImplNullRegion),
+ "ImplRegion::~ImplRegion() - Empty oder NULL-Region" )
+
+ ImplRegionBand* pBand = mpFirstBand;
+ while ( pBand )
+ {
+ ImplRegionBand* pTempBand = pBand->mpNextBand;
+ delete pBand;
+ pBand = pTempBand;
+ }
+
+ delete mpPolyPoly;
+}
+
+// -----------------------------------------------------------------------
+//
+// create complete range of bands in single steps
+
+void ImplRegion::CreateBandRange( long nYTop, long nYBottom )
+{
+ // add top band
+ mpFirstBand = new ImplRegionBand( nYTop-1, nYTop-1 );
+
+ // begin first search from the first element
+ mpLastCheckedBand = mpFirstBand;
+
+ ImplRegionBand* pBand = mpFirstBand;
+ for ( int i = nYTop; i <= nYBottom+1; i++ )
+ {
+ // create new band
+ ImplRegionBand* pNewBand = new ImplRegionBand( i, i );
+ pBand->mpNextBand = pNewBand;
+ if ( pBand != mpFirstBand )
+ pNewBand->mpPrevBand = pBand;
+
+ pBand = pBand->mpNextBand;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplRegion::InsertLine( const Point& rStartPt, const Point& rEndPt,
+ long nLineId )
+{
+ long nX, nY;
+
+ // lines consisting of a single point do not interest here
+ if ( rStartPt == rEndPt )
+ return TRUE;
+
+ LineType eLineType = (rStartPt.Y() > rEndPt.Y()) ? LINE_DESCENDING : LINE_ASCENDING;
+ if ( rStartPt.X() == rEndPt.X() )
+ {
+ // vertical line
+ const long nEndY = rEndPt.Y();
+
+ nX = rStartPt.X();
+ nY = rStartPt.Y();
+
+ if( nEndY > nY )
+ {
+ for ( ; nY <= nEndY; nY++ )
+ {
+ Point aNewPoint( nX, nY );
+ InsertPoint( aNewPoint, nLineId,
+ (aNewPoint == rEndPt) || (aNewPoint == rStartPt),
+ eLineType );
+ }
+ }
+ else
+ {
+ for ( ; nY >= nEndY; nY-- )
+ {
+ Point aNewPoint( nX, nY );
+ InsertPoint( aNewPoint, nLineId,
+ (aNewPoint == rEndPt) || (aNewPoint == rStartPt),
+ eLineType );
+ }
+ }
+ }
+ else if ( rStartPt.Y() != rEndPt.Y() )
+ {
+ const long nDX = labs( rEndPt.X() - rStartPt.X() );
+ const long nDY = labs( rEndPt.Y() - rStartPt.Y() );
+ const long nStartX = rStartPt.X();
+ const long nStartY = rStartPt.Y();
+ const long nEndX = rEndPt.X();
+ const long nEndY = rEndPt.Y();
+ const long nXInc = ( nStartX < nEndX ) ? 1L : -1L;
+ const long nYInc = ( nStartY < nEndY ) ? 1L : -1L;
+
+ if ( nDX >= nDY )
+ {
+ const long nDYX = ( nDY - nDX ) << 1;
+ const long nDY2 = nDY << 1;
+ long nD = nDY2 - nDX;
+
+ for ( nX = nStartX, nY = nStartY; nX != nEndX; nX += nXInc )
+ {
+ InsertPoint( Point( nX, nY ), nLineId, nStartX == nX, eLineType );
+
+ if ( nD < 0L )
+ nD += nDY2;
+ else
+ nD += nDYX, nY += nYInc;
+ }
+ }
+ else
+ {
+ const long nDYX = ( nDX - nDY ) << 1;
+ const long nDY2 = nDX << 1;
+ long nD = nDY2 - nDY;
+
+ for ( nX = nStartX, nY = nStartY; nY != nEndY; nY += nYInc )
+ {
+ InsertPoint( Point( nX, nY ), nLineId, nStartY == nY, eLineType );
+
+ if ( nD < 0L )
+ nD += nDY2;
+ else
+ nD += nDYX, nX += nXInc;
+ }
+ }
+
+ // last point
+ InsertPoint( Point( nEndX, nEndY ), nLineId, TRUE, eLineType );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+//
+// search for appropriate place for the new point
+
+BOOL ImplRegion::InsertPoint( const Point &rPoint, long nLineID,
+ BOOL bEndPoint, LineType eLineType )
+{
+ DBG_ASSERT( mpFirstBand != NULL, "ImplRegion::InsertPoint - no bands available!" );
+
+ if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
+ {
+ mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
+ return TRUE;
+ }
+
+ if ( rPoint.Y() > mpLastCheckedBand->mnYTop )
+ {
+ // Search ascending
+ while ( mpLastCheckedBand )
+ {
+ // Insert point if possible
+ if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
+ {
+ mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
+ return TRUE;
+ }
+
+ mpLastCheckedBand = mpLastCheckedBand->mpNextBand;
+ }
+
+ DBG_ERROR( "ImplRegion::InsertPoint reached the end of the list!" );
+ }
+ else
+ {
+ // Search descending
+ while ( mpLastCheckedBand )
+ {
+ // Insert point if possible
+ if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
+ {
+ mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
+ return TRUE;
+ }
+
+ mpLastCheckedBand = mpLastCheckedBand->mpPrevBand;
+ }
+
+ DBG_ERROR( "ImplRegion::InsertPoint reached the beginning of the list!" );
+ }
+
+ DBG_ERROR( "ImplRegion::InsertPoint point not inserted!" );
+
+ // reinitialize pointer (should never be reached!)
+ mpLastCheckedBand = mpFirstBand;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+//
+// search for appropriate places for the new bands
+
+void ImplRegion::InsertBands( long nTop, long nBottom )
+{
+ // region empty? -> set rectagle as first entry!
+ if ( !mpFirstBand )
+ {
+ // add band with boundaries of the rectangle
+ mpFirstBand = new ImplRegionBand( nTop, nBottom );
+ return;
+ }
+
+ // find/insert bands for the boundaries of the rectangle
+ BOOL bTopBoundaryInserted = FALSE;
+ BOOL bTop2BoundaryInserted = FALSE;
+ BOOL bBottomBoundaryInserted = FALSE;
+
+ // special case: top boundary is above the first band
+ ImplRegionBand* pNewBand;
+ if ( nTop < mpFirstBand->mnYTop )
+ {
+ // create new band above the first in the list
+ pNewBand = new ImplRegionBand( nTop, mpFirstBand->mnYTop );
+ if ( nBottom < mpFirstBand->mnYTop )
+ pNewBand->mnYBottom = nBottom;
+
+ // insert band into the list
+ pNewBand->mpNextBand = mpFirstBand;
+ mpFirstBand = pNewBand;
+
+ bTopBoundaryInserted = TRUE;
+ }
+
+ // insert band(s) into the list
+ ImplRegionBand* pBand = mpFirstBand;
+ while ( pBand )
+ {
+ // Insert Bands if possible
+ if ( !bTopBoundaryInserted )
+ bTopBoundaryInserted = InsertSingleBand( pBand, nTop - 1 );
+
+ if ( !bTop2BoundaryInserted )
+ bTop2BoundaryInserted = InsertSingleBand( pBand, nTop );
+
+ if ( !bBottomBoundaryInserted && (nTop != nBottom) )
+ bBottomBoundaryInserted = InsertSingleBand( pBand, nBottom );
+
+ // both boundaries inserted? -> nothing more to do
+ if ( bTopBoundaryInserted && bTop2BoundaryInserted && bBottomBoundaryInserted )
+ break;
+
+ // insert bands between two bands if neccessary
+ if ( pBand->mpNextBand )
+ {
+ if ( (pBand->mnYBottom + 1) < pBand->mpNextBand->mnYTop )
+ {
+ // copy band with list and set new boundary
+ pNewBand = new ImplRegionBand( pBand->mnYBottom+1,
+ pBand->mpNextBand->mnYTop-1 );
+
+ // insert band into the list
+ pNewBand->mpNextBand = pBand->mpNextBand;
+ pBand->mpNextBand = pNewBand;
+ }
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+}
+
+// -----------------------------------------------------------------------
+//
+// create new band and insert it into the list
+
+BOOL ImplRegion::InsertSingleBand( ImplRegionBand* pBand,
+ long nYBandPosition )
+{
+ // boundary already included in band with height 1? -> nothing to do!
+ if ( (pBand->mnYTop == pBand->mnYBottom) &&
+ (nYBandPosition == pBand->mnYTop) )
+ return TRUE;
+
+ // insert single height band on top?
+ ImplRegionBand* pNewBand;
+ if ( nYBandPosition == pBand->mnYTop )
+ {
+ // copy band with list and set new boundary
+ pNewBand = new ImplRegionBand( *pBand );
+ pNewBand->mnYTop = nYBandPosition+1;
+
+ // insert band into the list
+ pNewBand->mpNextBand = pBand->mpNextBand;
+ pBand->mnYBottom = nYBandPosition;
+ pBand->mpNextBand = pNewBand;
+
+ return TRUE;
+ }
+
+ // top of new rectangle within the current band? -> insert new band and copy data
+ if ( (nYBandPosition > pBand->mnYTop) &&
+ (nYBandPosition < pBand->mnYBottom) )
+ {
+ // copy band with list and set new boundary
+ pNewBand = new ImplRegionBand( *pBand );
+ pNewBand->mnYTop = nYBandPosition;
+
+ // insert band into the list
+ pNewBand->mpNextBand = pBand->mpNextBand;
+ pBand->mnYBottom = nYBandPosition;
+ pBand->mpNextBand = pNewBand;
+
+ // copy band with list and set new boundary
+ pNewBand = new ImplRegionBand( *pBand );
+ pNewBand->mnYTop = nYBandPosition;
+
+ // insert band into the list
+ pBand->mpNextBand->mnYTop = nYBandPosition+1;
+
+ pNewBand->mpNextBand = pBand->mpNextBand;
+ pBand->mnYBottom = nYBandPosition - 1;
+ pBand->mpNextBand = pNewBand;
+
+ return TRUE;
+ }
+
+ // create new band behind the current in the list
+ if ( !pBand->mpNextBand )
+ {
+ if ( nYBandPosition == pBand->mnYBottom )
+ {
+ // copy band with list and set new boundary
+ pNewBand = new ImplRegionBand( *pBand );
+ pNewBand->mnYTop = pBand->mnYBottom;
+ pNewBand->mnYBottom = nYBandPosition;
+
+ pBand->mnYBottom = nYBandPosition-1;
+
+ // append band to the list
+ pBand->mpNextBand = pNewBand;
+ return TRUE;
+ }
+
+ if ( nYBandPosition > pBand->mnYBottom )
+ {
+ // create new band
+ pNewBand = new ImplRegionBand( pBand->mnYBottom + 1, nYBandPosition );
+
+ // append band to the list
+ pBand->mpNextBand = pNewBand;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplRegion::Union( long nLeft, long nTop, long nRight, long nBottom )
+{
+ DBG_ASSERT( nLeft <= nRight, "ImplRegion::Union() - nLeft > nRight" );
+ DBG_ASSERT( nTop <= nBottom, "ImplRegion::Union() - nTop > nBottom" );
+
+ // process union
+ ImplRegionBand* pBand = mpFirstBand;
+ while ( pBand )
+ {
+ if ( pBand->mnYTop >= nTop )
+ {
+ if ( pBand->mnYBottom <= nBottom )
+ pBand->Union( nLeft, nRight );
+ else
+ {
+#ifdef DBG_UTIL
+ long nCurY = pBand->mnYBottom;
+ pBand = pBand->mpNextBand;
+ while ( pBand )
+ {
+ if ( (pBand->mnYTop < nCurY) || (pBand->mnYBottom < nCurY) )
+ {
+ DBG_ERROR( "ImplRegion::Union() - Bands not sorted!" );
+ }
+ pBand = pBand->mpNextBand;
+ }
+#endif
+ break;
+ }
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplRegion::Exclude( long nLeft, long nTop, long nRight, long nBottom )
+{
+ DBG_ASSERT( nLeft <= nRight, "ImplRegion::Exclude() - nLeft > nRight" );
+ DBG_ASSERT( nTop <= nBottom, "ImplRegion::Exclude() - nTop > nBottom" );
+
+ // process exclude
+ ImplRegionBand* pBand = mpFirstBand;
+ while ( pBand )
+ {
+ if ( pBand->mnYTop >= nTop )
+ {
+ if ( pBand->mnYBottom <= nBottom )
+ pBand->Exclude( nLeft, nRight );
+ else
+ {
+#ifdef DBG_UTIL
+ long nCurY = pBand->mnYBottom;
+ pBand = pBand->mpNextBand;
+ while ( pBand )
+ {
+ if ( (pBand->mnYTop < nCurY) || (pBand->mnYBottom < nCurY) )
+ {
+ DBG_ERROR( "ImplRegion::Exclude() - Bands not sorted!" );
+ }
+ pBand = pBand->mpNextBand;
+ }
+#endif
+ break;
+ }
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplRegion::XOr( long nLeft, long nTop, long nRight, long nBottom )
+{
+ DBG_ASSERT( nLeft <= nRight, "ImplRegion::Exclude() - nLeft > nRight" );
+ DBG_ASSERT( nTop <= nBottom, "ImplRegion::Exclude() - nTop > nBottom" );
+
+ // process xor
+ ImplRegionBand* pBand = mpFirstBand;
+ while ( pBand )
+ {
+ if ( pBand->mnYTop >= nTop )
+ {
+ if ( pBand->mnYBottom <= nBottom )
+ pBand->XOr( nLeft, nRight );
+ else
+ {
+#ifdef DBG_UTIL
+ long nCurY = pBand->mnYBottom;
+ pBand = pBand->mpNextBand;
+ while ( pBand )
+ {
+ if ( (pBand->mnYTop < nCurY) || (pBand->mnYBottom < nCurY) )
+ {
+ DBG_ERROR( "ImplRegion::XOr() - Bands not sorted!" );
+ }
+ pBand = pBand->mpNextBand;
+ }
+#endif
+ break;
+ }
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+}
+
+// -----------------------------------------------------------------------
+//
+// remove empty bands
+
+BOOL ImplRegion::OptimizeBandList()
+{
+ DBG_ASSERT( (this != &aImplNullRegion) && (this != &aImplEmptyRegion),
+ "ImplRegion::OptimizeBandList() - Empty oder NULL-Region" );
+
+ mnRectCount = 0;
+
+ ImplRegionBand* pPrevBand;
+ ImplRegionBand* pBand = mpFirstBand;
+ while ( pBand )
+ {
+ const BOOL bBTEqual = pBand->mpNextBand &&
+ (pBand->mnYBottom == pBand->mpNextBand->mnYTop);
+
+ // no separation? -> remove!
+ if ( pBand->IsEmpty() || (bBTEqual && (pBand->mnYBottom == pBand->mnYTop)) )
+ {
+ // save pointer
+ ImplRegionBand* pOldBand = pBand;
+
+ // previous element of the list
+ if ( pBand == mpFirstBand )
+ mpFirstBand = pBand->mpNextBand;
+ else
+ pPrevBand->mpNextBand = pBand->mpNextBand;
+
+ pBand = pBand->mpNextBand;
+ delete pOldBand;
+ }
+ else
+ {
+ // fixup
+ if ( bBTEqual )
+ pBand->mnYBottom = pBand->mpNextBand->mnYTop-1;
+
+ // this and next band with equal separations? -> combine!
+ if ( pBand->mpNextBand &&
+ ((pBand->mnYBottom+1) == pBand->mpNextBand->mnYTop) &&
+ (*pBand == *pBand->mpNextBand) )
+ {
+ // expand current height
+ pBand->mnYBottom = pBand->mpNextBand->mnYBottom;
+
+ // remove next band from list
+ ImplRegionBand* pDeletedBand = pBand->mpNextBand;
+ pBand->mpNextBand = pDeletedBand->mpNextBand;
+ delete pDeletedBand;
+
+ // check band again!
+ }
+ else
+ {
+ // count rectangles within band
+ ImplRegionBandSep* pSep = pBand->mpFirstSep;
+ while ( pSep )
+ {
+ mnRectCount++;
+ pSep = pSep->mpNextSep;
+ }
+
+ pPrevBand = pBand;
+ pBand = pBand->mpNextBand;
+ }
+ }
+ }
+
+#ifdef DBG_UTIL
+ pBand = mpFirstBand;
+ while ( pBand )
+ {
+ DBG_ASSERT( pBand->mpFirstSep != NULL,
+ "Exiting ImplRegion::OptimizeBandList(): empty band in region!" );
+
+ if ( pBand->mnYBottom < pBand->mnYTop )
+ DBG_ERROR( "ImplRegion::OptimizeBandList(): YBottomBoundary < YTopBoundary" );
+
+ if ( pBand->mpNextBand )
+ {
+ if ( pBand->mnYBottom >= pBand->mpNextBand->mnYTop )
+ DBG_ERROR( "ImplRegion::OptimizeBandList(): overlapping bands in region!" );
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+#endif
+
+ return (mnRectCount != 0);
+}
+
+// =======================================================================
+
+void Region::ImplCopyData()
+{
+ mpImplRegion->mnRefCount--;
+ mpImplRegion = new ImplRegion( *mpImplRegion );
+}
+
+// =======================================================================
+
+Region::Region()
+{
+ DBG_CTOR( Region, ImplDbgTestRegion );
+
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+}
+
+// -----------------------------------------------------------------------
+
+Region::Region( RegionType eType )
+{
+ DBG_CTOR( Region, ImplDbgTestRegion );
+ DBG_ASSERT( (eType == REGION_NULL) || (eType == REGION_EMPTY),
+ "Region( RegionType ) - RegionType != EMPTY/NULL" );
+
+ if ( eType == REGION_NULL )
+ mpImplRegion = (ImplRegion*)(&aImplNullRegion);
+ else
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+}
+
+// -----------------------------------------------------------------------
+
+Region::Region( const Rectangle& rRect )
+{
+ DBG_CTOR( Region, ImplDbgTestRegion );
+
+ ImplCreateRectRegion( rRect );
+}
+
+// -----------------------------------------------------------------------
+
+Region::Region( const Polygon& rPolygon )
+{
+ DBG_CTOR( Region, ImplDbgTestRegion );
+ DBG_CHKOBJ( &rPolygon, Polygon, NULL );
+
+ ImplCreatePolyPolyRegion( rPolygon );
+}
+
+// -----------------------------------------------------------------------
+
+Region::Region( const PolyPolygon& rPolyPoly )
+{
+ DBG_CTOR( Region, ImplDbgTestRegion );
+ DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
+
+ ImplCreatePolyPolyRegion( rPolyPoly );
+}
+
+// -----------------------------------------------------------------------
+
+Region::Region( const Region& rRegion )
+{
+ DBG_CTOR( Region, ImplDbgTestRegion );
+ DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
+ DBG_ASSERT( rRegion.mpImplRegion->mnRefCount < 0xFFFFFFFE, "Region: RefCount overflow" );
+
+ // copy pointer to instance of implementation
+ mpImplRegion = rRegion.mpImplRegion;
+ if ( mpImplRegion->mnRefCount )
+ mpImplRegion->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+Region::~Region()
+{
+ DBG_DTOR( Region, ImplDbgTestRegion );
+
+ // statische Object haben RefCount von 0
+ if ( mpImplRegion->mnRefCount )
+ {
+ if ( mpImplRegion->mnRefCount > 1 )
+ mpImplRegion->mnRefCount--;
+ else
+ delete mpImplRegion;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Region::ImplCreateRectRegion( const Rectangle& rRect )
+{
+ if ( rRect.IsEmpty() )
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ else
+ {
+ // get justified rectangle
+ long nTop = Min( rRect.Top(), rRect.Bottom() );
+ long nBottom = Max( rRect.Top(), rRect.Bottom() );
+ long nLeft = Min( rRect.Left(), rRect.Right() );
+ long nRight = Max( rRect.Left(), rRect.Right() );
+
+ // create instance of implementation class
+ mpImplRegion = new ImplRegion();
+
+ // add band with boundaries of the rectangle
+ mpImplRegion->mpFirstBand = new ImplRegionBand( nTop, nBottom );
+
+ // Set left and right boundaries of the band
+ mpImplRegion->mpFirstBand->Union( nLeft, nRight );
+ mpImplRegion->mnRectCount = 1;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Region::ImplCreatePolyPolyRegion( const PolyPolygon& rPolyPoly )
+{
+ const USHORT nPolyCount = rPolyPoly.Count();
+ if ( nPolyCount )
+ {
+ // polypolygon empty? -> empty region
+ const Rectangle aRect( rPolyPoly.GetBoundRect() );
+
+ if ( !aRect.IsEmpty() )
+ {
+ // width OR height == 1 ? => Rectangular region
+ if ( (aRect.GetWidth() == 1) || (aRect.GetHeight() == 1) )
+ ImplCreateRectRegion( aRect );
+ else
+ mpImplRegion = new ImplRegion( rPolyPoly );
+ }
+ else
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+ else
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+}
+
+// -----------------------------------------------------------------------
+
+void Region::ImplPolyPolyRegionToBandRegionFunc()
+{
+ const PolyPolygon aPolyPoly( *mpImplRegion->mpPolyPoly );
+
+ if ( mpImplRegion->mnRefCount > 1 )
+ mpImplRegion->mnRefCount--;
+ else
+ delete mpImplRegion;
+
+ const USHORT nPolyCount = aPolyPoly.Count();
+ if ( nPolyCount )
+ {
+ // polypolygon empty? -> empty region
+ const Rectangle aRect( aPolyPoly.GetBoundRect() );
+
+ if ( !aRect.IsEmpty() )
+ {
+ long nLineID = 0L;
+
+ // initialisation and creation of Bands
+ mpImplRegion = new ImplRegion();
+ mpImplRegion->CreateBandRange( aRect.Top(), aRect.Bottom() );
+
+ // insert polygons
+ for ( USHORT nPoly = 0; nPoly < nPolyCount; nPoly++ )
+ {
+ // get reference to current polygon
+ const Polygon& aPoly = aPolyPoly.GetObject( nPoly );
+ const USHORT nSize = aPoly.GetSize();
+
+ // not enough points ( <= 2 )? -> nothing to do!
+ if ( nSize <= 2 )
+ continue;
+
+ // band the polygon
+ for ( USHORT nPoint = 1; nPoint < nSize; nPoint++ )
+ mpImplRegion->InsertLine( aPoly.GetPoint(nPoint-1), aPoly.GetPoint(nPoint), nLineID++ );
+
+ // close polygon with line from first point to last point, if neccesary
+ const Point rLastPoint = aPoly.GetPoint(nSize-1);
+ const Point rFirstPoint = aPoly.GetPoint(0);
+ if ( rLastPoint != rFirstPoint )
+ mpImplRegion->InsertLine( rLastPoint, rFirstPoint, nLineID++ );
+ }
+
+ // process bands with lines
+ ImplRegionBand* pRegionBand = mpImplRegion->mpFirstBand;
+ while ( pRegionBand )
+ {
+ // generate separations from the lines and process union
+ pRegionBand->ProcessPoints();
+ pRegionBand = pRegionBand->mpNextBand;
+ }
+
+ // cleanup
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+ }
+ else
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+ else
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+}
+
+// -----------------------------------------------------------------------
+
+void Region::Move( long nHorzMove, long nVertMove )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // no region data? -> nothing to do
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return;
+
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ if ( mpImplRegion->mpPolyPoly )
+ mpImplRegion->mpPolyPoly->Move( nHorzMove, nVertMove );
+ else
+ {
+ ImplRegionBand* pBand = mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ // process the vertical move
+ if ( nVertMove != 0)
+ {
+ pBand->mnYTop = pBand->mnYTop + nVertMove;
+ pBand->mnYBottom = pBand->mnYBottom + nVertMove;
+ }
+
+ // process the horizontal move
+ if ( nHorzMove != 0)
+ pBand->MoveX( nHorzMove );
+
+ pBand = pBand->mpNextBand;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Region::Scale( double fScaleX, double fScaleY )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // no region data? -> nothing to do
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return;
+
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ if ( mpImplRegion->mpPolyPoly )
+ mpImplRegion->mpPolyPoly->Scale( fScaleX, fScaleY );
+ else
+ {
+ ImplRegionBand* pBand = mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ // process the vertical move
+ if ( fScaleY != 0.0 )
+ {
+ pBand->mnYTop = FRound( pBand->mnYTop * fScaleY );
+ pBand->mnYBottom = FRound( pBand->mnYBottom * fScaleY );
+ }
+
+ // process the horizontal move
+ if ( fScaleX != 0.0 )
+ pBand->ScaleX( fScaleX );
+
+ pBand = pBand->mpNextBand;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::Union( const Rectangle& rRect )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // is rectangle empty? -> nothing to do
+ if ( rRect.IsEmpty() )
+ return TRUE;
+
+ ImplPolyPolyRegionToBandRegion();
+
+ // no instance data? -> create!
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ mpImplRegion = new ImplRegion();
+
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ // get justified rectangle
+ long nLeft = Min( rRect.Left(), rRect.Right() );
+ long nTop = Min( rRect.Top(), rRect.Bottom() );
+ long nRight = Max( rRect.Left(), rRect.Right() );
+ long nBottom = Max( rRect.Top(), rRect.Bottom() );
+
+ // insert bands if the boundaries are not allready in the list
+ mpImplRegion->InsertBands( nTop, nBottom );
+
+ // process union
+ mpImplRegion->Union( nLeft, nTop, nRight, nBottom );
+
+ // cleanup
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::Intersect( const Rectangle& rRect )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // is rectangle empty? -> nothing to do
+ if ( rRect.IsEmpty() )
+ {
+ // statische Object haben RefCount von 0
+ if ( mpImplRegion->mnRefCount )
+ {
+ if ( mpImplRegion->mnRefCount > 1 )
+ mpImplRegion->mnRefCount--;
+ else
+ delete mpImplRegion;
+ }
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ return TRUE;
+ }
+
+ ImplPolyPolyRegionToBandRegion();
+
+ // is region empty? -> nothing to do!
+ if ( mpImplRegion == &aImplEmptyRegion )
+ return TRUE;
+
+ // get justified rectangle
+ long nLeft = Min( rRect.Left(), rRect.Right() );
+ long nTop = Min( rRect.Top(), rRect.Bottom() );
+ long nRight = Max( rRect.Left(), rRect.Right() );
+ long nBottom = Max( rRect.Top(), rRect.Bottom() );
+
+ // is own region NULL-region? -> copy data!
+ if ( mpImplRegion == &aImplNullRegion )
+ {
+ // create instance of implementation class
+ mpImplRegion = new ImplRegion();
+
+ // add band with boundaries of the rectangle
+ mpImplRegion->mpFirstBand = new ImplRegionBand( nTop, nBottom );
+
+ // Set left and right boundaries of the band
+ mpImplRegion->mpFirstBand->Union( nLeft, nRight );
+ mpImplRegion->mnRectCount = 1;
+
+ return TRUE;
+ }
+
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ // insert bands if the boundaries are not allready in the list
+ mpImplRegion->InsertBands( nTop, nBottom );
+
+ // process intersections
+ ImplRegionBand* pPrevBand;
+ ImplRegionBand* pBand = mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ // band within intersection boundary? -> process. otherwise remove
+ if ( (pBand->mnYTop >= nTop) &&
+ (pBand->mnYBottom <= nBottom) )
+ {
+ // process intersection
+ pBand->Intersect( nLeft, nRight );
+
+ pPrevBand = pBand;
+ pBand = pBand->mpNextBand;
+ }
+ else
+ {
+ ImplRegionBand* pOldBand = pBand;
+ if ( pBand == mpImplRegion->mpFirstBand )
+ mpImplRegion->mpFirstBand = pBand->mpNextBand;
+ else
+ pPrevBand->mpNextBand = pBand->mpNextBand;
+ pBand = pBand->mpNextBand;
+ delete pOldBand;
+ }
+ }
+
+ // cleanup
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::Exclude( const Rectangle& rRect )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // is rectangle empty? -> nothing to do
+ if ( rRect.IsEmpty() )
+ return TRUE;
+
+ ImplPolyPolyRegionToBandRegion();
+
+ // no instance data? -> create!
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return TRUE;
+
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ // get justified rectangle
+ long nLeft = Min( rRect.Left(), rRect.Right() );
+ long nTop = Min( rRect.Top(), rRect.Bottom() );
+ long nRight = Max( rRect.Left(), rRect.Right() );
+ long nBottom = Max( rRect.Top(), rRect.Bottom() );
+
+ // insert bands if the boundaries are not allready in the list
+ mpImplRegion->InsertBands( nTop, nBottom );
+
+ // process exclude
+ mpImplRegion->Exclude( nLeft, nTop, nRight, nBottom );
+
+ // cleanup
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::XOr( const Rectangle& rRect )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // is rectangle empty? -> nothing to do
+ if ( rRect.IsEmpty() )
+ return TRUE;
+
+ ImplPolyPolyRegionToBandRegion();
+
+ // no instance data? -> create!
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ mpImplRegion = new ImplRegion();
+
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ // get justified rectangle
+ long nLeft = Min( rRect.Left(), rRect.Right() );
+ long nTop = Min( rRect.Top(), rRect.Bottom() );
+ long nRight = Max( rRect.Left(), rRect.Right() );
+ long nBottom = Max( rRect.Top(), rRect.Bottom() );
+
+ // insert bands if the boundaries are not allready in the list
+ mpImplRegion->InsertBands( nTop, nBottom );
+
+ // process xor
+ mpImplRegion->XOr( nLeft, nTop, nRight, nBottom );
+
+ // cleanup
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::Union( const Region& rRegion )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ ImplPolyPolyRegionToBandRegion();
+ ((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
+
+ // is region empty or null? -> nothing to do
+ if ( (rRegion.mpImplRegion == &aImplEmptyRegion) || (rRegion.mpImplRegion == &aImplNullRegion) )
+ return TRUE;
+
+ // no instance data? -> create!
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ mpImplRegion = new ImplRegion();
+
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ // Alle Rechtecke aus der uebergebenen Region auf diese Region anwenden
+ ImplRegionBand* pBand = rRegion.mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ // insert bands if the boundaries are not allready in the list
+ mpImplRegion->InsertBands( pBand->mnYTop, pBand->mnYBottom );
+
+ // process all elements of the list
+ ImplRegionBandSep* pSep = pBand->mpFirstSep;
+ while ( pSep )
+ {
+ mpImplRegion->Union( pSep->mnXLeft, pBand->mnYTop,
+ pSep->mnXRight, pBand->mnYBottom );
+ pSep = pSep->mpNextSep;
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+
+ // cleanup
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::Intersect( const Region& rRegion )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // same instance data? -> nothing to do!
+ if ( mpImplRegion == rRegion.mpImplRegion )
+ return TRUE;
+
+ ImplPolyPolyRegionToBandRegion();
+ ((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
+
+ if ( mpImplRegion == &aImplEmptyRegion )
+ return TRUE;
+
+ // is region null? -> nothing to do
+ if ( rRegion.mpImplRegion == &aImplNullRegion )
+ return TRUE;
+
+ // is rectangle empty? -> nothing to do
+ if ( rRegion.mpImplRegion == &aImplEmptyRegion )
+ {
+ // statische Object haben RefCount von 0
+ if ( mpImplRegion->mnRefCount )
+ {
+ if ( mpImplRegion->mnRefCount > 1 )
+ mpImplRegion->mnRefCount--;
+ else
+ delete mpImplRegion;
+ }
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ return TRUE;
+ }
+
+ // is own region NULL-region? -> copy data!
+ if ( mpImplRegion == &aImplNullRegion)
+ {
+ mpImplRegion = rRegion.mpImplRegion;
+ rRegion.mpImplRegion->mnRefCount++;
+ return TRUE;
+ }
+
+ // Wenn wir weniger Rechtecke haben, drehen wir den Intersect-Aufruf um
+ if ( mpImplRegion->mnRectCount+2 < rRegion.mpImplRegion->mnRectCount )
+ {
+ Region aTempRegion = rRegion;
+ aTempRegion.Intersect( *this );
+ *this = aTempRegion;
+ }
+ else
+ {
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ // mark all bands as untouched
+ ImplRegionBand* pBand = mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ pBand->mbTouched = FALSE;
+ pBand = pBand->mpNextBand;
+ }
+
+ pBand = rRegion.mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ // insert bands if the boundaries are not allready in the list
+ mpImplRegion->InsertBands( pBand->mnYTop, pBand->mnYBottom );
+
+ // process all elements of the list
+ ImplRegionBandSep* pSep = pBand->mpFirstSep;
+ while ( pSep )
+ {
+ // left boundary?
+ if ( pSep == pBand->mpFirstSep )
+ {
+ // process intersection and do not remove untouched bands
+ mpImplRegion->Exclude( LONG_MIN+1, pBand->mnYTop,
+ pSep->mnXLeft-1, pBand->mnYBottom );
+ }
+
+ // right boundary?
+ if ( pSep->mpNextSep == NULL )
+ {
+ // process intersection and do not remove untouched bands
+ mpImplRegion->Exclude( pSep->mnXRight+1, pBand->mnYTop,
+ LONG_MAX-1, pBand->mnYBottom );
+ }
+ else
+ {
+ // process intersection and do not remove untouched bands
+ mpImplRegion->Exclude( pSep->mnXRight+1, pBand->mnYTop,
+ pSep->mpNextSep->mnXLeft-1, pBand->mnYBottom );
+ }
+
+ pSep = pSep->mpNextSep;
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+
+ // remove all untouched bands if bands allready left
+ ImplRegionBand* pPrevBand;
+ pBand = mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ if ( !pBand->mbTouched )
+ {
+ // save pointer
+ ImplRegionBand* pOldBand = pBand;
+
+ // previous element of the list
+ if ( pBand == mpImplRegion->mpFirstBand )
+ mpImplRegion->mpFirstBand = pBand->mpNextBand;
+ else
+ pPrevBand->mpNextBand = pBand->mpNextBand;
+
+ pBand = pBand->mpNextBand;
+ delete pOldBand;
+ }
+ else
+ {
+ pPrevBand = pBand;
+ pBand = pBand->mpNextBand;
+ }
+ }
+
+ // cleanup
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::Exclude( const Region& rRegion )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ ImplPolyPolyRegionToBandRegion();
+ ((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
+
+ // is region empty or null? -> nothing to do
+ if ( (rRegion.mpImplRegion == &aImplEmptyRegion) || (rRegion.mpImplRegion == &aImplNullRegion) )
+ return TRUE;
+
+ // no instance data? -> nothing to do
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return TRUE;
+
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ // Alle Rechtecke aus der uebergebenen Region auf diese Region anwenden
+ ImplRegionBand* pBand = rRegion.mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ // insert bands if the boundaries are not allready in the list
+ mpImplRegion->InsertBands( pBand->mnYTop, pBand->mnYBottom );
+
+ // process all elements of the list
+ ImplRegionBandSep* pSep = pBand->mpFirstSep;
+ while ( pSep )
+ {
+ mpImplRegion->Exclude( pSep->mnXLeft, pBand->mnYTop,
+ pSep->mnXRight, pBand->mnYBottom );
+ pSep = pSep->mpNextSep;
+ }
+
+ // Wir optimieren schon in der Schleife, da wir davon
+ // ausgehen, das wir insgesammt weniger Baender ueberpruefen
+ // muessen
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ break;
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::XOr( const Region& rRegion )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ ImplPolyPolyRegionToBandRegion();
+ ((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
+
+ // is region empty or null? -> nothing to do
+ if ( (rRegion.mpImplRegion == &aImplEmptyRegion) || (rRegion.mpImplRegion == &aImplNullRegion) )
+ return TRUE;
+
+ // no instance data? -> nothing to do
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return TRUE;
+
+ // no own instance data? -> make own copy!
+ if ( mpImplRegion->mnRefCount > 1 )
+ ImplCopyData();
+
+ // Alle Rechtecke aus der uebergebenen Region auf diese Region anwenden
+ ImplRegionBand* pBand = rRegion.mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ // insert bands if the boundaries are not allready in the list
+ mpImplRegion->InsertBands( pBand->mnYTop, pBand->mnYBottom );
+
+ // process all elements of the list
+ ImplRegionBandSep* pSep = pBand->mpFirstSep;
+ while ( pSep )
+ {
+ mpImplRegion->XOr( pSep->mnXLeft, pBand->mnYTop,
+ pSep->mnXRight, pBand->mnYBottom );
+ pSep = pSep->mpNextSep;
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+
+ // cleanup
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle Region::GetBoundRect() const
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ Rectangle aRect;
+
+ // no internal data? -> region is empty!
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return aRect;
+
+ // PolyPolygon data im Imp structure?
+ if ( mpImplRegion->mpPolyPoly )
+ return mpImplRegion->mpPolyPoly->GetBoundRect();
+
+ // no band in the list? -> region is empty!
+ if ( !mpImplRegion->mpFirstBand )
+ return aRect;
+
+ // get the boundaries of the first band
+ long nYTop = mpImplRegion->mpFirstBand->mnYTop;
+ long nYBottom = mpImplRegion->mpFirstBand->mnYBottom;
+ long nXLeft = mpImplRegion->mpFirstBand->GetXLeftBoundary();
+ long nXRight = mpImplRegion->mpFirstBand->GetXRightBoundary();
+
+ // look in the band list (don't test first band again!)
+ ImplRegionBand* pBand = mpImplRegion->mpFirstBand->mpNextBand;
+ while ( pBand )
+ {
+ nYBottom = pBand->mnYBottom;
+ nXLeft = Min( nXLeft, pBand->GetXLeftBoundary() );
+ nXRight = Max( nXRight, pBand->GetXRightBoundary() );
+
+ pBand = pBand->mpNextBand;
+ }
+
+ // set rectangle
+ aRect = Rectangle( nXLeft, nYTop, nXRight, nYBottom );
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::ImplGetFirstRect( ImplRegionInfo& rImplRegionInfo,
+ long& rX, long& rY,
+ long& rWidth, long& rHeight ) const
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ ((Region*)this)->ImplPolyPolyRegionToBandRegion();
+
+ // no internal data? -> region is empty!
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return FALSE;
+
+ // no band in the list? -> region is empty!
+ if ( mpImplRegion->mpFirstBand == NULL )
+ return FALSE;
+
+ // initialise pointer for first access
+ ImplRegionBand* pCurrRectBand = mpImplRegion->mpFirstBand;
+ ImplRegionBandSep* pCurrRectBandSep = pCurrRectBand->mpFirstSep;
+
+ DBG_ASSERT( pCurrRectBandSep != NULL, "Erstes Band wurde nicht optimiert." );
+ if ( !pCurrRectBandSep )
+ return FALSE;
+
+ // get boundaries of current rectangle
+ rX = pCurrRectBandSep->mnXLeft;
+ rY = pCurrRectBand->mnYTop;
+ rWidth = pCurrRectBandSep->mnXRight - pCurrRectBandSep->mnXLeft + 1;
+ rHeight = pCurrRectBand->mnYBottom - pCurrRectBand->mnYTop + 1;
+
+ // save pointers
+ rImplRegionInfo.mpVoidCurrRectBand = (void*)pCurrRectBand;
+ rImplRegionInfo.mpVoidCurrRectBandSep = (void*)pCurrRectBandSep;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::ImplGetNextRect( ImplRegionInfo& rImplRegionInfo,
+ long& rX, long& rY,
+ long& rWidth, long& rHeight ) const
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // no internal data? -> region is empty!
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return FALSE;
+
+ // get last pointers
+ ImplRegionBand* pCurrRectBand = (ImplRegionBand*)rImplRegionInfo.mpVoidCurrRectBand;
+ ImplRegionBandSep* pCurrRectBandSep = (ImplRegionBandSep*)rImplRegionInfo.mpVoidCurrRectBandSep;
+
+ // get next separation from current band
+ pCurrRectBandSep = pCurrRectBandSep->mpNextSep;
+
+ // no separation found? -> go to next band!
+ if ( !pCurrRectBandSep )
+ {
+ // get next band
+ pCurrRectBand = pCurrRectBand->mpNextBand;
+
+ // no band found? -> not further rectangles!
+ if( !pCurrRectBand )
+ return FALSE;
+
+ // get first separation in current band
+ pCurrRectBandSep = pCurrRectBand->mpFirstSep;
+ }
+
+ // get boundaries of current rectangle
+ rX = pCurrRectBandSep->mnXLeft;
+ rY = pCurrRectBand->mnYTop;
+ rWidth = pCurrRectBandSep->mnXRight - pCurrRectBandSep->mnXLeft + 1;
+ rHeight = pCurrRectBand->mnYBottom - pCurrRectBand->mnYTop + 1;
+
+ // save new pointers
+ rImplRegionInfo.mpVoidCurrRectBand = (void*)pCurrRectBand;
+ rImplRegionInfo.mpVoidCurrRectBandSep = (void*)pCurrRectBandSep;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+RegionType Region::GetType() const
+{
+ if ( mpImplRegion == &aImplEmptyRegion )
+ return REGION_EMPTY;
+ else if ( mpImplRegion == &aImplNullRegion )
+ return REGION_NULL;
+ else if ( mpImplRegion->mnRectCount == 1 )
+ return REGION_RECTANGLE;
+ else
+ return REGION_COMPLEX;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::IsInside( const Point& rPoint ) const
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // PolyPolygon data im Imp structure?
+ ((Region*)this)->ImplPolyPolyRegionToBandRegion();
+/*
+ if ( mpImplRegion->mpPolyPoly )
+ return mpImplRegion->mpPolyPoly->IsInside( rPoint );
+*/
+
+ // no instance data? -> not inside
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return FALSE;
+
+ // search band list
+ ImplRegionBand* pBand = mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ // is point within band?
+ if ( (pBand->mnYTop <= rPoint.Y()) &&
+ (pBand->mnYBottom >= rPoint.Y()) )
+ {
+ // is point within separation of the band?
+ if ( pBand->IsInside( rPoint.X() ) )
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::IsInside( const Rectangle& rRect ) const
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // is rectangle empty? -> not inside
+ if ( rRect.IsEmpty() )
+ return FALSE;
+
+ // no instance data? -> not inside
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return FALSE;
+
+ // create region from rectangle and intersect own region
+ Region aRegion = rRect;
+ aRegion.Exclude( *this );
+
+ // rectangle is inside if exclusion is empty
+ return aRegion.IsEmpty();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::IsOver( const Rectangle& rRect ) const
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return FALSE;
+
+ // Can we optimize this ??? - is used in StarDraw for brushes pointers
+ // Why we have no IsOver for Regions ???
+ // create region from rectangle and intersect own region
+ Region aRegion = rRect;
+ aRegion.Intersect( *this );
+
+ // rectangle is over if include is not empty
+ return !aRegion.IsEmpty();
+}
+
+// -----------------------------------------------------------------------
+
+void Region::SetNull()
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // statische Object haben RefCount von 0
+ if ( mpImplRegion->mnRefCount )
+ {
+ if ( mpImplRegion->mnRefCount > 1 )
+ mpImplRegion->mnRefCount--;
+ else
+ delete mpImplRegion;
+ }
+
+ // set new type
+ mpImplRegion = (ImplRegion*)(&aImplNullRegion);
+}
+
+// -----------------------------------------------------------------------
+
+void Region::SetEmpty()
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // statische Object haben RefCount von 0
+ if ( mpImplRegion->mnRefCount )
+ {
+ if ( mpImplRegion->mnRefCount > 1 )
+ mpImplRegion->mnRefCount--;
+ else
+ delete mpImplRegion;
+ }
+
+ // set new type
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+}
+
+// -----------------------------------------------------------------------
+
+Region& Region::operator=( const Region& rRegion )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+ DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
+ DBG_ASSERT( rRegion.mpImplRegion->mnRefCount < 0xFFFFFFFE, "Region: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ // RefCount == 0 fuer statische Objekte
+ if ( rRegion.mpImplRegion->mnRefCount )
+ rRegion.mpImplRegion->mnRefCount++;
+
+ // statische Object haben RefCount von 0
+ if ( mpImplRegion->mnRefCount )
+ {
+ if ( mpImplRegion->mnRefCount > 1 )
+ mpImplRegion->mnRefCount--;
+ else
+ delete mpImplRegion;
+ }
+
+ mpImplRegion = rRegion.mpImplRegion;
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Region& Region::operator=( const Rectangle& rRect )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // statische Object haben RefCount von 0
+ if ( mpImplRegion->mnRefCount )
+ {
+ if ( mpImplRegion->mnRefCount > 1 )
+ mpImplRegion->mnRefCount--;
+ else
+ delete mpImplRegion;
+ }
+
+ ImplCreateRectRegion( rRect );
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::operator==( const Region& rRegion ) const
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+ DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
+
+ // reference to same object? -> equal!
+ if ( mpImplRegion == rRegion.mpImplRegion )
+ return TRUE;
+
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return FALSE;
+
+ if ( (rRegion.mpImplRegion == &aImplEmptyRegion) || (rRegion.mpImplRegion == &aImplNullRegion) )
+ return FALSE;
+
+ if ( rRegion.mpImplRegion->mpPolyPoly && mpImplRegion->mpPolyPoly )
+ return *rRegion.mpImplRegion->mpPolyPoly == *mpImplRegion->mpPolyPoly;
+ else
+ {
+ ((Region*)this)->ImplPolyPolyRegionToBandRegion();
+ ((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
+
+ // Eine der beiden Regions kann jetzt Empty sein
+ if ( mpImplRegion == rRegion.mpImplRegion )
+ return TRUE;
+
+ if ( mpImplRegion == &aImplEmptyRegion )
+ return FALSE;
+
+ if ( rRegion.mpImplRegion == &aImplEmptyRegion )
+ return FALSE;
+ }
+
+ // initialise pointers
+ ImplRegionBand* pOwnRectBand = mpImplRegion->mpFirstBand;
+ ImplRegionBandSep* pOwnRectBandSep = pOwnRectBand->mpFirstSep;
+ ImplRegionBand* pSecondRectBand = rRegion.mpImplRegion->mpFirstBand;
+ ImplRegionBandSep* pSecondRectBandSep = pSecondRectBand->mpFirstSep;
+ while ( pOwnRectBandSep && pSecondRectBandSep )
+ {
+ // get boundaries of current rectangle
+ long nOwnXLeft = pOwnRectBandSep->mnXLeft;
+ long nSecondXLeft = pSecondRectBandSep->mnXLeft;
+ if ( nOwnXLeft != nSecondXLeft )
+ return FALSE;
+
+ long nOwnYTop = pOwnRectBand->mnYTop;
+ long nSecondYTop = pSecondRectBand->mnYTop;
+ if ( nOwnYTop != nSecondYTop )
+ return FALSE;
+
+ long nOwnXRight = pOwnRectBandSep->mnXRight;
+ long nSecondXRight = pSecondRectBandSep->mnXRight;
+ if ( nOwnXRight != nSecondXRight )
+ return FALSE;
+
+ long nOwnYBottom = pOwnRectBand->mnYBottom;
+ long nSecondYBottom = pSecondRectBand->mnYBottom;
+ if ( nOwnYBottom != nSecondYBottom )
+ return FALSE;
+
+ // get next separation from current band
+ pOwnRectBandSep = pOwnRectBandSep->mpNextSep;
+
+ // no separation found? -> go to next band!
+ if ( !pOwnRectBandSep )
+ {
+ // get next band
+ pOwnRectBand = pOwnRectBand->mpNextBand;
+
+ // get first separation in current band
+ if( pOwnRectBand )
+ pOwnRectBandSep = pOwnRectBand->mpFirstSep;
+ }
+
+ // get next separation from current band
+ pSecondRectBandSep = pSecondRectBandSep->mpNextSep;
+
+ // no separation found? -> go to next band!
+ if ( !pSecondRectBandSep )
+ {
+ // get next band
+ pSecondRectBand = pSecondRectBand->mpNextBand;
+
+ // get first separation in current band
+ if( pSecondRectBand )
+ pSecondRectBandSep = pSecondRectBand->mpFirstSep;
+ }
+
+ if ( pOwnRectBandSep && !pSecondRectBandSep )
+ return FALSE;
+
+ if ( !pOwnRectBandSep && pSecondRectBandSep )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+enum StreamEntryType { STREAMENTRY_BANDHEADER, STREAMENTRY_SEPARATION, STREAMENTRY_END };
+
+SvStream& operator>>( SvStream& rIStrm, Region& rRegion )
+{
+ DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
+
+ VersionCompat aCompat( rIStrm, STREAM_READ );
+ UINT16 nVersion;
+ UINT16 nTmp16;
+
+ // statische Object haben RefCount von 0
+ if ( rRegion.mpImplRegion->mnRefCount )
+ {
+ if ( rRegion.mpImplRegion->mnRefCount > 1 )
+ rRegion.mpImplRegion->mnRefCount--;
+ else
+ delete rRegion.mpImplRegion;
+ }
+
+ // get version of streamed region
+ rIStrm >> nVersion;
+
+ // get type of region
+ rIStrm >> nTmp16;
+
+ RegionType meStreamedType = (RegionType)nTmp16;
+
+ switch( meStreamedType )
+ {
+ case REGION_NULL:
+ rRegion.mpImplRegion = (ImplRegion*)&aImplNullRegion;
+ break;
+
+ case REGION_EMPTY:
+ rRegion.mpImplRegion = (ImplRegion*)&aImplEmptyRegion;
+ break;
+
+ default:
+ // create instance of implementation class
+ rRegion.mpImplRegion = new ImplRegion();
+
+ // get header from first element
+ rIStrm >> nTmp16;
+
+ // get all bands
+ rRegion.mpImplRegion->mnRectCount = 0;
+ ImplRegionBand* pCurrBand = NULL;
+ while ( (StreamEntryType)nTmp16 != STREAMENTRY_END )
+ {
+ // insert new band or new separation?
+ if ( (StreamEntryType)nTmp16 == STREAMENTRY_BANDHEADER )
+ {
+ long nYTop;
+ long nYBottom;
+
+ rIStrm >> nYTop;
+ rIStrm >> nYBottom;
+
+ // create band
+ ImplRegionBand* pNewBand = new ImplRegionBand( nYTop, nYBottom );
+
+ // first element? -> set as first into the list
+ if ( !pCurrBand )
+ rRegion.mpImplRegion->mpFirstBand = pNewBand;
+ else
+ pCurrBand->mpNextBand = pNewBand;
+
+ // save pointer for next creation
+ pCurrBand = pNewBand;
+ }
+ else
+ {
+ long nXLeft;
+ long nXRight;
+
+ rIStrm >> nXLeft;
+ rIStrm >> nXRight;
+
+ // add separation
+ if ( pCurrBand )
+ {
+ pCurrBand->Union( nXLeft, nXRight );
+ rRegion.mpImplRegion->mnRectCount++;
+ }
+ }
+
+ // get next header
+ rIStrm >> nTmp16;
+ }
+ break;
+ }
+
+ return rIStrm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStrm, const Region& rRegion )
+{
+ DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
+
+ VersionCompat aCompat( rOStrm, STREAM_WRITE );
+ UINT16 nVersion = 1;
+
+ ((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
+
+ // put version
+ rOStrm << nVersion;
+
+ // put type
+ rOStrm << (UINT16)rRegion.GetType();
+
+ // put all bands if not null or empty
+ if ( (rRegion.mpImplRegion != &aImplEmptyRegion) && (rRegion.mpImplRegion != &aImplNullRegion) )
+ {
+ ImplRegionBand* pBand = rRegion.mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ // put boundaries
+ rOStrm << (UINT16) STREAMENTRY_BANDHEADER;
+ rOStrm << pBand->mnYTop;
+ rOStrm << pBand->mnYBottom;
+
+ // put separations of current band
+ ImplRegionBandSep* pSep = pBand->mpFirstSep;
+ while ( pSep )
+ {
+ // put separation
+ rOStrm << (UINT16) STREAMENTRY_SEPARATION;
+ rOStrm << pSep->mnXLeft;
+ rOStrm << pSep->mnXRight;
+
+ // next separation from current band
+ pSep = pSep->mpNextSep;
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+
+ // put endmarker
+ rOStrm << (UINT16) STREAMENTRY_END;
+ }
+
+ return rOStrm;
+}
+
+// -----------------------------------------------------------------------
+
+RegionOverlapType Region::GetOverlapType( const Rectangle& rRect ) const
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // is rectangle empty? -> not inside
+ if ( rRect.IsEmpty() )
+ return REGION_OUTSIDE;
+
+ ((Region*)this)->ImplPolyPolyRegionToBandRegion();
+
+ // no instance data? -> not inside
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return REGION_OUTSIDE;
+
+ // resolve pointer
+ ImplRegionBand* pBand = mpImplRegion->mpFirstBand;
+ ImplRegionBandSep* pSep = pBand->mpFirstSep;
+
+ // complex region? don't check for now. This may change in the future...
+ if ( pBand->mpNextBand || pSep->mpNextSep )
+ return REGION_OVER;
+
+ // get justified rectangle
+ long nLeft = Min( rRect.Left(), rRect.Right() );
+ long nTop = Min( rRect.Top(), rRect.Bottom() );
+ long nRight = Max( rRect.Left(), rRect.Right() );
+ long nBottom = Max( rRect.Top(), rRect.Bottom() );
+
+ // check rectangle region
+ BOOL boLeft = (nLeft >= pSep->mnXLeft) && (nLeft < pSep->mnXRight);
+ BOOL boRight = (nRight <= pSep->mnXRight) && (nRight > pSep->mnXLeft);
+ BOOL boTop = (nTop >= pBand->mnYTop) && (nTop < pBand->mnYBottom);
+ BOOL boBottom = (nBottom <= pBand->mnYBottom) && (nBottom > pBand->mnYTop);
+ if ( boLeft && boRight && boTop && boBottom )
+ return REGION_INSIDE;
+ if ( boLeft || boRight || boTop || boBottom )
+ return REGION_OVER;
+
+ return REGION_OUTSIDE;
+}
+
+// -----------------------------------------------------------------------
+
+void Region::ImplBeginAddRect()
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ // statische Object haben RefCount von 0
+ if ( mpImplRegion->mnRefCount )
+ {
+ if ( mpImplRegion->mnRefCount > 1 )
+ mpImplRegion->mnRefCount--;
+ else
+ delete mpImplRegion;
+ }
+
+ // create fresh region
+ mpImplRegion = new ImplRegion();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::ImplAddRect( const Rectangle& rRect )
+{
+ // Hier kein CheckThis, da nicht alle Daten auf Stand
+
+ if ( rRect.IsEmpty() )
+ return TRUE;
+
+ // get justified rectangle
+ long nTop;
+ long nBottom;
+ long nLeft;
+ long nRight;
+ if ( rRect.Top() <= rRect.Bottom() )
+ {
+ nTop = rRect.Top();
+ nBottom = rRect.Bottom();
+ }
+ else
+ {
+ nTop = rRect.Bottom();
+ nBottom = rRect.Top();
+ }
+ if ( rRect.Left() <= rRect.Right() )
+ {
+ nLeft = rRect.Left();
+ nRight = rRect.Right();
+ }
+ else
+ {
+ nLeft = rRect.Right();
+ nRight = rRect.Left();
+ }
+
+ if ( !mpImplRegion->mpLastCheckedBand )
+ {
+ // create new band
+ mpImplRegion->mpLastCheckedBand = new ImplRegionBand( nTop, nBottom );
+
+ // set band as current
+ mpImplRegion->mpFirstBand = mpImplRegion->mpLastCheckedBand;
+ mpImplRegion->mpLastCheckedBand->Union( nLeft, nRight );
+ }
+ else
+ {
+ DBG_ASSERT( nTop >= mpImplRegion->mpLastCheckedBand->mnYTop,
+ "Region::ImplAddRect() - nTopY < nLastTopY" );
+
+ // new band? create it!
+ if ( (nTop != mpImplRegion->mpLastCheckedBand->mnYTop) ||
+ (nBottom != mpImplRegion->mpLastCheckedBand->mnYBottom) )
+ {
+ // create new band
+ ImplRegionBand* pNewRegionBand = new ImplRegionBand( nTop, nBottom );
+
+ // append band to the end
+ mpImplRegion->mpLastCheckedBand->mpNextBand = pNewRegionBand;
+
+ // skip to the new band
+ mpImplRegion->mpLastCheckedBand = mpImplRegion->mpLastCheckedBand->mpNextBand;
+ }
+
+ // Insert Sep
+ mpImplRegion->mpLastCheckedBand->Union( nLeft, nRight );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Region::ImplEndAddRect()
+{
+ // check if we are empty
+ if ( !mpImplRegion->mpFirstBand )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ return;
+ }
+
+ // check if we have somthing to optimize
+ if ( !mpImplRegion->mpFirstBand->mpNextBand )
+ {
+ // update mpImplRegion->mnRectCount, because no OptimizeBandList is called
+ ImplRegionBandSep* pSep = mpImplRegion->mpFirstBand->mpFirstSep;
+ mpImplRegion->mnRectCount = 0;
+ while( pSep )
+ {
+ mpImplRegion->mnRectCount++;
+ pSep = pSep->mpNextSep;
+ }
+
+ // Erst hier testen, da hier die Daten wieder stimmen
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+ return;
+ }
+
+ // have to revert list? -> do it now!
+ if ( mpImplRegion->mpFirstBand->mnYTop >
+ mpImplRegion->mpFirstBand->mpNextBand->mnYTop )
+ {
+ ImplRegionBand * pNewFirstRegionBand;
+
+ // initialize temp list with first element
+ pNewFirstRegionBand = mpImplRegion->mpFirstBand;
+ mpImplRegion->mpFirstBand = mpImplRegion->mpFirstBand->mpNextBand;
+ pNewFirstRegionBand->mpNextBand = NULL;
+
+ // insert elements to the temp list
+ while ( mpImplRegion->mpFirstBand )
+ {
+ ImplRegionBand * pSavedRegionBand = pNewFirstRegionBand;
+ pNewFirstRegionBand = mpImplRegion->mpFirstBand;
+ mpImplRegion->mpFirstBand = mpImplRegion->mpFirstBand->mpNextBand;
+ pNewFirstRegionBand->mpNextBand = pSavedRegionBand;
+ }
+
+ // set temp list as new list
+ mpImplRegion->mpFirstBand = pNewFirstRegionBand;
+ }
+
+ // cleanup
+ if ( !mpImplRegion->OptimizeBandList() )
+ {
+ delete mpImplRegion;
+ mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
+ }
+
+ // Erst hier testen, da hier die Daten wieder stimmen
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Region::GetRectCount() const
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ ((Region*)this)->ImplPolyPolyRegionToBandRegion();
+
+#ifdef DBG_UTIL
+ ULONG nCount = 0;
+
+ // all bands if not null or empty
+ if ( (mpImplRegion != &aImplEmptyRegion) && (mpImplRegion != &aImplNullRegion) )
+ {
+ ImplRegionBand* pBand = mpImplRegion->mpFirstBand;
+ while ( pBand )
+ {
+ ImplRegionBandSep* pSep = pBand->mpFirstSep;
+ while( pSep )
+ {
+ nCount++;
+ pSep = pSep->mpNextSep;
+ }
+
+ pBand = pBand->mpNextBand;
+ }
+ }
+
+ DBG_ASSERT( mpImplRegion->mnRectCount == nCount, "Region: invalid mnRectCount!" );
+#endif
+
+ return mpImplRegion->mnRectCount;
+}
+
+// -----------------------------------------------------------------------
+
+RegionHandle Region::BeginEnumRects()
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ ImplPolyPolyRegionToBandRegion();
+
+ // no internal data? -> region is empty!
+ if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
+ return NULL;
+
+ // no band in the list? -> region is empty!
+ if ( mpImplRegion->mpFirstBand == NULL )
+ {
+ DBG_ASSERT( mpImplRegion->mpFirstBand, "Region::BeginEnumRects() First Band is Empty!" );
+ return NULL;
+ }
+
+ ImplRegionHandle* pData = new ImplRegionHandle;
+ pData->mpRegion = new Region( *this );
+ pData->mbFirst = TRUE;
+
+ // save pointers
+ pData->mpCurrRectBand = pData->mpRegion->mpImplRegion->mpFirstBand;
+ pData->mpCurrRectBandSep = pData->mpCurrRectBand->mpFirstSep;
+
+ return (RegionHandle)pData;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Region::GetEnumRects( RegionHandle pVoidData, Rectangle& rRect )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ ImplRegionHandle* pData = (ImplRegionHandle*)pVoidData;
+ if ( !pData )
+ return FALSE;
+
+ if ( pData->mbFirst )
+ pData->mbFirst = FALSE;
+ else
+ {
+ // get next separation from current band
+ pData->mpCurrRectBandSep = pData->mpCurrRectBandSep->mpNextSep;
+
+ // no separation found? -> go to next band!
+ if ( !pData->mpCurrRectBandSep )
+ {
+ // get next band
+ pData->mpCurrRectBand = pData->mpCurrRectBand->mpNextBand;
+
+ // no band found? -> not further rectangles!
+ if ( !pData->mpCurrRectBand )
+ return FALSE;
+
+ // get first separation in current band
+ pData->mpCurrRectBandSep = pData->mpCurrRectBand->mpFirstSep;
+ }
+ }
+
+ // get boundaries of current rectangle
+ rRect.Top() = pData->mpCurrRectBand->mnYTop;
+ rRect.Bottom() = pData->mpCurrRectBand->mnYBottom;
+ rRect.Left() = pData->mpCurrRectBandSep->mnXLeft;
+ rRect.Right() = pData->mpCurrRectBandSep->mnXRight;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Region::EndEnumRects( RegionHandle pVoidData )
+{
+ DBG_CHKTHIS( Region, ImplDbgTestRegion );
+
+ ImplRegionHandle* pData = (ImplRegionHandle*)pVoidData;
+ if ( !pData )
+ return;
+
+ // cleanup
+ delete pData->mpRegion;
+ delete pData;
+}
diff --git a/vcl/source/gdi/salmisc.cxx b/vcl/source/gdi/salmisc.cxx
new file mode 100644
index 000000000000..50af07d0eda9
--- /dev/null
+++ b/vcl/source/gdi/salmisc.cxx
@@ -0,0 +1,497 @@
+/*************************************************************************
+ *
+ * $RCSfile: salmisc.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+#include <bmpacc.hxx>
+#include <salbtype.hxx>
+
+// -----------
+// - Defines -
+// -----------
+
+#define IMPL_CASE_GET_FORMAT( Format ) \
+case( BMP_FORMAT##Format ): \
+ pFncGetPixel = BitmapReadAccess::GetPixelFor##Format; \
+break
+
+// -----------------------------------------------------------------------------
+
+#define IMPL_CASE_SET_FORMAT( Format, BitCount ) \
+case( BMP_FORMAT##Format ): \
+{ \
+ pFncSetPixel = BitmapReadAccess::SetPixelFor##Format; \
+ pDstBuffer->mnBitCount = BitCount; \
+} \
+break
+
+// -----------------------------------------------------------------------------
+
+#define DOUBLE_SCANLINES() \
+while( ( nActY < nHeight1 ) && ( pMapY[ nActY + 1 ] == nMapY ) ) \
+{ \
+ HMEMCPY( pDstScanMap[ nActY + 1L ], pDstScan, rDstBuffer.mnScanlineSize ); \
+ nActY++; \
+}
+
+// -----------
+// - Inlines -
+// -----------
+
+#define TC_TO_PAL_COLORS 4096
+
+static long ImplIndexFromColor( const BitmapColor& rCol )
+{
+#if TC_TO_PAL_COLORS == 4096
+
+ return( ( ( (long) rCol.GetBlue() >> 4L) << 8L ) |
+ ( ( (long) rCol.GetGreen() >> 4L ) << 4L ) |
+ ( (long) rCol.GetRed() >> 4L ) );
+
+#elif TC_TO_PAL_COLORS == 32768
+
+ return( ( ( (long) rCol.GetBlue() >> 3L) << 10L ) |
+ ( ( (long) rCol.GetGreen() >> 3L ) << 5L ) |
+ ( (long) rCol.GetRed() >> 3L ) );
+
+#endif
+}
+
+
+#define COLOR_TO_INDEX( _def_rCol )
+
+// ------------------------
+// - conversion functions -
+// ------------------------
+
+static void ImplPALToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
+ FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
+ Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
+{
+ const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
+ const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
+ const ColorMask& rDstMask = rDstBuffer.maColorMask;
+ BitmapPalette aColMap( rSrcBuffer.maPalette.GetEntryCount() );
+ BitmapColor* pColMapBuf = aColMap.ImplGetColorBuffer();
+ BitmapColor aIndex( 0 );
+
+ for( USHORT i = 0, nCount = aColMap.GetEntryCount(); i < nCount; i++ )
+ {
+ if( rSrcBuffer.maPalette[ i ] == rDstBuffer.maPalette[ i ] )
+ aIndex.SetIndex( i );
+ else
+ aIndex.SetIndex( rDstBuffer.maPalette.GetBestIndex( rSrcBuffer.maPalette[ i ] ) );
+
+ pColMapBuf[ i ] = aIndex;
+ }
+
+ for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
+ {
+ Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pFncSetPixel( pDstScan, nX, pColMapBuf[ pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ).GetIndex() ], rDstMask );
+
+ DOUBLE_SCANLINES();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static void ImplPALToTC( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
+ FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
+ Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
+{
+ const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
+ const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
+ const ColorMask& rDstMask = rDstBuffer.maColorMask;
+ const BitmapColor* pColBuf = rSrcBuffer.maPalette.ImplGetColorBuffer();
+
+ if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_1BIT_MSB_PAL )
+ {
+ const BitmapColor aCol0( pColBuf[ 0 ] );
+ const BitmapColor aCol1( pColBuf[ 1 ] );
+ long nMapX;
+
+ for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
+ {
+ Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
+
+ for( long nX = 0L; nX < nWidth; )
+ {
+ nMapX = pMapX[ nX ];
+ pFncSetPixel( pDstScan, nX++,
+ pSrcScan[ nMapX >> 3 ] & ( 1 << ( 7 - ( nMapX & 7 ) ) ) ? aCol1 : aCol0,
+ rDstMask );
+ }
+
+ DOUBLE_SCANLINES();
+ }
+ }
+ else if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_4BIT_MSN_PAL )
+ {
+ long nMapX;
+
+ for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
+ {
+ Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
+
+ for( long nX = 0L; nX < nWidth; )
+ {
+ nMapX = pMapX[ nX ];
+ pFncSetPixel( pDstScan, nX++,
+ pColBuf[ ( pSrcScan[ nMapX >> 1 ] >> ( nMapX & 1 ? 0 : 4 ) ) & 0x0f ],
+ rDstMask );
+ }
+
+ DOUBLE_SCANLINES();
+ }
+ }
+ else if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_8BIT_PAL )
+ {
+ for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
+ {
+ Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pFncSetPixel( pDstScan, nX, pColBuf[ pSrcScan[ pMapX[ nX ] ] ], rDstMask );
+
+ DOUBLE_SCANLINES();
+ }
+ }
+ else
+ {
+ for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
+ {
+ Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pFncSetPixel( pDstScan, nX, pColBuf[ pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ).GetIndex() ], rDstMask );
+
+ DOUBLE_SCANLINES();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static void ImplTCToTC( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
+ FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
+ Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
+{
+ const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
+ const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
+ const ColorMask& rDstMask = rDstBuffer.maColorMask;
+
+ if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_24BIT_TC_BGR )
+ {
+ BitmapColor aCol;
+ BYTE* pPixel;
+
+ for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
+ {
+ Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aCol.SetBlue( *( pPixel = ( pSrcScan + pMapX[ nX ] * 3 ) )++ );
+ aCol.SetGreen( *pPixel++ );
+ aCol.SetRed( *pPixel );
+ pFncSetPixel( pDstScan, nX, aCol, rDstMask );
+ }
+
+ DOUBLE_SCANLINES()
+ }
+ }
+ else
+ {
+ for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
+ {
+ Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ pFncSetPixel( pDstScan, nX, pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ), rDstMask );
+
+ DOUBLE_SCANLINES();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static void ImplTCToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
+ FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
+ Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
+{
+ const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
+ const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
+ const ColorMask& rDstMask = rDstBuffer.maColorMask;
+ BitmapPalette aColMap( rSrcBuffer.maPalette.GetEntryCount() );
+ BYTE* pColToPalMap = new BYTE[ TC_TO_PAL_COLORS ];
+ BitmapColor aIndex( 0 );
+
+ for( long nR = 0; nR < 16; nR++ )
+ {
+ for( long nG = 0; nG < 16; nG++ )
+ {
+ for( long nB = 0; nB < 16; nB++ )
+ {
+ BitmapColor aCol( nR << 4, nG << 4, nB << 4 );
+ pColToPalMap[ ImplIndexFromColor( aCol ) ] = (BYTE) rDstBuffer.maPalette.GetBestIndex( aCol );
+ }
+ }
+ }
+
+ for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
+ {
+ Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
+
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ aIndex.SetIndex( pColToPalMap[ ImplIndexFromColor( pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ) ) ] );
+ pFncSetPixel( pDstScan, nX, aIndex, rDstMask );
+ }
+
+ DOUBLE_SCANLINES();
+ }
+
+ delete[] pColToPalMap;
+}
+
+// ---------------------
+// - StretchAndConvert -
+// ---------------------
+
+BitmapBuffer* StretchAndConvert( const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect,
+ ULONG nDstBitmapFormat, BitmapPalette* pDstPal, ColorMask* pDstMask )
+{
+ FncGetPixel pFncGetPixel;
+ FncSetPixel pFncSetPixel;
+ BitmapBuffer* pDstBuffer = new BitmapBuffer;
+ const ULONG nDstScanlineFormat = BMP_SCANLINE_FORMAT( nDstBitmapFormat );
+ const long nSrcX = rTwoRect.mnSrcX, nSrcY = rTwoRect.mnSrcY;
+ const long nSrcDX = rTwoRect.mnSrcWidth, nSrcDY = rTwoRect.mnSrcHeight;
+ const long nDstDX = rTwoRect.mnDestWidth, nDstDY = rTwoRect.mnDestHeight;
+ Scanline* pSrcScan = new Scanline[ rSrcBuffer.mnHeight ];
+ Scanline* pDstScan = new Scanline[ nDstDY ];
+ long* pMapX = new long[ nDstDX ];
+ long* pMapY = new long[ nDstDY ];
+ Scanline pTmpScan;
+ long i, nTmp, nOffset;
+
+ // set function for getting pixels
+ switch( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) )
+ {
+ IMPL_CASE_GET_FORMAT( _1BIT_MSB_PAL );
+ IMPL_CASE_GET_FORMAT( _1BIT_LSB_PAL );
+ IMPL_CASE_GET_FORMAT( _4BIT_MSN_PAL );
+ IMPL_CASE_GET_FORMAT( _4BIT_LSN_PAL );
+ IMPL_CASE_GET_FORMAT( _8BIT_PAL );
+ IMPL_CASE_GET_FORMAT( _8BIT_TC_MASK );
+ IMPL_CASE_GET_FORMAT( _16BIT_TC_MASK );
+ IMPL_CASE_GET_FORMAT( _24BIT_TC_BGR );
+ IMPL_CASE_GET_FORMAT( _24BIT_TC_RGB );
+ IMPL_CASE_GET_FORMAT( _24BIT_TC_MASK );
+ IMPL_CASE_GET_FORMAT( _32BIT_TC_ABGR );
+ IMPL_CASE_GET_FORMAT( _32BIT_TC_ARGB );
+ IMPL_CASE_GET_FORMAT( _32BIT_TC_BGRA );
+ IMPL_CASE_GET_FORMAT( _32BIT_TC_RGBA );
+ IMPL_CASE_GET_FORMAT( _32BIT_TC_MASK );
+
+ default:
+ DBG_ERROR( "unknown read format" );
+ break;
+ }
+
+ // set function for setting pixels
+ switch( nDstScanlineFormat )
+ {
+ IMPL_CASE_SET_FORMAT( _1BIT_MSB_PAL, 1 );
+ IMPL_CASE_SET_FORMAT( _1BIT_LSB_PAL, 1 );
+ IMPL_CASE_SET_FORMAT( _4BIT_MSN_PAL, 1 );
+ IMPL_CASE_SET_FORMAT( _4BIT_LSN_PAL, 4 );
+ IMPL_CASE_SET_FORMAT( _8BIT_PAL, 8 );
+ IMPL_CASE_SET_FORMAT( _8BIT_TC_MASK, 8 );
+ IMPL_CASE_SET_FORMAT( _16BIT_TC_MASK, 16 );
+ IMPL_CASE_SET_FORMAT( _24BIT_TC_BGR, 24 );
+ IMPL_CASE_SET_FORMAT( _24BIT_TC_RGB, 24 );
+ IMPL_CASE_SET_FORMAT( _24BIT_TC_MASK, 24 );
+ IMPL_CASE_SET_FORMAT( _32BIT_TC_ABGR, 32 );
+ IMPL_CASE_SET_FORMAT( _32BIT_TC_ARGB, 32 );
+ IMPL_CASE_SET_FORMAT( _32BIT_TC_BGRA, 32 );
+ IMPL_CASE_SET_FORMAT( _32BIT_TC_RGBA, 32 );
+ IMPL_CASE_SET_FORMAT( _32BIT_TC_MASK, 32 );
+
+ default:
+ DBG_ERROR( "unknown write format" );
+ break;
+ }
+
+ // fill destination buffer
+ pDstBuffer->mnFormat = nDstBitmapFormat;
+ pDstBuffer->mnWidth = nDstDX;
+ pDstBuffer->mnHeight = nDstDY;
+ pDstBuffer->mnScanlineSize = AlignedWidth4Bytes( pDstBuffer->mnBitCount * nDstDX );
+ pDstBuffer->mpBits = new BYTE[ pDstBuffer->mnScanlineSize * nDstDY ];
+ rtl_zeroMemory( pDstBuffer->mpBits, pDstBuffer->mnScanlineSize * nDstDY );
+
+ // do we need a destination palette or color mask?
+ if( ( nDstScanlineFormat == BMP_FORMAT_1BIT_MSB_PAL ) ||
+ ( nDstScanlineFormat == BMP_FORMAT_1BIT_LSB_PAL ) ||
+ ( nDstScanlineFormat == BMP_FORMAT_4BIT_MSN_PAL ) ||
+ ( nDstScanlineFormat == BMP_FORMAT_4BIT_LSN_PAL ) ||
+ ( nDstScanlineFormat == BMP_FORMAT_8BIT_PAL ) )
+ {
+ DBG_ASSERT( pDstPal, "destination buffer requires palette" );
+ pDstBuffer->maPalette = *pDstPal;
+ }
+ else if( ( nDstScanlineFormat == BMP_FORMAT_8BIT_TC_MASK ) ||
+ ( nDstScanlineFormat == BMP_FORMAT_16BIT_TC_MASK ) ||
+ ( nDstScanlineFormat == BMP_FORMAT_24BIT_TC_MASK ) ||
+ ( nDstScanlineFormat == BMP_FORMAT_32BIT_TC_MASK ) )
+ {
+ DBG_ASSERT( pDstMask, "destination buffer requires color mask" );
+ pDstBuffer->maColorMask = *pDstMask;
+ }
+
+ // horizontal mapping table
+ if( nDstDX != nSrcDX )
+ {
+ const double fFactorX = ( nDstDX > 1 ) ? (double) ( nSrcDX - 1 ) / ( nDstDX - 1 ) : 0.0;
+
+ for( i = 0L; i < nDstDX; i++ )
+ pMapX[ i ] = nSrcX + FRound( i * fFactorX );
+ }
+ else
+ {
+ for( i = 0L, nTmp = nSrcX; i < nDstDX; i++ )
+ pMapX[ i ] = nTmp++;
+ }
+
+ // vertical mapping table
+ if( nDstDY != nSrcDY )
+ {
+ const double fFactorY = ( nDstDY > 1 ) ? (double) ( nSrcDY - 1 ) / ( nDstDY - 1 ) : 0.0;
+
+ for( i = 0L; i < nDstDY; i++ )
+ pMapY[ i ] = nSrcY + FRound( i * fFactorY );
+ }
+ else
+ {
+ for( i = 0L, nTmp = nSrcY; i < nDstDY; i++ )
+ pMapY[ i ] = nTmp++;
+ }
+
+ // source scanline buffer
+ if( BMP_SCANLINE_ADJUSTMENT( rSrcBuffer.mnFormat ) == BMP_FORMAT_TOP_DOWN )
+ pTmpScan = rSrcBuffer.mpBits, nOffset = rSrcBuffer.mnScanlineSize;
+ else
+ {
+ pTmpScan = rSrcBuffer.mpBits + ( rSrcBuffer.mnHeight - 1 ) * rSrcBuffer.mnScanlineSize;
+ nOffset = -rSrcBuffer.mnScanlineSize;
+ }
+
+ for( i = 0L; i < rSrcBuffer.mnHeight; i++, pTmpScan += nOffset )
+ pSrcScan[ i ] = pTmpScan;
+
+ // destination scanline buffer
+ if( BMP_SCANLINE_ADJUSTMENT( pDstBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
+ pTmpScan = pDstBuffer->mpBits, nOffset = pDstBuffer->mnScanlineSize;
+ else
+ {
+ pTmpScan = pDstBuffer->mpBits + ( nDstDY - 1 ) * pDstBuffer->mnScanlineSize;
+ nOffset = -pDstBuffer->mnScanlineSize;
+ }
+
+ for( i = 0L; i < nDstDY; i++, pTmpScan += nOffset )
+ pDstScan[ i ] = pTmpScan;
+
+ // do buffer scaling and conversion
+ if( rSrcBuffer.mnBitCount <= 8 && pDstBuffer->mnBitCount <= 8 )
+ {
+ ImplPALToPAL( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
+ pSrcScan, pDstScan, pMapX, pMapY );
+ }
+ else if( rSrcBuffer.mnBitCount <= 8 && pDstBuffer->mnBitCount > 8 )
+ {
+ ImplPALToTC( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
+ pSrcScan, pDstScan, pMapX, pMapY );
+ }
+ else if( rSrcBuffer.mnBitCount > 8 && pDstBuffer->mnBitCount > 8 )
+ {
+ ImplTCToTC( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
+ pSrcScan, pDstScan, pMapX, pMapY );
+ }
+ else
+ {
+ ImplTCToPAL( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
+ pSrcScan, pDstScan, pMapX, pMapY );
+ }
+
+ // cleanup
+ delete[] pSrcScan;
+ delete[] pDstScan;
+ delete[] pMapX;
+ delete[] pMapY;
+
+ return pDstBuffer;
+}
diff --git a/vcl/source/gdi/svcompat.cxx b/vcl/source/gdi/svcompat.cxx
new file mode 100644
index 000000000000..dc037185e064
--- /dev/null
+++ b/vcl/source/gdi/svcompat.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * $RCSfile: svcompat.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_COMPAT_CXX
+
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+
+#ifndef _SV_SVCOMPAT_HXX
+#include <svcompat.hxx>
+#endif
+
+// --------------
+// - ImplCompat -
+// --------------
+
+ImplCompat::ImplCompat( SvStream& rStm, USHORT nStreamMode, USHORT nVersion ) :
+ mpRWStm ( &rStm ),
+ mnStmMode ( nStreamMode ),
+ mnVersion ( nVersion )
+{
+ if( !mpRWStm->GetError() )
+ {
+ if( STREAM_WRITE == mnStmMode )
+ {
+ *mpRWStm << mnVersion;
+ mnTotalSize = ( mnCompatPos = mpRWStm->Tell() ) + 4UL;
+ mpRWStm->SeekRel( 4L );
+ }
+ else
+ {
+ *mpRWStm >> mnVersion;
+ *mpRWStm >> mnTotalSize;
+ mnCompatPos = mpRWStm->Tell();
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ImplCompat::~ImplCompat()
+{
+ if( STREAM_WRITE == mnStmMode )
+ {
+ const UINT32 nEndPos = mpRWStm->Tell();
+
+ mpRWStm->Seek( mnCompatPos );
+ *mpRWStm << ( nEndPos - mnTotalSize );
+ mpRWStm->Seek( nEndPos );
+ }
+ else
+ {
+ const UINT32 nReadSize = mpRWStm->Tell() - mnCompatPos;
+
+ if( mnTotalSize > nReadSize )
+ mpRWStm->SeekRel( mnTotalSize - nReadSize );
+ }
+}
diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx
new file mode 100644
index 000000000000..ff8c7268c9fe
--- /dev/null
+++ b/vcl/source/gdi/virdev.cxx
@@ -0,0 +1,442 @@
+/*************************************************************************
+ *
+ * $RCSfile: virdev.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_VIRDEV_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+
+using namespace ::com::sun::star::uno;
+
+// appserver
+#ifdef REMOTE_APPSERVER
+#ifndef _SV_RMOUTDEV_HXX
+#include <rmoutdev.hxx>
+#endif
+#ifndef _SV_RMVIRDEV_HXX
+#include <rmvirdev.hxx>
+#endif
+#ifndef _VCL_RMCACHE_HXX_
+#include <rmcache.hxx>
+#endif
+#endif
+
+// =======================================================================
+
+// interface cache
+#ifdef REMOTE_APPSERVER
+
+static ::vcl::InterfacePairCache< ::com::sun::star::portal::client::XRmVirtualDevice, ::com::sun::star::portal::client::XRmOutputDevice >* pRemoteVirdevCache = NULL;
+
+typedef ::std::pair< ::com::sun::star::uno::Reference< ::com::sun::star::portal::client::XRmVirtualDevice >, ::com::sun::star::uno::Reference< ::com::sun::star::portal::client::XRmOutputDevice > > virdevInterfacePair;
+
+void eraseRemoteVirdevCache()
+{
+ if( pRemoteVirdevCache )
+ {
+ delete pRemoteVirdevCache;
+ pRemoteVirdevCache = NULL;
+ }
+}
+
+#endif
+
+// =======================================================================
+
+void VirtualDevice::ImplInitVirDev( const OutputDevice* pOutDev,
+ long nDX, long nDY, USHORT nBitCount )
+{
+ DBG_ASSERT( nBitCount <= 1,
+ "VirtualDevice::VirtualDevice(): Only 0 or 1 is for BitCount allowed" );
+
+ if ( nDX < 1 )
+ nDX = 1;
+
+ if ( nDY < 1 )
+ nDY = 1;
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( !pOutDev )
+ pOutDev = ImplGetDefaultWindow();
+
+#ifndef REMOTE_APPSERVER
+ SalGraphics* pGraphics;
+ if ( !pOutDev->mpGraphics )
+ ((OutputDevice*)pOutDev)->ImplGetGraphics();
+ pGraphics = pOutDev->mpGraphics;
+ if ( pGraphics )
+ mpVirDev = pSVData->mpDefInst->CreateVirtualDevice( pGraphics, nDX, nDY, nBitCount );
+ else
+ mpVirDev = NULL;
+ if ( !mpVirDev )
+ GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
+#else
+ if( ! pRemoteVirdevCache )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ pRemoteVirdevCache = new ::vcl::InterfacePairCache< ::com::sun::star::portal::client::XRmVirtualDevice, ::com::sun::star::portal::client::XRmOutputDevice >(
+ pSVData->mxMultiFactory,
+ ::rtl::OUString::createFromAscii( "OfficeVirtualDevice.stardiv.de" ),
+ 20, 10, 40 );
+ }
+
+ if( pOutDev->GetOutDevType() == OUTDEV_PRINTER || ! mpVirDev )
+ {
+ virdevInterfacePair aPair = pRemoteVirdevCache->takeInterface();
+ if( aPair.first.is() && aPair.second.is() )
+ {
+ if( ! mpVirDev )
+ mpVirDev = new RmVirtualDevice;
+ mpVirDev->SetInterface( aPair.first );
+ mpVirDev->Create( (ULONG) pOutDev, nDX, nDY, nBitCount );
+
+ if( ! mpGraphics )
+ mpGraphics = new ImplServerGraphics();
+ mpGraphics->SetInterface( aPair.second );
+ }
+ }
+ else
+ {
+ // this was done in ImpGetServerGraphics before
+ // and is now here because of interface caching
+ if( mpGraphics && mpGraphics->GetInterface().is() )
+ {
+ try
+ {
+ mpGraphics->GetInterface()->SetFillColor( mpGraphics->maFillColor.GetColor() );
+ }
+ catch (...)
+ {
+ if( mpGraphics )
+ delete mpGraphics, mpGraphics = NULL;
+
+ if( mpVirDev )
+ {
+ virdevInterfacePair aPair = pRemoteVirdevCache->takeInterface();
+ if( aPair.first.is() && aPair.second.is() )
+ {
+ mpVirDev->SetInterface( aPair.first );
+ mpVirDev->Create( (ULONG)NULL, mnOutWidth, mnOutHeight, mnBitCount );
+ mpGraphics = new ImplServerGraphics();
+ mpGraphics->SetInterface( aPair.second );
+ }
+ else
+ mpVirDev->SetInterface( REF( NMSP_CLIENT::XRmVirtualDevice )() );
+ }
+ }
+ }
+ ImplGetServerGraphics( TRUE );
+ }
+#endif
+
+ mnBitCount = ( nBitCount ? nBitCount : pOutDev->GetBitCount() );
+ mnOutWidth = nDX;
+ mnOutHeight = nDY;
+ mbScreenComp = TRUE;
+
+ if ( pOutDev->GetOutDevType() == OUTDEV_PRINTER )
+ mbScreenComp = FALSE;
+ else if ( pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
+ mbScreenComp = ((VirtualDevice*)pOutDev)->mbScreenComp;
+
+ meOutDevType = OUTDEV_VIRDEV;
+ mbDevOutput = TRUE;
+ mpFontList = pSVData->maGDIData.mpScreenFontList;
+ mpFontCache = pSVData->maGDIData.mpScreenFontCache;
+ mnDPIX = pOutDev->mnDPIX;
+ mnDPIY = pOutDev->mnDPIY;
+ maFont = pOutDev->maFont;
+
+ // Virtuelle Devices haben defaultmaessig einen weissen Hintergrund
+ SetBackground( Wallpaper( Color( COL_WHITE ) ) );
+ Erase();
+
+ // VirDev in Liste eintragen
+ mpNext = pSVData->maGDIData.mpFirstVirDev;
+ mpPrev = NULL;
+ if ( mpNext )
+ mpNext->mpPrev = this;
+ else
+ pSVData->maGDIData.mpLastVirDev = this;
+ pSVData->maGDIData.mpFirstVirDev = this;
+}
+
+// -----------------------------------------------------------------------
+
+VirtualDevice::VirtualDevice( USHORT nBitCount )
+ : mpVirDev( NULL )
+{
+ DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
+
+ ImplInitVirDev( Application::GetDefaultDevice(), 1, 1, nBitCount );
+}
+
+// -----------------------------------------------------------------------
+
+VirtualDevice::VirtualDevice( const OutputDevice& rCompDev, USHORT nBitCount )
+ : mpVirDev( NULL )
+{
+ DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
+
+ ImplInitVirDev( &rCompDev, 1, 1, nBitCount );
+}
+
+// -----------------------------------------------------------------------
+
+VirtualDevice::~VirtualDevice()
+{
+ DBG_TRACE( "VirtualDevice::~VirtualDevice()" );
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+
+ if ( mpVirDev )
+ pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev );
+#else
+ if ( pRemoteVirdevCache && mpVirDev && mpGraphics )
+ {
+ virdevInterfacePair aPair( mpVirDev->GetInterface(), mpGraphics->GetInterface() );
+ aPair.first->Create( 0, 0, 0, 0 );
+ pRemoteVirdevCache->putInterface( aPair );
+ }
+
+ mpGraphics->SetInterface( REF( NMSP_CLIENT::XRmOutputDevice )() );
+ ImplReleaseServerGraphics();
+ delete mpVirDev;
+ delete mpGraphics;
+#endif
+
+ // VirDev aus der Liste eintragen
+ if( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ pSVData->maGDIData.mpFirstVirDev = mpNext;
+
+ if( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ pSVData->maGDIData.mpLastVirDev = mpPrev;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL VirtualDevice::SetOutputSizePixel( const Size& rNewSize, BOOL bErase )
+{
+ DBG_TRACE3( "VirtualDevice::SetOutputSizePixel( %ld, %ld, %d )", rNewSize.Width(), rNewSize.Height(), (int)bErase );
+
+ if ( !mpVirDev )
+ return FALSE;
+ else if ( rNewSize == GetOutputSizePixel() )
+ {
+ if ( bErase )
+ Erase();
+ return TRUE;
+ }
+
+#ifdef REMOTE_APPSERVER
+ long nOldWidth = mnOutWidth, nOldHeight = mnOutHeight;
+
+ try
+ {
+ mnOutWidth = rNewSize.Width();
+ mnOutHeight = rNewSize.Height();
+ mpVirDev->ResizeOutputSizePixel( mnOutWidth, mnOutHeight );
+ }
+ catch (...)
+ {
+ delete mpVirDev, mpVirDev = NULL;
+ ImplInitVirDev( NULL, mnOutWidth, mnOutHeight, mnBitCount );
+ }
+
+ if( bErase )
+ Erase();
+ else
+ {
+ if ( nOldWidth < mnOutWidth )
+ Erase( Rectangle( Point( nOldWidth, 0 ), Size( mnOutWidth-nOldWidth, Max( nOldHeight, mnOutHeight ) ) ) );
+ if ( nOldHeight< mnOutHeight )
+ Erase( Rectangle( Point( 0, nOldHeight ), Size( Max( nOldWidth, mnOutWidth ), mnOutHeight-nOldHeight ) ) );
+ }
+
+ return TRUE;
+#else
+ BOOL bRet;
+ long nNewWidth = rNewSize.Width(), nNewHeight = rNewSize.Height();
+
+ if ( nNewWidth < 1 )
+ nNewWidth = 1;
+
+ if ( nNewHeight < 1 )
+ nNewHeight = 1;
+
+ if ( bErase )
+ {
+ bRet = mpVirDev->SetSize( nNewWidth, nNewHeight );
+
+ if ( bRet )
+ {
+ mnOutWidth = rNewSize.Width();
+ mnOutHeight = rNewSize.Height();
+ Erase();
+ }
+ }
+ else
+ {
+ SalVirtualDevice* pNewVirDev;
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return FALSE;
+ }
+
+ pNewVirDev = pSVData->mpDefInst->CreateVirtualDevice( mpGraphics, nNewWidth, nNewHeight, mnBitCount );
+ if ( pNewVirDev )
+ {
+ SalGraphics* pGraphics = pNewVirDev->GetGraphics();
+ if ( pGraphics )
+ {
+ SalTwoRect aPosAry;
+ long nWidth;
+ long nHeight;
+ if ( mnOutWidth < nNewWidth )
+ nWidth = mnOutWidth;
+ else
+ nWidth = nNewWidth;
+ if ( mnOutHeight < nNewHeight )
+ nHeight = mnOutHeight;
+ else
+ nHeight = nNewHeight;
+ aPosAry.mnSrcX = 0;
+ aPosAry.mnSrcY = 0;
+ aPosAry.mnSrcWidth = nWidth;
+ aPosAry.mnSrcHeight = nHeight;
+ aPosAry.mnDestX = 0;
+ aPosAry.mnDestY = 0;
+ aPosAry.mnDestWidth = nWidth;
+ aPosAry.mnDestHeight = nHeight;
+
+ pGraphics->CopyBits( &aPosAry, mpGraphics );
+ pNewVirDev->ReleaseGraphics( pGraphics );
+ ImplReleaseGraphics();
+ pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev );
+ mpVirDev = pNewVirDev;
+ mnOutWidth = rNewSize.Width();
+ mnOutHeight = rNewSize.Height();
+ bRet = TRUE;
+ }
+ else
+ {
+ bRet = FALSE;
+ pSVData->mpDefInst->DestroyVirtualDevice( pNewVirDev );
+ }
+ }
+ else
+ bRet = FALSE;
+ }
+
+ return bRet;
+#endif
+}
+
diff --git a/vcl/source/gdi/wall.cxx b/vcl/source/gdi/wall.cxx
new file mode 100644
index 000000000000..64eb82b23585
--- /dev/null
+++ b/vcl/source/gdi/wall.cxx
@@ -0,0 +1,616 @@
+/*************************************************************************
+ *
+ * $RCSfile: wall.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_WALL_CXX
+
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _VCOMPAT_HXX
+#include <tools/vcompat.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_BITMAPEX_HXX
+#include <bitmapex.hxx>
+#endif
+#ifndef _SV_GRADIENT_HXX
+#include <gradient.hxx>
+#endif
+#ifndef _SV_WALL_HXX
+#include <wall.hxx>
+#endif
+
+// =======================================================================
+
+DBG_NAME( Wallpaper );
+
+// -----------------------------------------------------------------------
+
+ImplWallpaper::ImplWallpaper() :
+ maColor( COL_TRANSPARENT )
+{
+ mnRefCount = 1;
+ mpBitmap = NULL;
+ mpCache = NULL;
+ mpGradient = NULL;
+ mpRect = NULL;
+ meStyle = WALLPAPER_NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplWallpaper::ImplWallpaper( const ImplWallpaper& rImplWallpaper ) :
+ maColor( rImplWallpaper.maColor )
+{
+ mnRefCount = 1;
+ meStyle = rImplWallpaper.meStyle;
+
+ if ( rImplWallpaper.mpBitmap )
+ mpBitmap = new BitmapEx( *rImplWallpaper.mpBitmap );
+ else
+ mpBitmap = NULL;
+ if( rImplWallpaper.mpCache )
+ mpCache = new BitmapEx( *rImplWallpaper.mpCache );
+ else
+ mpCache = NULL;
+ if ( rImplWallpaper.mpGradient )
+ mpGradient = new Gradient( *rImplWallpaper.mpGradient );
+ else
+ mpGradient = NULL;
+ if ( rImplWallpaper.mpRect )
+ mpRect = new Rectangle( *rImplWallpaper.mpRect );
+ else
+ mpRect = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplWallpaper::~ImplWallpaper()
+{
+ delete mpBitmap;
+ delete mpCache;
+ delete mpGradient;
+ delete mpRect;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWallpaper::ImplSetCachedBitmap( BitmapEx& rBmp )
+{
+ if( !mpCache )
+ mpCache = new BitmapEx( rBmp );
+ else
+ *mpCache = rBmp;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWallpaper::ImplReleaseCachedBitmap()
+{
+ delete mpCache;
+ mpCache = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, ImplWallpaper& rImplWallpaper )
+{
+ VersionCompat aCompat( rIStm, STREAM_READ );
+ UINT16 nTmp16;
+
+ delete rImplWallpaper.mpRect;
+ rImplWallpaper.mpRect = NULL;
+
+ delete rImplWallpaper.mpGradient;
+ rImplWallpaper.mpGradient = NULL;
+
+ delete rImplWallpaper.mpBitmap;
+ rImplWallpaper.mpBitmap = NULL;
+
+ // version 1
+ rIStm >> rImplWallpaper.maColor;
+ rIStm >> nTmp16; rImplWallpaper.meStyle = (WallpaperStyle) nTmp16;
+
+ // version 2
+ if( aCompat.GetVersion() >= 2 )
+ {
+ BOOL bRect, bGrad, bBmp, bDummy;
+
+ rIStm >> bRect >> bGrad >> bBmp >> bDummy >> bDummy >> bDummy;
+
+ if( bRect )
+ {
+ rImplWallpaper.mpRect = new Rectangle;
+ rIStm >> *rImplWallpaper.mpRect;
+ }
+
+ if( bGrad )
+ {
+ rImplWallpaper.mpGradient = new Gradient;
+ rIStm >> *rImplWallpaper.mpGradient;
+ }
+
+ if( bBmp )
+ {
+ rImplWallpaper.mpBitmap = new BitmapEx;
+ rIStm >> *rImplWallpaper.mpBitmap;
+ }
+
+ // version 3 (new color format)
+ if( aCompat.GetVersion() >= 3 )
+ {
+ rImplWallpaper.maColor.Read( rIStm, TRUE );
+ }
+ }
+
+ return rIStm;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const ImplWallpaper& rImplWallpaper )
+{
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 3 );
+ BOOL bRect = ( rImplWallpaper.mpRect != NULL );
+ BOOL bGrad = ( rImplWallpaper.mpGradient != NULL );
+ BOOL bBmp = ( rImplWallpaper.mpBitmap != NULL );
+ BOOL bDummy = FALSE;
+
+ // version 1
+ rOStm << rImplWallpaper.maColor << (UINT16) rImplWallpaper.meStyle;
+
+ // version 2
+ rOStm << bRect << bGrad << bBmp << bDummy << bDummy << bDummy;
+
+ if( bRect )
+ rOStm << *rImplWallpaper.mpRect;
+
+ if( bGrad )
+ rOStm << *rImplWallpaper.mpGradient;
+
+ if( bBmp )
+ rOStm << *rImplWallpaper.mpBitmap;
+
+ // version 3 (new color format)
+ ( (Color&) rImplWallpaper.maColor ).Write( rOStm, TRUE );
+
+ return rOStm;
+}
+
+// -----------------------------------------------------------------------
+
+inline void Wallpaper::ImplMakeUnique( BOOL bReleaseCache )
+{
+ // Falls noch andere Referenzen bestehen, dann kopieren
+ if ( mpImplWallpaper->mnRefCount != 1 )
+ {
+ if ( mpImplWallpaper->mnRefCount )
+ mpImplWallpaper->mnRefCount--;
+ mpImplWallpaper = new ImplWallpaper( *(mpImplWallpaper) );
+ }
+
+ if( bReleaseCache )
+ mpImplWallpaper->ImplReleaseCachedBitmap();
+}
+
+// -----------------------------------------------------------------------
+
+Wallpaper::Wallpaper()
+{
+ DBG_CTOR( Wallpaper, NULL );
+
+#ifdef WIN
+ static ImplWallpaper _near aStaticImplWallpaper;
+#else
+ static ImplWallpaper aStaticImplWallpaper;
+#endif
+
+ aStaticImplWallpaper.mnRefCount = 0;
+ mpImplWallpaper = &aStaticImplWallpaper;
+}
+
+// -----------------------------------------------------------------------
+
+Wallpaper::Wallpaper( const Wallpaper& rWallpaper )
+{
+ DBG_CTOR( Wallpaper, NULL );
+ DBG_CHKOBJ( &rWallpaper, Wallpaper, NULL );
+ DBG_ASSERT( rWallpaper.mpImplWallpaper->mnRefCount < 0xFFFE, "Wallpaper: RefCount overflow" );
+
+ // Instance Daten uebernehmen und Referenzcounter erhoehen
+ mpImplWallpaper = rWallpaper.mpImplWallpaper;
+ // RefCount == 0 fuer statische Objekte
+ if ( mpImplWallpaper->mnRefCount )
+ mpImplWallpaper->mnRefCount++;
+}
+
+// -----------------------------------------------------------------------
+
+Wallpaper::Wallpaper( const Color& rColor )
+{
+ DBG_CTOR( Wallpaper, NULL );
+
+ mpImplWallpaper = new ImplWallpaper;
+ mpImplWallpaper->maColor = rColor;
+ mpImplWallpaper->meStyle = WALLPAPER_TILE;
+}
+
+// -----------------------------------------------------------------------
+
+Wallpaper::Wallpaper( const BitmapEx& rBmpEx )
+{
+ DBG_CTOR( Wallpaper, NULL );
+
+ mpImplWallpaper = new ImplWallpaper;
+ mpImplWallpaper->mpBitmap = new BitmapEx( rBmpEx );
+ mpImplWallpaper->meStyle = WALLPAPER_TILE;
+}
+
+// -----------------------------------------------------------------------
+
+Wallpaper::Wallpaper( const Gradient& rGradient )
+{
+ DBG_CTOR( Wallpaper, NULL );
+
+ mpImplWallpaper = new ImplWallpaper;
+ mpImplWallpaper->mpGradient = new Gradient( rGradient );
+ mpImplWallpaper->meStyle = WALLPAPER_TILE;
+}
+
+// -----------------------------------------------------------------------
+
+Wallpaper::~Wallpaper()
+{
+ DBG_DTOR( Wallpaper, NULL );
+
+ // Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
+ // die letzte Referenz ist, sonst Referenzcounter decrementieren
+ if ( mpImplWallpaper->mnRefCount )
+ {
+ if ( mpImplWallpaper->mnRefCount == 1 )
+ delete mpImplWallpaper;
+ else
+ mpImplWallpaper->mnRefCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Wallpaper::SetColor( const Color& rColor )
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ ImplMakeUnique();
+ mpImplWallpaper->maColor = rColor;
+
+ if( WALLPAPER_NULL == mpImplWallpaper->meStyle )
+ mpImplWallpaper->meStyle = WALLPAPER_TILE;
+}
+
+// -----------------------------------------------------------------------
+
+void Wallpaper::SetStyle( WallpaperStyle eStyle )
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ ImplMakeUnique( FALSE );
+ mpImplWallpaper->meStyle = eStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void Wallpaper::SetBitmap( const BitmapEx& rBitmap )
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ if ( !rBitmap )
+ {
+ if ( mpImplWallpaper->mpBitmap )
+ {
+ ImplMakeUnique();
+ delete mpImplWallpaper->mpBitmap;
+ mpImplWallpaper->mpBitmap = NULL;
+ }
+ }
+ else
+ {
+ ImplMakeUnique();
+ if ( mpImplWallpaper->mpBitmap )
+ *(mpImplWallpaper->mpBitmap) = rBitmap;
+ else
+ mpImplWallpaper->mpBitmap = new BitmapEx( rBitmap );
+ }
+
+ if( WALLPAPER_NULL == mpImplWallpaper->meStyle )
+ mpImplWallpaper->meStyle = WALLPAPER_TILE;
+}
+
+// -----------------------------------------------------------------------
+
+void Wallpaper::SetBitmap()
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ if ( mpImplWallpaper->mpBitmap )
+ {
+ ImplMakeUnique();
+ delete mpImplWallpaper->mpBitmap;
+ mpImplWallpaper->mpBitmap = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BitmapEx Wallpaper::GetBitmap() const
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ if ( mpImplWallpaper->mpBitmap )
+ return *(mpImplWallpaper->mpBitmap);
+ else
+ {
+ BitmapEx aBmp;
+ return aBmp;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Wallpaper::SetGradient( const Gradient& rGradient )
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ ImplMakeUnique();
+
+ if ( mpImplWallpaper->mpGradient )
+ *(mpImplWallpaper->mpGradient) = rGradient;
+ else
+ mpImplWallpaper->mpGradient = new Gradient( rGradient );
+
+ if( WALLPAPER_NULL == mpImplWallpaper->meStyle )
+ mpImplWallpaper->meStyle = WALLPAPER_TILE;
+}
+
+// -----------------------------------------------------------------------
+
+void Wallpaper::SetGradient()
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ if ( mpImplWallpaper->mpGradient )
+ {
+ ImplMakeUnique();
+ delete mpImplWallpaper->mpGradient;
+ mpImplWallpaper->mpGradient = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Gradient Wallpaper::GetGradient() const
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ if ( mpImplWallpaper->mpGradient )
+ return *(mpImplWallpaper->mpGradient);
+ else
+ {
+ Gradient aGradient;
+ return aGradient;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Wallpaper::SetRect( const Rectangle& rRect )
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ ImplMakeUnique( FALSE );
+
+ if ( rRect.IsEmpty() )
+ {
+ if ( mpImplWallpaper->mpRect )
+ {
+ delete mpImplWallpaper->mpRect;
+ mpImplWallpaper->mpRect = NULL;
+ }
+ }
+ else
+ {
+ if ( mpImplWallpaper->mpRect )
+ *(mpImplWallpaper->mpRect) = rRect;
+ else
+ mpImplWallpaper->mpRect = new Rectangle( rRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Wallpaper::SetRect()
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ if ( mpImplWallpaper->mpRect )
+ {
+ ImplMakeUnique( FALSE );
+ delete mpImplWallpaper->mpRect;
+ mpImplWallpaper->mpRect = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle Wallpaper::GetRect() const
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+
+ if ( mpImplWallpaper->mpRect )
+ return *(mpImplWallpaper->mpRect);
+ else
+ {
+ Rectangle aRect;
+ return aRect;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Wallpaper::IsFixed() const
+{
+ if ( mpImplWallpaper->meStyle == WALLPAPER_NULL )
+ return FALSE;
+ else
+ return (!mpImplWallpaper->mpBitmap && !mpImplWallpaper->mpGradient);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Wallpaper::IsScrollable() const
+{
+ if ( mpImplWallpaper->meStyle == WALLPAPER_NULL )
+ return FALSE;
+ else if ( !mpImplWallpaper->mpBitmap && !mpImplWallpaper->mpGradient )
+ return TRUE;
+ else if ( mpImplWallpaper->mpBitmap )
+ return (mpImplWallpaper->meStyle == WALLPAPER_TILE);
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Wallpaper& Wallpaper::operator=( const Wallpaper& rWallpaper )
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+ DBG_CHKOBJ( &rWallpaper, Wallpaper, NULL );
+ DBG_ASSERT( rWallpaper.mpImplWallpaper->mnRefCount < 0xFFFE, "Wallpaper: RefCount overflow" );
+
+ // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
+ if ( rWallpaper.mpImplWallpaper->mnRefCount )
+ rWallpaper.mpImplWallpaper->mnRefCount++;
+
+ // Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
+ // die letzte Referenz ist, sonst Referenzcounter decrementieren
+ if ( mpImplWallpaper->mnRefCount )
+ {
+ if ( mpImplWallpaper->mnRefCount == 1 )
+ delete mpImplWallpaper;
+ else
+ mpImplWallpaper->mnRefCount--;
+ }
+
+ mpImplWallpaper = rWallpaper.mpImplWallpaper;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Wallpaper::operator==( const Wallpaper& rWallpaper ) const
+{
+ DBG_CHKTHIS( Wallpaper, NULL );
+ DBG_CHKOBJ( &rWallpaper, Wallpaper, NULL );
+
+ if ( mpImplWallpaper == rWallpaper.mpImplWallpaper )
+ return TRUE;
+
+ if ( ( mpImplWallpaper->meStyle != rWallpaper.mpImplWallpaper->meStyle ) ||
+ ( mpImplWallpaper->maColor != rWallpaper.mpImplWallpaper->maColor ) )
+ return FALSE;
+
+ if ( mpImplWallpaper->mpRect != rWallpaper.mpImplWallpaper->mpRect
+ && ( !mpImplWallpaper->mpRect
+ || !rWallpaper.mpImplWallpaper->mpRect
+ || *(mpImplWallpaper->mpRect) != *(rWallpaper.mpImplWallpaper->mpRect) ) )
+ return FALSE;
+
+ if ( mpImplWallpaper->mpBitmap != rWallpaper.mpImplWallpaper->mpBitmap
+ && ( !mpImplWallpaper->mpBitmap
+ || !rWallpaper.mpImplWallpaper->mpBitmap
+ || *(mpImplWallpaper->mpBitmap) != *(rWallpaper.mpImplWallpaper->mpBitmap) ) )
+ return FALSE;
+
+ if ( mpImplWallpaper->mpGradient != rWallpaper.mpImplWallpaper->mpGradient
+ && ( !mpImplWallpaper->mpGradient
+ || !rWallpaper.mpImplWallpaper->mpGradient
+ || *(mpImplWallpaper->mpGradient) != *(rWallpaper.mpImplWallpaper->mpGradient) ) )
+ return FALSE;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIStm, Wallpaper& rWallpaper )
+{
+ rWallpaper.ImplMakeUnique();
+ return( rIStm >> *rWallpaper.mpImplWallpaper );
+}
+
+// -----------------------------------------------------------------------
+
+SvStream& operator<<( SvStream& rOStm, const Wallpaper& rWallpaper )
+{
+ return( rOStm << *rWallpaper.mpImplWallpaper );
+}
diff --git a/vcl/source/helper/evntpost.cxx b/vcl/source/helper/evntpost.cxx
new file mode 100644
index 000000000000..b19c5b190a1a
--- /dev/null
+++ b/vcl/source/helper/evntpost.cxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * $RCSfile: evntpost.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#pragma hdrstop
+
+#include "evntpost.hxx"
+#include "svapp.hxx"
+
+namespace vcl
+{
+
+EventPoster::EventPoster( const Link& rLink )
+ : m_aLink(rLink)
+ , m_nId(0)
+{
+}
+
+EventPoster::~EventPoster()
+{
+ if ( m_nId )
+ GetpApp()->RemoveUserEvent( m_nId );
+}
+
+void EventPoster::Post( UserEvent* pEvent )
+
+{
+ m_nId = GetpApp()->PostUserEvent( ( LINK( this, EventPoster, DoEvent_Impl ) ), pEvent );
+}
+
+IMPL_LINK_INLINE_START( EventPoster, DoEvent_Impl, UserEvent*, pEvent )
+{
+ m_nId = 0;
+ m_aLink.Call( pEvent );
+ return 0;
+}
+IMPL_LINK_INLINE_END( EventPoster, DoEvent_Impl, UserEvent*, pEvent )
+
+};
diff --git a/vcl/source/helper/makefile.mk b/vcl/source/helper/makefile.mk
new file mode 100644
index 000000000000..eeec5a8f0a1d
--- /dev/null
+++ b/vcl/source/helper/makefile.mk
@@ -0,0 +1,100 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+ENABLE_EXCEPTIONS=TRUE
+PRJNAME=vcl
+TARGET=helper
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES=\
+ $(SLO)$/sunowrap.obj \
+ $(SLO)$/atom.obj \
+ $(SLO)$/threadex.obj
+
+.IF "$(GUI)" == "UNX"
+SLOFILES+=\
+ $(SLO)$/ppdparser.obj \
+ $(SLO)$/strhelper.obj
+.ENDIF
+
+# NETBSD: somewhere we have to instantiate the static data members.
+# NETBSD-1.2.1 doesn't know about weak symbols so the default mechanism for GCC won't work.
+# SCO and MACOSX: the linker does know about weak symbols, but we can't ignore multiple defined symbols
+.IF "$(OS)"=="NETBSD" || "$(OS)"=="SCO" || "$(OS)$(COM)"=="OS2GCC" || "$(OS)"=="MACOSX"
+SLOFILES+=$(SLO)$/staticmbhelper.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
diff --git a/vcl/source/helper/threadex.cxx b/vcl/source/helper/threadex.cxx
new file mode 100644
index 000000000000..d33be4f6f355
--- /dev/null
+++ b/vcl/source/helper/threadex.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * $RCSfile: threadex.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <threadex.hxx>
+#include <svapp.hxx>
+
+using namespace vcl;
+
+ThreadExecutor::ThreadExecutor()
+{
+ m_aFinish = osl_createCondition();
+ m_aThread = NULL;
+}
+
+ThreadExecutor::~ThreadExecutor()
+{
+ osl_destroyCondition( m_aFinish );
+ if( m_aThread )
+ osl_freeThreadHandle( m_aThread );
+}
+
+void ThreadExecutor::worker( void* pInstance )
+{
+ ThreadExecutor* pThis = ((ThreadExecutor*)pInstance);
+ pThis->m_nReturn = pThis->doIt();
+ osl_setCondition( pThis->m_aFinish );
+}
+
+long ThreadExecutor::execute()
+{
+ osl_resetCondition( m_aFinish );
+ if( m_aThread )
+ osl_freeThreadHandle( m_aThread ), m_aThread = NULL;
+ m_aThread = osl_createThread( worker, this );
+ while( ! osl_checkCondition( m_aFinish ) )
+ Application::Reschedule();
+ return m_nReturn;
+}
+
+
+SolarThreadExecutor::SolarThreadExecutor()
+{
+ m_aFinish = osl_createCondition();
+}
+
+SolarThreadExecutor::~SolarThreadExecutor()
+{
+ osl_destroyCondition( m_aFinish );
+}
+
+IMPL_LINK( SolarThreadExecutor, worker, void*, pDummy )
+{
+ m_nReturn = doIt();
+ osl_setCondition( m_aFinish );
+ return m_nReturn;
+}
+
+long SolarThreadExecutor::execute()
+{
+ if( ::vos::OThread::getCurrentIdentifier() == Application::GetMainThreadIdentifier() )
+ {
+ m_nReturn = doIt();
+ osl_setCondition( m_aFinish );
+ }
+ else
+ {
+ osl_resetCondition( m_aFinish );
+ Application::PostUserEvent( LINK( this, SolarThreadExecutor, worker ) );
+ osl_waitCondition( m_aFinish, NULL );
+ }
+ return m_nReturn;
+}
diff --git a/vcl/source/src/btntext.src b/vcl/source/src/btntext.src
new file mode 100644
index 000000000000..51f9d9df8bd0
--- /dev/null
+++ b/vcl/source/src/btntext.src
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * $RCSfile: btntext.src,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_BTNTEXT_SRC
+
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+
+String SV_BUTTONTEXT_OK
+{
+ Text = "OK";
+ Text [ English ] = "OK";
+ TEXT[ italian ] = "OK";
+ TEXT[ portuguese_brazilian ] = "OK";
+ TEXT[ portuguese ] = "OK";
+ TEXT[ danish ] = "OK";
+ TEXT[ french ] = "OK";
+ TEXT[ swedish ] = "OK";
+ TEXT[ dutch ] = "OK";
+ TEXT[ spanish ] = "Aceptar";
+ TEXT[ english_us ] = "OK";
+ TEXT[ russian ] = "OK";
+ TEXT[ polish ] = "OK";
+ TEXT[ japanese ] = "OK";
+ TEXT[ chinese_simplified ] = "ȷ";
+ TEXT[ chinese_traditional ] = "Tw";
+ TEXT[ arabic ] = "";
+ TEXT[ dutch ] = "OK";
+ TEXT[ chinese_simplified ] = "ȷ";
+ TEXT[ greek ] = "OK";
+ TEXT[ korean ] = "Ȯ";
+ TEXT[ turkish ] = "Tamam";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_BUTTONTEXT_CANCEL
+{
+ Text = "Abbrechen" ;
+ Text [ English ] = "Cancel" ;
+ TEXT[ italian ] = "Annulla";
+ TEXT[ portuguese_brazilian ] = "Cancelar";
+ TEXT[ portuguese ] = "Cancelar";
+ TEXT[ danish ] = "Annuller";
+ TEXT[ french ] = "Annuler";
+ TEXT[ swedish ] = "Avbryt";
+ TEXT[ dutch ] = "Annuleren";
+ TEXT[ spanish ] = "Cancelar";
+ TEXT[ english_us ] = "Cancel";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Anuluj";
+ TEXT[ japanese ] = "ݾ";
+ TEXT[ chinese_simplified ] = "ȡ";
+ TEXT[ chinese_traditional ] = "";
+ TEXT[ arabic ] = " ";
+ TEXT[ dutch ] = "Annuleren";
+ TEXT[ chinese_simplified ] = "ȡ";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "";
+ TEXT[ turkish ] = "ptal";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_BUTTONTEXT_YES
+{
+ Text = "~Ja";
+ Text [ English ] = "~Yes";
+ TEXT[ italian ] = "S";
+ TEXT[ portuguese_brazilian ] = "~Sim";
+ TEXT[ portuguese ] = "~Sim";
+ TEXT[ danish ] = "~Ja";
+ TEXT[ french ] = "~Oui";
+ TEXT[ swedish ] = "~Ja";
+ TEXT[ dutch ] = "~Ja";
+ TEXT[ spanish ] = "~S";
+ TEXT[ english_us ] = "~Yes";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "~Tak";
+ TEXT[ japanese ] = "͂(~Y)";
+ TEXT[ chinese_simplified ] = "(~Y)";
+ TEXT[ chinese_traditional ] = "O(~Y)";
+ TEXT[ arabic ] = "";
+ TEXT[ dutch ] = "~Ja";
+ TEXT[ chinese_simplified ] = "(~Y)";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "(~Y)";
+ TEXT[ turkish ] = "~Evet";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_BUTTONTEXT_NO
+{
+ Text = "~Nein";
+ Text [ English ] = "~No";
+ TEXT[ italian ] = "No";
+ TEXT[ portuguese_brazilian ] = "~No";
+ TEXT[ portuguese ] = "~No";
+ TEXT[ danish ] = "~Nej";
+ TEXT[ french ] = "~Non";
+ TEXT[ swedish ] = "~Nej";
+ TEXT[ dutch ] = "~Nee";
+ TEXT[ spanish ] = "~No";
+ TEXT[ english_us ] = "~No";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "~Nie";
+ TEXT[ japanese ] = "(~N)";
+ TEXT[ chinese_simplified ] = "(~N)";
+ TEXT[ chinese_traditional ] = "_(~N)";
+ TEXT[ arabic ] = "";
+ TEXT[ dutch ] = "~Nee";
+ TEXT[ chinese_simplified ] = "(~N)";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "ƴϿ(~N)";
+ TEXT[ turkish ] = "~Hayr";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_BUTTONTEXT_RETRY
+{
+ Text = "~Wiederholen";
+ Text [ English ] = "~Retry";
+ TEXT[ italian ] = "Riprova";
+ TEXT[ portuguese_brazilian ] = "~Repetir";
+ TEXT[ portuguese ] = "~Repetir";
+ TEXT[ danish ] = "Prv igen";
+ TEXT[ french ] = "~Ressayer";
+ TEXT[ swedish ] = "~Upprepa";
+ TEXT[ dutch ] = "H~erhalen";
+ TEXT[ spanish ] = "~Reintentar";
+ TEXT[ english_us ] = "~Retry";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "P~onw";
+ TEXT[ japanese ] = "蒼(~R)";
+ TEXT[ chinese_simplified ] = "(~R)";
+ TEXT[ chinese_traditional ] = "(~R)";
+ TEXT[ arabic ] = " ";
+ TEXT[ dutch ] = "H~erhalen";
+ TEXT[ chinese_simplified ] = "(~R)";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "ٽ õ(~R)";
+ TEXT[ turkish ] = "Y~inele";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_BUTTONTEXT_HELP
+{
+ Text = "~Hilfe";
+ Text [ English ] = "~Help";
+ TEXT[ italian ] = "?";
+ TEXT[ portuguese_brazilian ] = "Aj~uda";
+ TEXT[ portuguese ] = "Aj~uda";
+ TEXT[ danish ] = "~Hjlp";
+ TEXT[ french ] = "Ai~de";
+ TEXT[ swedish ] = "~Hjlp";
+ TEXT[ dutch ] = "~Help";
+ TEXT[ spanish ] = "Ay~uda";
+ TEXT[ english_us ] = "~Help";
+ TEXT[ russian ] = "~";
+ TEXT[ polish ] = "~Pomoc";
+ TEXT[ japanese ] = "(~H)";
+ TEXT[ chinese_simplified ] = "(~H)";
+ TEXT[ chinese_traditional ] = "(~H)";
+ TEXT[ arabic ] = "";
+ TEXT[ dutch ] = "~Help";
+ TEXT[ chinese_simplified ] = "(~H)";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "(~H)";
+ TEXT[ turkish ] = "~Yardm";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_BUTTONTEXT_MORE
+{
+ Text = "~Zustze";
+ Text [ English ] = "~More";
+ TEXT[ italian ] = "E~xtra";
+ TEXT[ portuguese_brazilian ] = "~Mais";
+ TEXT[ portuguese ] = "~Opes";
+ TEXT[ danish ] = "~Flere";
+ TEXT[ french ] = "O~ptions";
+ TEXT[ swedish ] = "~Fler";
+ TEXT[ dutch ] = "~Overige";
+ TEXT[ spanish ] = "~Opciones";
+ TEXT[ english_us ] = "~More";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "~Dodatki";
+ TEXT[ japanese ] = "lj(~M)";
+ TEXT[ chinese_simplified ] = "(~M)";
+ TEXT[ chinese_traditional ] = "L(~M)";
+ TEXT[ arabic ] = "";
+ TEXT[ dutch ] = "~Overige";
+ TEXT[ chinese_simplified ] = "(~M)";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "ڼ(~M)";
+ TEXT[ turkish ] = "A~yrntlar";
+ TEXT[ language_user1 ] = " ";
+};
+
+/* HelpTexte, die wir derzeit nicht mehr verwenden:
+SV_BUTTONHELPTEXT_OK
+{
+ Text = "Schliet dieses Dialogfeld und speichert alle vorgenommenen nderungen." ;
+ Text [ English ] = "Closes this dialog box and save any changes you have made." ;
+};
+
+SV_BUTTONHELPTEXT_CANCEL
+{
+ Text = "Schliet dieses Dialogfeld, ohne Ihre nderungen zu speichern." ;
+ Text [ English ] = "Closes this dialog box without saving any changes you have made." ;
+};
+
+SV_BUTTONHELPTEXT_HELP
+{
+ Text = "Zeigt Hilfe zu diesem Fenster an." ;
+ Text [ English ] = "Shows help for the current window." ;
+};
+
+SV_BUTTONHELPTEXT_MORE
+{
+ Text = "Zeigt weitere Einstellmglichkeiten an oder versteckt diese wieder." ;
+ Text [ English ] = "Shows more Options or hide these options again." ;
+};
+
+Finnische-Texte:
+OK OK
+CANCEL Peruuta
+HELP ~Ohje
+MORE ~Enemmn
+YES ~Kyll
+NO ~Ei
+RETRY ~Yrituudelleen
+*/
diff --git a/vcl/source/src/helptext.src b/vcl/source/src/helptext.src
new file mode 100644
index 000000000000..41f6eccace76
--- /dev/null
+++ b/vcl/source/src/helptext.src
@@ -0,0 +1,367 @@
+/*************************************************************************
+ *
+ * $RCSfile: helptext.src,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_HELPTEXT_SRC
+
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+
+String SV_HELPTEXT_CLOSE
+{
+ Text = "Schlieen" ;
+ Text [ English ] = "Close" ;
+ TEXT[ italian ] = "Chiudi";
+ TEXT[ portuguese_brazilian ] = "Schlieen";
+ TEXT[ portuguese ] = "Fechar";
+ TEXT[ danish ] = "Luk";
+ TEXT[ french ] = "Fermer";
+ TEXT[ swedish ] = "Stng";
+ TEXT[ dutch ] = "Sluiten";
+ TEXT[ spanish ] = "Cerrar";
+ TEXT[ english_us ] = "Close";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Zamknij";
+ TEXT[ japanese ] = "I";
+ TEXT[ chinese_simplified ] = "ر";
+ TEXT[ chinese_traditional ] = "";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "ݱ";
+ TEXT[ arabic ] = "";
+ TEXT[ turkish ] = "Kapat";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_MINIMIZE
+{
+ Text = "Minimieren" ;
+ Text [ English ] = "Minimize" ;
+ TEXT[ italian ] = "Riduci";
+ TEXT[ portuguese_brazilian ] = "Minimieren";
+ TEXT[ portuguese ] = "Minimizar";
+ TEXT[ danish ] = "Minimer";
+ TEXT[ french ] = "Rduire";
+ TEXT[ swedish ] = "Minimera";
+ TEXT[ dutch ] = "Minimaliseren";
+ TEXT[ spanish ] = "Minimizar";
+ TEXT[ english_us ] = "Minimize";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Minimalizuj";
+ TEXT[ japanese ] = "ŏ";
+ TEXT[ chinese_simplified ] = "С";
+ TEXT[ chinese_traditional ] = "̤p";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "ּȭ";
+ TEXT[ arabic ] = " ";
+ TEXT[ turkish ] = "Simge durumuna klt";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_MAXIMIZE
+{
+ Text = "Maximieren" ;
+ Text [ English ] = "Maximize" ;
+ TEXT[ italian ] = "Ingrandire";
+ TEXT[ portuguese_brazilian ] = "Maximieren";
+ TEXT[ portuguese ] = "Maximizar";
+ TEXT[ danish ] = "Maksimer";
+ TEXT[ french ] = "Agrandir";
+ TEXT[ swedish ] = "Maximera";
+ TEXT[ dutch ] = "Maximeren";
+ TEXT[ spanish ] = "Maximizar";
+ TEXT[ english_us ] = "Maximize";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Maksymalizuj";
+ TEXT[ japanese ] = "ő剻";
+ TEXT[ chinese_simplified ] = "";
+ TEXT[ chinese_traditional ] = "̤j";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "ִȭ";
+ TEXT[ arabic ] = " ";
+ TEXT[ turkish ] = "Ekran kapla";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_RESTORE
+{
+ Text = "Wiederherstellen" ;
+ Text [ English ] = "Restore" ;
+ TEXT[ italian ] = "Ripristina";
+ TEXT[ portuguese_brazilian ] = "Wiederherstellen";
+ TEXT[ portuguese ] = "Restaurar";
+ TEXT[ danish ] = "Gendan";
+ TEXT[ french ] = "Restaurer";
+ TEXT[ swedish ] = "terstll";
+ TEXT[ dutch ] = "Herstellen";
+ TEXT[ spanish ] = "Restaurar";
+ TEXT[ english_us ] = "Restore";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Przywr";
+ TEXT[ japanese ] = "̏Ԃɖ߂";
+ TEXT[ chinese_simplified ] = "ָ";
+ TEXT[ chinese_traditional ] = "_";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "";
+ TEXT[ arabic ] = "";
+ TEXT[ turkish ] = "Baa al";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_ROLLDOWN
+{
+ Text = "Aufklappen" ;
+ Text [ English ] = "Roll Down" ;
+ TEXT[ italian ] = "Mostra";
+ TEXT[ portuguese_brazilian ] = "Aufklappen";
+ TEXT[ portuguese ] = "Abrir";
+ TEXT[ danish ] = "Klap ud";
+ TEXT[ french ] = "Agrandir";
+ TEXT[ swedish ] = "Visa";
+ TEXT[ dutch ] = "Openslaan";
+ TEXT[ spanish ] = "Mostrar";
+ TEXT[ english_us ] = "Drop down";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Otwrz";
+ TEXT[ japanese ] = "J";
+ TEXT[ chinese_simplified ] = "ʾ";
+ TEXT[ chinese_traditional ] = "";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "̱";
+ TEXT[ arabic ] = "";
+ TEXT[ turkish ] = "A";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_ROLLUP
+{
+ Text = "Zuklappen" ;
+ Text [ English ] = "Roll Up" ;
+ TEXT[ italian ] = "Nascondi";
+ TEXT[ portuguese_brazilian ] = "Zuklappen";
+ TEXT[ portuguese ] = "Fechar";
+ TEXT[ danish ] = "Minimer";
+ TEXT[ french ] = "Rduire";
+ TEXT[ swedish ] = "Dlj";
+ TEXT[ dutch ] = "Dichtslaan";
+ TEXT[ spanish ] = "Ocultar";
+ TEXT[ english_us ] = "Roll up";
+ TEXT[ language_user1 ] = " ";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Ukryj";
+ TEXT[ japanese ] = "‚";
+ TEXT[ chinese_simplified ] = "";
+ TEXT[ chinese_traditional ] = "J";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "";
+ TEXT[ arabic ] = "";
+ TEXT[ turkish ] = "Kapat";
+};
+
+String SV_HELPTEXT_HELP
+{
+ Text = "Hilfe" ;
+ Text [ English ] = "Help" ;
+ TEXT[ italian ] = "Guida";
+ TEXT[ portuguese_brazilian ] = "Hilfe";
+ TEXT[ portuguese ] = "Ajuda";
+ TEXT[ danish ] = "Hjlp";
+ TEXT[ french ] = "Aide";
+ TEXT[ swedish ] = "Hjlp";
+ TEXT[ dutch ] = "Help";
+ TEXT[ spanish ] = "Ayuda";
+ TEXT[ english_us ] = "Help";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Pomoc";
+ TEXT[ japanese ] = "wv";
+ TEXT[ chinese_simplified ] = "";
+ TEXT[ chinese_traditional ] = "";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "";
+ TEXT[ arabic ] = "";
+ TEXT[ turkish ] = "Yardm";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_ALWAYSVISIBLE
+{
+ Text = "Immer sichtbar" ;
+ Text [ English ] = "Always Visible" ;
+ TEXT[ italian ] = "Sempre visibile";
+ TEXT[ portuguese_brazilian ] = "Immer sichtbar";
+ TEXT[ portuguese ] = "Sempre visvel";
+ TEXT[ danish ] = "Altid synlig";
+ TEXT[ french ] = "Toujours visible";
+ TEXT[ swedish ] = "Alltid synlig";
+ TEXT[ dutch ] = "Steeds zichtbaar";
+ TEXT[ spanish ] = "Siempre visible";
+ TEXT[ english_us ] = "Always visible";
+ TEXT[ russian ] = " ";
+ TEXT[ polish ] = "Zawsze widoczny";
+ TEXT[ japanese ] = "‚";
+ TEXT[ chinese_simplified ] = "ʾ";
+ TEXT[ chinese_traditional ] = "`O";
+ TEXT[ greek ] = " ";
+ TEXT[ korean ] = "׻ ";
+ TEXT[ arabic ] = " ";
+ TEXT[ turkish ] = "Daima grnr";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_FADEIN
+{
+ Text = "Einblenden" ;
+ Text [ English ] = "Fade In" ;
+ TEXT[ italian ] = "Mostra";
+ TEXT[ portuguese_brazilian ] = "Einblenden";
+ TEXT[ portuguese ] = "Mostrar";
+ TEXT[ danish ] = "Vis";
+ TEXT[ french ] = "Afficher";
+ TEXT[ swedish ] = "Visa";
+ TEXT[ dutch ] = "Weergeven";
+ TEXT[ spanish ] = "Mostrar";
+ TEXT[ english_us ] = "Show";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Poka";
+ TEXT[ japanese ] = "\\";
+ TEXT[ chinese_simplified ] = "ʾ";
+ TEXT[ chinese_traditional ] = "";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "̱";
+ TEXT[ arabic ] = "";
+ TEXT[ turkish ] = "Gster";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_FADEOUT
+{
+ Text = "Ausblenden" ;
+ Text [ English ] = "Fade Out" ;
+ TEXT[ italian ] = "Nascondi";
+ TEXT[ portuguese_brazilian ] = "Ausblenden";
+ TEXT[ portuguese ] = "Ocultar";
+ TEXT[ danish ] = "Skjul";
+ TEXT[ french ] = "Masquer";
+ TEXT[ swedish ] = "Dlj";
+ TEXT[ dutch ] = "Verbergen";
+ TEXT[ spanish ] = "Ocultar";
+ TEXT[ english_us ] = "Hide";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Ukryj";
+ TEXT[ japanese ] = "\\";
+ TEXT[ chinese_simplified ] = "";
+ TEXT[ chinese_traditional ] = "J";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "";
+ TEXT[ arabic ] = "";
+ TEXT[ turkish ] = "Gizle";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_SPLITFLOATING
+{
+ Text = "Schwebend" ;
+ Text [ English ] = "Floating" ;
+ TEXT[ italian ] = "Fluttuante";
+ TEXT[ portuguese_brazilian ] = "Schwebend";
+ TEXT[ portuguese ] = "Flutuante";
+ TEXT[ danish ] = "Flydende";
+ TEXT[ french ] = "Flottante";
+ TEXT[ swedish ] = "Svvande";
+ TEXT[ dutch ] = "Zwevend";
+ TEXT[ spanish ] = "Flotando";
+ TEXT[ english_us ] = "Floating";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Pywajcy";
+ TEXT[ japanese ] = "";
+ TEXT[ chinese_simplified ] = "";
+ TEXT[ chinese_traditional ] = "B";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = " ";
+ TEXT[ arabic ] = "";
+ TEXT[ turkish ] = "Serbest";
+ TEXT[ language_user1 ] = " ";
+};
+
+String SV_HELPTEXT_SPLITFIXED
+{
+ Text = "Fixieren" ;
+ Text [ English ] = "Fixed" ;
+ TEXT[ italian ] = "Fissa";
+ TEXT[ portuguese_brazilian ] = "Fixieren";
+ TEXT[ portuguese ] = "Fixar";
+ TEXT[ danish ] = "Frys";
+ TEXT[ french ] = "Ancre";
+ TEXT[ swedish ] = "Fixera";
+ TEXT[ dutch ] = "Fixeren";
+ TEXT[ spanish ] = "Fijar";
+ TEXT[ english_us ] = "Stick";
+ TEXT[ russian ] = "";
+ TEXT[ polish ] = "Przytwierdzony";
+ TEXT[ japanese ] = "Œ";
+ TEXT[ chinese_simplified ] = "̶";
+ TEXT[ chinese_traditional ] = "Tw";
+ TEXT[ greek ] = "";
+ TEXT[ korean ] = "";
+ TEXT[ arabic ] = "";
+ TEXT[ turkish ] = "Sabitle";
+ TEXT[ language_user1 ] = " ";
+};
+
diff --git a/vcl/source/src/images.src b/vcl/source/src/images.src
new file mode 100644
index 000000000000..163cb4dc6e00
--- /dev/null
+++ b/vcl/source/src/images.src
@@ -0,0 +1,167 @@
+/*************************************************************************
+ *
+ * $RCSfile: images.src,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_IMAGES_SRC
+
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+
+// =======================================================================
+
+Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_STDOFFSET)
+{
+ File = "check.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_WINOFFSET)
+{
+ File = "checkwin.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_OS2OFFSET)
+{
+ File = "checkos2.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_MACOFFSET)
+{
+ File = "checkmac.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_UNIXOFFSET)
+{
+ File = "checkunx.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_SCROLLBMP)
+{
+ File = "scrbmp.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_SCROLLMSK)
+{
+ File = "scrmsk.bmp";
+};
+
+// -----------------------------------------------------------------------
+
+Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_STDOFFSET)
+{
+ File = "radio.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_WINOFFSET)
+{
+ File = "radiowin.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_OS2OFFSET)
+{
+ File = "radioos2.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_MACOFFSET)
+{
+ File = "radiomac.bmp";
+};
+
+Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_UNIXOFFSET)
+{
+ File = "radiounx.bmp";
+};
+
+// -----------------------------------------------------------------------
+
+Bitmap SV_RESID_BITMAP_MSGBOX
+{
+ File = "msgbox.bmp";
+};
+
+// -----------------------------------------------------------------------
+
+Bitmap SV_RESID_BITMAP_PIN
+{
+ File = "pin.bmp";
+};
+
+// -----------------------------------------------------------------------
+
+Bitmap SV_RESID_BITMAP_SPLITHPIN
+{
+ File = "splhpin.bmp";
+};
+
+Bitmap SV_RESID_BITMAP_SPLITVPIN
+{
+ File = "splvpin.bmp";
+};
+
+Bitmap SV_RESID_BITMAP_SPLITHARW
+{
+ File = "splharw.bmp";
+};
+
+Bitmap SV_RESID_BITMAP_SPLITVARW
+{
+ File = "splvarw.bmp";
+};
+
diff --git a/vcl/source/src/makefile.mk b/vcl/source/src/makefile.mk
new file mode 100644
index 000000000000..8520005b59d8
--- /dev/null
+++ b/vcl/source/src/makefile.mk
@@ -0,0 +1,106 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=vcl
+TARGET=svsrc
+RESTARGET=vcl
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+SRCFILES= images.src \
+ menu.src \
+ stdtext.src \
+ helptext.src \
+ btntext.src
+
+RESLIB1NAME= $(RESTARGET)
+RESLIB1SRSFILES= $(SRS)$/svsrc.srs
+RESLIB1BMPS= check.bmp \
+ checkwin.bmp \
+ checkos2.bmp \
+ checkmac.bmp \
+ checkunx.bmp \
+ radio.bmp \
+ radiowin.bmp \
+ radioos2.bmp \
+ radiomac.bmp \
+ radiounx.bmp \
+ msgbox.bmp \
+ scrbmp.bmp \
+ scrmsk.bmp \
+ pin.bmp \
+ splhpin.bmp \
+ splvpin.bmp \
+ splharw.bmp \
+ splvarw.bmp
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/source/src/menu.src b/vcl/source/src/menu.src
new file mode 100644
index 000000000000..a3294770dff7
--- /dev/null
+++ b/vcl/source/src/menu.src
@@ -0,0 +1,284 @@
+/*************************************************************************
+ *
+ * $RCSfile: menu.src,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define _SV_MENU_SRC
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+
+String SV_RESID_STRING_NOSELECTIONPOSSIBLE
+{
+ Text ="<Keine Auswahl mglich>";
+ Text[English] ="<No selection possible>";
+ Text[ english_us ] = "<No selection possible>";
+ Text[ portuguese ] = "<Seleco impossvel>";
+ Text[ russian ] = "< >";
+ Text[ greek ] = "< >";
+ Text[ dutch ] = "<Geen selectie mogelijk>";
+ Text[ french ] = "<Aucune slection possible>";
+ Text[ spanish ] = "<Ninguna seleccin posible>";
+ Text[ italian ] = "<Impossibile selezionare>";
+ Text[ danish ] = "<Intet udvalg muligt>";
+ Text[ swedish ] = "<Inget urval mjligt>";
+ Text[ polish ] = "<Selekcja niemoliwa>";
+ Text[ portuguese_brazilian ] = "<No selection possible>";
+ Text[ japanese ] = "<Ił܂>";
+ Text[ korean ] = "< Ұ>";
+ Text[ chinese_simplified ] = "<޷ѡ>";
+ Text[ chinese_traditional ] = "<Lk>";
+ Text[ arabic ] = "< >";
+ Text[ turkish ] = "<Seim yaplamaz>";
+};
+
+Menu SV_RESID_MENU_EDIT
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SV_MENU_EDIT_UNDO ;
+ Text = "~Rckgngig" ;
+ Text [ English ] = "~Undo" ;
+ Text [ portuguese ] = "~Anular" ;
+ Text [ english_us ] = "~Undo" ;
+ Text [ portuguese_brazilian ] = "~Rckgngig" ;
+ Text [ swedish ] = "~ngra" ;
+ Text [ danish ] = "Fo~rtryd" ;
+ Text [ italian ] = "~Annulla" ;
+ Text [ spanish ] = "~Deshacer" ;
+ Text [ french ] = "~Annuler" ;
+ Text [ dutch ] = "~Ongedaan maken" ;
+ Text[ russian ] = "";
+ Text[ polish ] = "Cofnij";
+ Text[ japanese ] = "ɖ߂(~U)";
+ Text[ chinese_simplified ] = "(~U)";
+ Text[ chinese_traditional ] = "_(~U)";
+ Text[ greek ] = "~";
+ Text[ korean ] = "۾(~U)";
+ Text[ arabic ] = "";
+ Text[ turkish ] = "Geri al";
+ Text[ language_user1 ] = " ";
+ };
+ MenuItem { Separator = TRUE ; };
+ MenuItem
+ {
+ Identifier = SV_MENU_EDIT_CUT ;
+ Text = "~Ausschneiden" ;
+ Text [ English ] = "Cu~t" ;
+ Text [ norwegian ] = "Klipp~ut" ;
+ Text [ italian ] = "~Taglia" ;
+ Text [ portuguese_brazilian ] = "Co~rtar" ;
+ Text [ portuguese ] = "Co~rtar" ;
+ Text [ finnish ] = "~Leikkaa" ;
+ Text [ danish ] = "~Klip" ;
+ Text [ french ] = "~Couper" ;
+ Text [ swedish ] = "~Klipp ut" ;
+ Text [ dutch ] = "K~nippen" ;
+ Text [ spanish ] = "C~ortar" ;
+ Text [ english_us ] = "Cu~t" ;
+ Text[ russian ] = "~";
+ Text[ polish ] = "Wytnij";
+ Text[ japanese ] = "؂(~T)";
+ Text[ chinese_simplified ] = "(~T)";
+ Text[ chinese_traditional ] = "ŤU(~T)";
+ Text[ greek ] = "~";
+ Text[ korean ] = "߶󳻱(~T)";
+ Text[ arabic ] = "";
+ Text[ turkish ] = "~Kes";
+ Text[ language_user1 ] = " ";
+ };
+ MenuItem
+ {
+ Identifier = SV_MENU_EDIT_COPY ;
+ Text = "~Kopieren" ;
+ Text [ English ] = "~Copy" ;
+ Text [ norwegian ] = "~Kopier" ;
+ Text [ italian ] = "~Copia" ;
+ Text [ portuguese_brazilian ] = "~Copiar" ;
+ Text [ portuguese ] = "~Copiar" ;
+ Text [ finnish ] = "~Kopioi" ;
+ Text [ danish ] = "K~opier" ;
+ Text [ french ] = "Co~pier" ;
+ Text [ swedish ] = "K~opiera" ;
+ Text [ dutch ] = "~Kopiren" ;
+ Text [ spanish ] = "~Copiar" ;
+ Text [ english_us ] = "~Copy" ;
+ Text[ russian ] = "~";
+ Text[ polish ] = "Kopiuj";
+ Text[ japanese ] = "߰(~C)";
+ Text[ chinese_simplified ] = "(~C)";
+ Text[ chinese_traditional ] = "ƻs(~C)";
+ Text[ greek ] = "~";
+ Text[ korean ] = "(~C)";
+ Text[ arabic ] = "";
+ Text[ turkish ] = "K~opyala";
+ Text[ language_user1 ] = " ";
+ };
+ MenuItem
+ {
+ Identifier = SV_MENU_EDIT_PASTE ;
+ Text = "~Einfgen" ;
+ Text [ English ] = "~Paste" ;
+ Text [ norwegian ] = "~Paste" ;
+ Text [ italian ] = "~Incolla" ;
+ Text [ portuguese_brazilian ] = "~Colar" ;
+ Text [ portuguese ] = "Co~lar" ;
+ Text [ finnish ] = "L~iit" ;
+ Text [ danish ] = "~Indst" ;
+ Text [ french ] = "C~oller" ;
+ Text [ swedish ] = "K~listra in" ;
+ Text [ dutch ] = "~Plakken" ;
+ Text [ spanish ] = "~Pegar" ;
+ Text [ english_us ] = "~Paste" ;
+ Text[ russian ] = "~";
+ Text[ polish ] = "W~staw";
+ Text[ japanese ] = "\\t(~P)";
+ Text[ chinese_simplified ] = "(~P)";
+ Text[ chinese_traditional ] = "J(~P)";
+ Text[ greek ] = "~";
+ Text[ korean ] = "ٿֱ(~P)";
+ Text[ arabic ] = "";
+ Text[ turkish ] = "~Yaptr";
+ Text[ language_user1 ] = " ";
+ };
+ MenuItem
+ {
+ Identifier = SV_MENU_EDIT_DELETE ;
+ Text = "~Lschen" ;
+ Text [ English ] = "~Delete" ;
+ Text [ norwegian ] = "~Slett" ;
+ Text [ italian ] = "Cancella" ;
+ Text [ portuguese_brazilian ] = "~Apagar" ;
+ Text [ portuguese ] = "E~liminar" ;
+ Text [ finnish ] = "~Poista" ;
+ Text [ danish ] = "~Slet" ;
+ Text [ french ] = "~Supprimer" ;
+ Text [ swedish ] = "~Radera" ;
+ Text [ dutch ] = "~Wissen" ;
+ Text [ spanish ] = "~Eliminar" ;
+ Text [ english_us ] = "~Delete" ;
+ Text[ russian ] = "~";
+ Text[ polish ] = "Usu";
+ Text[ japanese ] = "폜(~D)";
+ Text[ chinese_simplified ] = "ɾ(~D)";
+ Text[ chinese_traditional ] = "R(~D)";
+ Text[ greek ] = "~";
+ Text[ korean ] = "(~D)";
+ Text[ arabic ] = "";
+ Text[ turkish ] = "~Sil";
+ Text[ language_user1 ] = " ";
+ };
+ MenuItem { Separator = TRUE ; };
+ MenuItem
+ {
+ Identifier = SV_MENU_EDIT_SELECTALL ;
+ Text = "Alles aus~whlen" ;
+ Text [ English ] = "Select ~All" ;
+ Text [ norwegian ] = "Select ~All" ;
+ Text [ italian ] = "Seleziona tutto" ;
+ Text [ portuguese_brazilian ] = "Selecionar ~Tudo" ;
+ Text [ portuguese ] = "Seleccionar ~tudo" ;
+ Text [ finnish ] = "Valitse ~kaikki" ;
+ Text [ danish ] = "~Marker alt" ;
+ Text [ french ] = "Slectio~nner tout" ;
+ Text [ swedish ] = "Markera ~allt" ;
+ Text [ dutch ] = "~Alles selecteren" ;
+ Text [ spanish ] = "Seleccionar ~todo" ;
+ Text [ english_us ] = "Select ~All" ;
+ Text[ russian ] = " ";
+ Text[ polish ] = "Zaznacz wszystko";
+ Text[ japanese ] = "ׂđI(~A)";
+ Text[ chinese_simplified ] = "ȫѡ(~A)";
+ Text[ chinese_traditional ] = "(~A)";
+ Text[ greek ] = " ~";
+ Text[ korean ] = "ü(~A)";
+ Text[ arabic ] = " ";
+ Text[ turkish ] = "Tmn se";
+ Text[ language_user1 ] = " ";
+ };
+ MenuItem { Separator = TRUE ; };
+ MenuItem
+ {
+ Identifier = SV_MENU_EDIT_INSERTSYMBOL;
+ Text = "~Sonderzeichen einfgen...";
+ Text [ English ] = "insert ~symbol...";
+ TEXT[ italian ] = "Inserisci caratteri speciali...";
+ TEXT[ portuguese_brazilian ] = "~Sonderzeichen einfgen...";
+ TEXT[ portuguese ] = "~Inserir carcter especial...";
+ TEXT[ danish ] = "Indst ~specialtegn...";
+ TEXT[ french ] = "~Insrer des caractres spciaux...";
+ TEXT[ swedish ] = "Infoga ~specialtecken...";
+ TEXT[ dutch ] = "~Speciaal teken invoegen...";
+ TEXT[ spanish ] = "Insertar ~smbolo...";
+ TEXT[ english_us ] = "~Special Character...";
+ TEXT[ russian ] = "~ ...";
+ TEXT[ polish ] = "Wstaw znaki specjalne...";
+ TEXT[ japanese ] = "LƓꕶ̑}(~S)...";
+
+ TEXT[ chinese_simplified ] = "ַ(~S)...";
+ TEXT[ chinese_traditional ] = "JSr(~S)...";
+ TEXT[ greek ] = "~ ...";
+ TEXT[ korean ] = "Ưȣ(~S)...";
+ TEXT[ arabic ] = " ";
+ TEXT[ turkish ] = "zel karakter ekle...";
+ TEXT[ language_user1 ] = " ";
+ };
+ };
+};
diff --git a/vcl/source/src/stdtext.src b/vcl/source/src/stdtext.src
new file mode 100644
index 000000000000..2a7ca53c68fd
--- /dev/null
+++ b/vcl/source/src/stdtext.src
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * $RCSfile: stdtext.src,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_STDTEXT_SRC
+
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+
+String SV_STDTEXT_SERVICENOTAVAILABLE
+{
+ Text = "Eine Komponente (%s) konnte nicht geladen werden.\nBitte starten Sie das Setup und fhren Sie eine Reparatur durch.";
+ Text [ English ] = "The component (%s) could not be loaded.\nPlease start setup in repair mode." ;
+ Text[ english_us ] = "The component (%s) could not be loaded.\nPlease start setup with the repair option.";
+ Text[ portuguese ] = "Impossvel carregar o componente (%s).\nReinicie o setup com a opo 'Reparao'.";
+ Text[ russian ] = " (%s) .\n .";
+ Text[ dutch ] = "Een component (%s) kon niet worden geladen.\nStart setup opnieuw met de optie Reparatie.";
+ Text[ french ] = "Impossible de charger l'un des composants (%s).\nVeuillez redmarrer le programme d'installation (Setup) et excuter une rparation.";
+ Text[ spanish ] = "No se pudo cargar un componente (%s).\nInicie por favor el programa de instalacin y ejecute una Reparacin.";
+ Text[ italian ] = "Impossibile caricare il componente (%s).\nRiavviate il setup e eseguite la riparazione.";
+ Text[ danish ] = "Det var ikke muligt at indlse en komponent (%s).\nStart venligst installationsprogrammet (Setup) og udfr en reparation.";
+ Text[ swedish ] = "Komponenten (%s) kunde inte laddas.\nVar vnlig och starta setupen och gr en reparation.";
+ Text[ polish ] = "Skadnika (%s) nie mona zaadowa.\nProsz rozpocznij program instalacyjny i przeprowad napraw.";
+ Text[ portuguese_brazilian ] = "The component (%s) could not be loaded.\nPlease start setup with the option -repair.";
+ Text[ japanese ] = "߰(%s)͓ǂݍ݂ł܂łB\nı߂JnďCsĉB";
+ Text[ chinese_simplified ] = "޷װس򲿼(%s)\nѡװѡ޲";
+ Text[ chinese_traditional ] = "Lk˸{(%s)C\nбzܦw˵{׽ƿﶵC";
+ Text[ arabic ] = " (%s).\n ϡ .";
+ Text[ greek ] = " (%s)\n .";
+ Text[ korean ] = "Ʈ (%s) ε ʾҽϴ.\n ɼǰħ Ͻʽÿ.";
+ Text[ turkish ] = "Bir bileen (%s) yklenemedi.\nSetup programn altrp onarnz.";
+ Text[ language_user1 ] = " ";
+};
diff --git a/vcl/source/window/accel.cxx b/vcl/source/window/accel.cxx
new file mode 100644
index 000000000000..f039c311ef28
--- /dev/null
+++ b/vcl/source/window/accel.cxx
@@ -0,0 +1,775 @@
+/*************************************************************************
+ *
+ * $RCSfile: accel.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_ACCEL_CXX
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _TABLE_HXX
+#include <tools/table.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_ACCEL_H
+#include <accel.h>
+#endif
+#ifndef _SV_ACCEL_HXX
+#include <accel.hxx>
+#endif
+#ifndef _RC_H
+#include <rc.h>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+DECLARE_TABLE( ImplAccelTable, ImplAccelEntry* );
+DECLARE_LIST( ImplAccelList, ImplAccelEntry* );
+
+#define ACCELENTRY_NOTFOUND ((USHORT)0xFFFF)
+
+// =======================================================================
+
+class ImplAccelData
+{
+public:
+ ImplAccelTable maKeyTable; // Fuer KeyCodes, die mit einem Code erzeugt wurden
+ ImplAccelList maIdList; // Id-List
+};
+
+// =======================================================================
+
+DBG_NAME( Accelerator );
+
+// =======================================================================
+
+USHORT ImplAccelEntryGetIndex( ImplAccelList* pList, USHORT nId,
+ USHORT* pIndex = NULL )
+{
+ ULONG nLow;
+ ULONG nHigh;
+ ULONG nMid;
+ ULONG nCount = pList->Count();
+ USHORT nCompareId;
+
+ // Abpruefen, ob der erste Key groesser als der Vergleichskey ist
+ if ( !nCount || (nId < pList->GetObject( 0 )->mnId) )
+ {
+ if ( pIndex )
+ *pIndex = 0;
+ return ACCELENTRY_NOTFOUND;
+ }
+
+ // Binaeres Suchen
+ nLow = 0;
+ nHigh = nCount-1;
+ do
+ {
+ nMid = (nLow + nHigh) / 2;
+ nCompareId = pList->GetObject( nMid )->mnId;
+ if ( nId < nCompareId )
+ nHigh = nMid-1;
+ else
+ {
+ if ( nId > nCompareId )
+ nLow = nMid + 1;
+ else
+ return (USHORT)nMid;
+ }
+ }
+ while ( nLow <= nHigh );
+
+ if ( pIndex )
+ {
+ if ( nId > nCompareId )
+ *pIndex = (USHORT)(nMid+1);
+ else
+ *pIndex = (USHORT)nMid;
+ }
+
+ return ACCELENTRY_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplAccelEntryInsert( ImplAccelList* pList, ImplAccelEntry* pEntry )
+{
+ USHORT nInsIndex;
+ USHORT nIndex = ImplAccelEntryGetIndex( pList, pEntry->mnId, &nInsIndex );
+
+ if ( nIndex != ACCELENTRY_NOTFOUND )
+ {
+ do
+ {
+ nIndex++;
+ ImplAccelEntry* pTempEntry = pList->GetObject( nIndex );
+ if ( !pTempEntry || (pTempEntry->mnId != pEntry->mnId) )
+ break;
+ }
+ while ( nIndex < pList->Count() );
+
+ pList->Insert( pEntry, (ULONG)nIndex );
+ }
+ else
+ pList->Insert( pEntry, (ULONG)nInsIndex );
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplAccelEntryGetFirstPos( ImplAccelList* pList, USHORT nId )
+{
+ USHORT nIndex = ImplAccelEntryGetIndex( pList, nId );
+ if ( nIndex != ACCELENTRY_NOTFOUND )
+ {
+ while ( nIndex )
+ {
+ nIndex--;
+ if ( pList->GetObject( nIndex )->mnId != nId )
+ break;
+ }
+
+ if ( pList->GetObject( nIndex )->mnId != nId )
+ nIndex++;
+ }
+
+ return nIndex;
+}
+
+// =======================================================================
+
+void Accelerator::ImplInit()
+{
+ mnCurId = 0;
+ mnCurRepeat = 0;
+ mbIsCancel = FALSE;
+ mpDel = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplAccelEntry* Accelerator::ImplGetAccelData( const KeyCode& rKeyCode ) const
+{
+ return mpData->maKeyTable.Get( rKeyCode.GetFullKeyCode() );
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::ImplCopyData( ImplAccelData& rAccelData )
+{
+ // Tabellen kopieren
+ ImplAccelEntry* pEntry = rAccelData.maIdList.First();
+ while ( pEntry )
+ {
+ pEntry = new ImplAccelEntry( *pEntry );
+
+ // Folge-Accelerator, dann auch kopieren
+ if ( pEntry->mpAccel )
+ {
+ pEntry->mpAccel = new Accelerator( *(pEntry->mpAccel) );
+ pEntry->mpAutoAccel = pEntry->mpAccel;
+ }
+ else
+ pEntry->mpAutoAccel = NULL;
+
+ mpData->maKeyTable.Insert( (ULONG)pEntry->maKeyCode.GetFullKeyCode(), pEntry );
+ mpData->maIdList.Insert( pEntry, LIST_APPEND );
+
+ pEntry = rAccelData.maIdList.Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::ImplDeleteData()
+{
+ // Accelerator-Eintraege ueber die Id-Tabelle loeschen
+ ImplAccelEntry* pEntry = mpData->maIdList.First();
+ while ( pEntry )
+ {
+ // AutoResAccel zerstoeren
+ if ( pEntry->mpAutoAccel )
+ delete pEntry->mpAutoAccel;
+ delete pEntry;
+
+ pEntry = mpData->maIdList.Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::ImplInsertAccel( USHORT nItemId, const KeyCode& rKeyCode,
+ BOOL bEnable, Accelerator* pAutoAccel )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+ DBG_ASSERT( nItemId, "Accelerator::InsertItem(): ItemId == 0" );
+
+ if ( rKeyCode.IsFunction() )
+ {
+ USHORT nCode1;
+ USHORT nCode2;
+ USHORT nCode3;
+ ImplGetKeyCode( rKeyCode.GetFunction(), nCode1, nCode2, nCode3 );
+ if ( nCode1 )
+ ImplInsertAccel( nItemId, KeyCode( nCode1, nCode1 ), bEnable, pAutoAccel );
+ if ( nCode2 )
+ {
+ if ( pAutoAccel )
+ pAutoAccel = new Accelerator( *pAutoAccel );
+ ImplInsertAccel( nItemId, KeyCode( nCode2, nCode2 ), bEnable, pAutoAccel );
+ if ( nCode3 )
+ {
+ if ( pAutoAccel )
+ pAutoAccel = new Accelerator( *pAutoAccel );
+ ImplInsertAccel( nItemId, KeyCode( nCode3, nCode3 ), bEnable, pAutoAccel );
+ }
+ }
+ return;
+ }
+
+ // Neuen Eintrag holen und fuellen
+ ImplAccelEntry* pEntry = new ImplAccelEntry;
+ pEntry->mnId = nItemId;
+ pEntry->maKeyCode = rKeyCode;
+ pEntry->mpAccel = pAutoAccel;
+ pEntry->mpAutoAccel = pAutoAccel;
+ pEntry->mbEnabled = bEnable;
+
+ // Ab in die Tabellen
+ ULONG nCode = rKeyCode.GetFullKeyCode();
+ if ( !nCode )
+ {
+ DBG_ERROR( "Accelerator::InsertItem(): KeyCode with KeyCode 0 not allowed" );
+ delete pEntry;
+ }
+ else if ( !mpData->maKeyTable.Insert( nCode, pEntry ) )
+ {
+ DBG_ERROR1( "Accelerator::InsertItem(): KeyCode (Key: %lx) already exists", nCode );
+ delete pEntry;
+ }
+ else
+ ImplAccelEntryInsert( &(mpData->maIdList), pEntry );
+}
+
+// -----------------------------------------------------------------------
+
+Accelerator::Accelerator()
+{
+ DBG_CTOR( Accelerator, NULL );
+
+ ImplInit();
+ mpData = new ImplAccelData;
+}
+
+// -----------------------------------------------------------------------
+
+Accelerator::Accelerator( const Accelerator& rAccel ) :
+ maHelpStr( rAccel.maHelpStr ),
+ maCurKeyCode( rAccel.maCurKeyCode )
+{
+ DBG_CTOR( Accelerator, NULL );
+ DBG_CHKOBJ( &rAccel, Accelerator, NULL );
+
+ ImplInit();
+ mpData = new ImplAccelData;
+ ImplCopyData( *((ImplAccelData*)(rAccel.mpData)) );
+}
+
+// -----------------------------------------------------------------------
+
+Accelerator::Accelerator( const ResId& rResId )
+{
+ DBG_CTOR( Accelerator, NULL );
+
+ ImplInit();
+ mpData = new ImplAccelData;
+ rResId.SetRT( RSC_ACCEL );
+ ImplLoadRes( rResId );
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::ImplLoadRes( const ResId& rResId )
+{
+ GetRes( rResId );
+
+ maHelpStr = ReadStringRes();
+ USHORT nObjFollows = ReadShortRes();
+
+ for( USHORT i = 0; i < nObjFollows; i++ )
+ {
+ InsertItem( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Accelerator::~Accelerator()
+{
+ DBG_DTOR( Accelerator, NULL );
+
+ // AccelManager benachrichtigen, das Accelrator geloescht wurde
+ if ( mpDel )
+ *mpDel = TRUE;
+
+ ImplDeleteData();
+ delete mpData;
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::Activate()
+{
+ maActivateHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::Deactivate()
+{
+ maDeactivateHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::InsertItem( USHORT nItemId, const KeyCode& rKeyCode )
+{
+ ImplInsertAccel( nItemId, rKeyCode, TRUE, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::InsertItem( const ResId& rResId )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ USHORT nObjMask;
+ USHORT nAccelKeyId;
+ USHORT bDisable;
+ KeyCode aKeyCode;
+ BOOL bEnable = FALSE;
+ Accelerator* pAutoAccel = NULL;
+
+ GetRes( rResId.SetRT( RSC_ACCELITEM ) );
+ nObjMask = ReadShortRes();
+ nAccelKeyId = ReadShortRes();
+ bDisable = ReadShortRes();
+
+ if ( nObjMask & ACCELITEM_KEY )
+ {
+ // es wird ein neuer Kontext aufgespannt
+ RSHEADER_TYPE * pKeyCodeRes = (RSHEADER_TYPE *)GetClassRes();
+ ResId aResId( pKeyCodeRes );
+ aKeyCode = KeyCode( aResId );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
+ }
+
+ if ( nObjMask & ACCELITEM_ACCEL )
+ {
+ pAutoAccel = new Accelerator( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
+ }
+
+ ImplInsertAccel( nAccelKeyId, aKeyCode, !bDisable, pAutoAccel );
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::RemoveItem( USHORT nItemId )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ // Aus der Id-Liste entfernen
+ USHORT nIndex = ImplAccelEntryGetFirstPos( &(mpData->maIdList), nItemId );
+ if ( nIndex != ACCELENTRY_NOTFOUND )
+ {
+ USHORT nItemCount = GetItemCount();
+ do
+ {
+ ImplAccelEntry* pEntry = mpData->maIdList.GetObject( (ULONG)nIndex );
+ if ( pEntry && pEntry->mnId == nItemId )
+ {
+ mpData->maKeyTable.Remove( pEntry->maKeyCode.GetFullKeyCode() );
+ mpData->maIdList.Remove( (ULONG)nIndex );
+
+ // AutoResAccel zerstoeren
+ if ( pEntry->mpAutoAccel )
+ delete pEntry->mpAutoAccel;
+
+ delete pEntry;
+ }
+ else
+ break;
+ }
+ while ( nIndex < nItemCount );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::RemoveItem( const KeyCode rKeyCode )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = ImplGetAccelData( rKeyCode );
+ if ( pEntry )
+ {
+ // Aus der Id-Liste entfernen
+ USHORT nIndex = ImplAccelEntryGetFirstPos( &(mpData->maIdList), pEntry->mnId );
+ USHORT nItemCount = GetItemCount();
+ do
+ {
+ if ( mpData->maIdList.GetObject( (ULONG)nIndex ) == pEntry )
+ break;
+ nIndex++;
+ }
+ while ( nIndex < nItemCount );
+
+ mpData->maKeyTable.Remove( rKeyCode.GetFullKeyCode() );
+ mpData->maIdList.Remove( (ULONG)nIndex );
+
+ // AutoResAccel zerstoeren
+ if ( pEntry->mpAutoAccel )
+ delete pEntry->mpAutoAccel;
+
+ delete pEntry;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::Clear()
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplDeleteData();
+ mpData->maKeyTable.Clear();
+ mpData->maIdList.Clear();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Accelerator::GetItemCount() const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ return (USHORT)mpData->maIdList.Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Accelerator::GetItemId( USHORT nPos ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = mpData->maIdList.GetObject( (ULONG)nPos );
+ if ( pEntry )
+ return pEntry->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+KeyCode Accelerator::GetItemKeyCode( USHORT nPos ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = mpData->maIdList.GetObject( (ULONG)nPos );
+ if ( pEntry )
+ return pEntry->maKeyCode;
+ else
+ return KeyCode();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Accelerator::GetItemId( const KeyCode& rKeyCode ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = ImplGetAccelData( rKeyCode );
+ if ( pEntry )
+ return pEntry->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+KeyCode Accelerator::GetKeyCode( USHORT nItemId ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ USHORT nIndex = ImplAccelEntryGetFirstPos( &(mpData->maIdList), nItemId );
+ if ( nIndex != ACCELENTRY_NOTFOUND )
+ return mpData->maIdList.GetObject( (ULONG)nIndex )->maKeyCode;
+ else
+ return KeyCode();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Accelerator::IsIdValid( USHORT nItemId ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ USHORT nIndex = ImplAccelEntryGetIndex( &(mpData->maIdList), nItemId );
+ return (nIndex != ACCELENTRY_NOTFOUND);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Accelerator::IsKeyCodeValid( const KeyCode rKeyCode ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = ImplGetAccelData( rKeyCode );
+ return (pEntry != NULL);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Accelerator::Call( const KeyCode& rKeyCode, USHORT nRepeat )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = ImplGetAccelData( rKeyCode );
+ if ( pEntry )
+ {
+ if ( pEntry->mbEnabled )
+ {
+ BOOL bDel = FALSE;
+ mnCurId = pEntry->mnId;
+ maCurKeyCode = rKeyCode;
+ mnCurRepeat = nRepeat;
+ mpDel = &bDel;
+ Select();
+ if ( !bDel )
+ {
+ mnCurId = 0;
+ maCurKeyCode = KeyCode();
+ mnCurRepeat = 0;
+ }
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::SetAccel( USHORT nItemId, Accelerator* pAccel )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ USHORT nIndex = ImplAccelEntryGetFirstPos( &(mpData->maIdList), nItemId );
+ if ( nIndex != ACCELENTRY_NOTFOUND )
+ {
+ USHORT nItemCount = GetItemCount();
+ do
+ {
+ ImplAccelEntry* pEntry = mpData->maIdList.GetObject( (ULONG)nIndex );
+ if ( pEntry->mnId != nItemId )
+ break;
+
+ pEntry->mpAccel = pAccel;
+ nIndex++;
+ }
+ while ( nIndex < nItemCount );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Accelerator* Accelerator::GetAccel( USHORT nItemId ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ USHORT nIndex = ImplAccelEntryGetIndex( &(mpData->maIdList), nItemId );
+ if ( nIndex != ACCELENTRY_NOTFOUND )
+ return mpData->maIdList.GetObject( (ULONG)nIndex )->mpAccel;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::SetAccel( const KeyCode rKeyCode, Accelerator* pAccel )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = ImplGetAccelData( rKeyCode );
+ if ( pEntry )
+ pEntry->mpAccel = pAccel;
+}
+
+// -----------------------------------------------------------------------
+
+Accelerator* Accelerator::GetAccel( const KeyCode rKeyCode ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = ImplGetAccelData( rKeyCode );
+ if ( pEntry )
+ return pEntry->mpAccel;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::EnableItem( USHORT nItemId, BOOL bEnable )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ USHORT nIndex = ImplAccelEntryGetFirstPos( &(mpData->maIdList), nItemId );
+ if ( nIndex != ACCELENTRY_NOTFOUND )
+ {
+ USHORT nItemCount = GetItemCount();
+ do
+ {
+ ImplAccelEntry* pEntry = mpData->maIdList.GetObject( (ULONG)nIndex );
+ if ( pEntry->mnId != nItemId )
+ break;
+
+ pEntry->mbEnabled = bEnable;
+ nIndex++;
+ }
+ while ( nIndex < nItemCount );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Accelerator::IsItemEnabled( USHORT nItemId ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ USHORT nIndex = ImplAccelEntryGetIndex( &(mpData->maIdList), nItemId );
+ if ( nIndex != ACCELENTRY_NOTFOUND )
+ return mpData->maIdList.GetObject( (ULONG)nIndex )->mbEnabled;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Accelerator::EnableItem( const KeyCode rKeyCode, BOOL bEnable )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = ImplGetAccelData( rKeyCode );
+ if ( pEntry )
+ pEntry->mbEnabled = bEnable;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Accelerator::IsItemEnabled( const KeyCode rKeyCode ) const
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+
+ ImplAccelEntry* pEntry = ImplGetAccelData( rKeyCode );
+ if ( pEntry )
+ return pEntry->mbEnabled;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Accelerator& Accelerator::operator=( const Accelerator& rAccel )
+{
+ DBG_CHKTHIS( Accelerator, NULL );
+ DBG_CHKOBJ( &rAccel, Accelerator, NULL );
+
+ // Neue Daten zuweisen
+ maHelpStr = rAccel.maHelpStr;
+ maCurKeyCode = KeyCode();
+ mnCurId = 0;
+ mnCurRepeat = 0;
+ mbIsCancel = FALSE;
+
+ // Tabellen loeschen und kopieren
+ ImplDeleteData();
+ mpData->maKeyTable.Clear();
+ mpData->maIdList.Clear();
+ ImplCopyData( *((ImplAccelData*)(rAccel.mpData)) );
+
+ return *this;
+}
diff --git a/vcl/source/window/accmgr.cxx b/vcl/source/window/accmgr.cxx
new file mode 100644
index 000000000000..2cf39ae4cd9c
--- /dev/null
+++ b/vcl/source/window/accmgr.cxx
@@ -0,0 +1,318 @@
+/*************************************************************************
+ *
+ * $RCSfile: accmgr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_ACCMGR_CXX
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_ACCEL_H
+#include <accel.h>
+#endif
+#ifndef _SV_ACCEL_HXX
+#include <accel.hxx>
+#endif
+#ifndef _SV_ACCMGR_HXX
+#include <accmgr.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+DECLARE_LIST( ImplAccelList, Accelerator* );
+
+// =======================================================================
+
+DBG_NAMEEX( Accelerator );
+
+// =======================================================================
+
+ImplAccelManager::~ImplAccelManager()
+{
+ if ( mpAccelList )
+ delete mpAccelList;
+ if ( mpSequenceList )
+ delete mpSequenceList;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplAccelManager::InsertAccel( Accelerator* pAccel )
+{
+ if ( !mpAccelList )
+ mpAccelList = new ImplAccelList;
+ else
+ {
+ // Gibts den schon ?
+ if ( mpAccelList->GetPos( pAccel ) != LIST_ENTRY_NOTFOUND )
+ return FALSE;
+ }
+
+ // Am Anfang der Liste einfuegen
+ mpAccelList->Insert( pAccel, (ULONG)0 );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplAccelManager::RemoveAccel( Accelerator* pAccel )
+{
+ // Haben wir ueberhaupt eine Liste ?
+ if ( !mpAccelList )
+ return;
+
+ // Raus damit
+ mpAccelList->Remove( pAccel );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplAccelManager::EndSequence( BOOL bCancel )
+{
+ // Sind wir ueberhaupt in einer Sequenz ?
+ if ( !mpSequenceList )
+ return;
+
+ // Alle Deactivate-Handler der Acceleratoren in der Sequenz rufen
+ Accelerator* pTempAccel = mpSequenceList->First();
+ while( pTempAccel )
+ {
+ BOOL bDel = FALSE;
+ pTempAccel->mbIsCancel = bCancel;
+ pTempAccel->mpDel = &bDel;
+ pTempAccel->Deactivate();
+ if ( !bDel )
+ {
+ pTempAccel->mbIsCancel = FALSE;
+ pTempAccel->mpDel = NULL;
+ }
+
+ pTempAccel = mpSequenceList->Next();
+ }
+
+ // Sequenz-Liste loeschen
+ delete mpSequenceList;
+ mpSequenceList = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplAccelManager::IsAccelKey( const KeyCode& rKeyCode, USHORT nRepeat )
+{
+ Accelerator* pAccel;
+
+ // Haben wir ueberhaupt Acceleratoren ??
+ if ( !mpAccelList )
+ return FALSE;
+ if ( !mpAccelList->Count() )
+ return FALSE;
+
+ // Sind wir in einer Sequenz ?
+ if ( mpSequenceList )
+ {
+ pAccel = mpSequenceList->GetObject( 0 );
+ DBG_CHKOBJ( pAccel, Accelerator, NULL );
+
+ // Nicht Gefunden ?
+ if ( !pAccel )
+ {
+ // Sequenz abbrechen
+ FlushAccel();
+ return FALSE;
+ }
+
+ // Ist der Eintrag da drin ?
+ ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
+ if ( pEntry )
+ {
+ Accelerator* pNextAccel = pEntry->mpAccel;
+
+ // Ist da ein Accelerator hinter ?
+ if ( pNextAccel )
+ {
+ DBG_CHKOBJ( pNextAccel, Accelerator, NULL );
+
+ mpSequenceList->Insert( pNextAccel, (ULONG)0 );
+
+ // Activate-Handler vom Neuen rufen
+ pNextAccel->Activate();
+ return TRUE;
+ }
+ else
+ {
+ // Hat ihn schon !
+ if ( pEntry->mbEnabled )
+ {
+ // Sequence beenden (Deactivate-Handler vorher rufen)
+ EndSequence();
+
+ // Dem Accelerator das aktuelle Item setzen
+ // und Handler rufen
+ BOOL bDel = FALSE;
+ pAccel->maCurKeyCode = rKeyCode;
+ pAccel->mnCurId = pEntry->mnId;
+ pAccel->mnCurRepeat = nRepeat;
+ pAccel->mpDel = &bDel;
+ pAccel->Select();
+
+ // Hat Accel den Aufruf ueberlebt
+ if ( !bDel )
+ {
+ DBG_CHKOBJ( pAccel, Accelerator, NULL );
+ pAccel->maCurKeyCode = KeyCode();
+ pAccel->mnCurId = 0;
+ pAccel->mnCurRepeat = 0;
+ pAccel->mpDel = NULL;
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ // Sequenz abbrechen, weil Acceleraor disabled
+ // Taste wird weitergeleitet (ans System)
+ FlushAccel();
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ // Sequenz abbrechen wegen falscher Taste
+ FlushAccel();
+ return FALSE;
+ }
+ }
+
+ // Durch die Liste der Acceleratoren wuehlen
+ pAccel = mpAccelList->First();
+ while ( pAccel )
+ {
+ DBG_CHKOBJ( pAccel, Accelerator, NULL );
+
+ // Ist der Eintrag da drin ?
+ ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
+ if ( pEntry )
+ {
+ Accelerator* pNextAccel = pEntry->mpAccel;
+
+ // Ist da ein Accelerator hinter ?
+ if ( pNextAccel )
+ {
+ DBG_CHKOBJ( pNextAccel, Accelerator, NULL );
+
+ // Sequenz-Liste erzeugen
+ mpSequenceList = new ImplAccelList;
+ mpSequenceList->Insert( pAccel, (ULONG)0 );
+ mpSequenceList->Insert( pNextAccel, (ULONG)0 );
+
+ // Activate-Handler vom Neuen rufen
+ pNextAccel->Activate();
+
+ return TRUE;
+ }
+ else
+ {
+ // Hat ihn schon !
+ if ( pEntry->mbEnabled )
+ {
+ // Activate/Deactivate-Handler vorher rufen
+ pAccel->Activate();
+ pAccel->Deactivate();
+
+ // Dem Accelerator das aktuelle Item setzen
+ // und Handler rufen
+ BOOL bDel = FALSE;
+ pAccel->maCurKeyCode = rKeyCode;
+ pAccel->mnCurId = pEntry->mnId;
+ pAccel->mnCurRepeat = nRepeat;
+ pAccel->mpDel = &bDel;
+ pAccel->Select();
+
+ // Hat Accel den Aufruf ueberlebt
+ if ( !bDel )
+ {
+ DBG_CHKOBJ( pAccel, Accelerator, NULL );
+ pAccel->maCurKeyCode = KeyCode();
+ pAccel->mnCurId = 0;
+ pAccel->mnCurRepeat = 0;
+ pAccel->mpDel = NULL;
+ }
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+ }
+
+ // Nicht gefunden, vielleicht im naechsten Accelerator
+ pAccel = mpAccelList->Next();
+ }
+
+ return FALSE;
+}
diff --git a/vcl/source/window/brdwin.cxx b/vcl/source/window/brdwin.cxx
new file mode 100644
index 000000000000..651306cf1e3b
--- /dev/null
+++ b/vcl/source/window/brdwin.cxx
@@ -0,0 +1,3808 @@
+/*************************************************************************
+ *
+ * $RCSfile: brdwin.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_BRDWIN_CXX
+
+#ifdef REMOTE_APPSERVER
+#include <rmwindow.hxx>
+#endif
+
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_SYSWIN_HXX
+#include <syswin.hxx>
+#endif
+#ifndef _SV_DOCKWIN_HXX
+#include <dockwin.hxx>
+#endif
+#ifndef _SV_FLOATWIN_HXX
+#include <floatwin.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_GRADIENT_HXX
+#include <gradient.hxx>
+#endif
+#ifndef _SV_IMAGE_HXX
+#include <image.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+
+#include <tools/debug.hxx>
+
+#include <rvp.hxx>
+
+#pragma hdrstop
+
+using namespace ::com::sun::star::uno;
+
+// =======================================================================
+
+// -----------------------
+// - ImplBorderFrameData -
+// -----------------------
+
+struct ImplBorderFrameData
+{
+ ImplBorderWindow* mpBorderWindow;
+ OutputDevice* mpOutDev;
+ Rectangle maTitleRect;
+ Rectangle maPinRect;
+ Rectangle maCloseRect;
+ Rectangle maRollRect;
+ Rectangle maDockRect;
+ Rectangle maHideRect;
+ Rectangle maHelpRect;
+ Point maMouseOff;
+ long mnWidth;
+ long mnHeight;
+ long mnTrackX;
+ long mnTrackY;
+ long mnTrackWidth;
+ long mnTrackHeight;
+ long mnLeftBorder;
+ long mnTopBorder;
+ long mnRightBorder;
+ long mnBottomBorder;
+ long mnNoTitleTop;
+ long mnBorderSize;
+ long mnTitleHeight;
+ long mnTitleOff;
+ USHORT mnHitTest;
+ USHORT mnPinState;
+ USHORT mnCloseState;
+ USHORT mnRollState;
+ USHORT mnDockState;
+ USHORT mnHideState;
+ USHORT mnHelpState;
+ USHORT mnTitleType;
+ BOOL mbFloatWindow;
+ BOOL mbDragFull;
+};
+
+// =======================================================================
+
+static void ImplGetPinImage( USHORT nStyle, BOOL bPinIn, Image& rImage )
+{
+ // ImageListe laden, wenn noch nicht vorhanden
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->maCtrlData.mpPinImgList )
+ {
+ Bitmap aBmp( ResId( SV_RESID_BITMAP_PIN, ImplGetResMgr() ) );
+ pSVData->maCtrlData.mpPinImgList = new ImageList( aBmp, Color( 0x00, 0x00, 0xFF ), 4 );
+ }
+
+ // Image ermitteln und zurueckgeben
+ USHORT nId;
+ if ( nStyle & BUTTON_DRAW_PRESSED )
+ {
+ if ( bPinIn )
+ nId = 4;
+ else
+ nId = 3;
+ }
+ else
+ {
+ if ( bPinIn )
+ nId = 2;
+ else
+ nId = 1;
+ }
+ rImage = pSVData->maCtrlData.mpPinImgList->GetImage( nId );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCalcSymbolRect( Rectangle& rRect )
+{
+ // Den Rand den der Button in der nicht Default-Darstellung freilaesst,
+ // dazuaddieren, da wir diesen bei kleinen Buttons mit ausnutzen wollen
+ rRect.Left()--;
+ rRect.Top()--;
+ rRect.Right()++;
+ rRect.Bottom()++;
+
+ // Zwischen dem Symbol und dem Button-Rand lassen wir 5% Platz
+ long nExtraWidth = ((rRect.GetWidth()*50)+500)/1000;
+ long nExtraHeight = ((rRect.GetHeight()*50)+500)/1000;
+ rRect.Left() += nExtraWidth;
+ rRect.Right() -= nExtraWidth;
+ rRect.Top() += nExtraHeight;
+ rRect.Bottom() -= nExtraHeight;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawBrdWinSymbol( OutputDevice* pDev,
+ const Rectangle& rRect, SymbolType eSymbol )
+{
+ // Zwischen dem Symbol und dem Button lassen wir 5% Platz
+ DecorationView aDecoView( pDev );
+ Rectangle aTempRect = rRect;
+ Window::ImplCalcSymbolRect( aTempRect );
+ aDecoView.DrawSymbol( aTempRect, eSymbol,
+ pDev->GetSettings().GetStyleSettings().GetButtonTextColor(), 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawBrdWinSymbolButton( OutputDevice* pDev,
+ const Rectangle& rRect,
+ SymbolType eSymbol, USHORT nState )
+{
+ DecorationView aDecoView( pDev );
+ Rectangle aTempRect = aDecoView.DrawButton( rRect, nState );
+ ImplDrawBrdWinSymbol( pDev, aTempRect, eSymbol );
+}
+
+// =======================================================================
+
+// ------------------------
+// - ImplBorderWindowView -
+// ------------------------
+
+class ImplBorderWindowView
+{
+public:
+ virtual ~ImplBorderWindowView();
+
+ virtual BOOL MouseMove( const MouseEvent& rMEvt );
+ virtual BOOL MouseButtonDown( const MouseEvent& rMEvt );
+ virtual BOOL Tracking( const TrackingEvent& rTEvt );
+ virtual USHORT RequestHelp( const Point& rPos, Rectangle& rHelpRect );
+
+ virtual void Init( OutputDevice* pDev, long nWidth, long nHeight ) = 0;
+ virtual void GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const = 0;
+ virtual long CalcTitleWidth() const = 0;
+ virtual void DrawWindow( USHORT nDrawFlags ) = 0;
+
+ void ImplInitTitle( ImplBorderFrameData* pData );
+ USHORT ImplHitTest( ImplBorderFrameData* pData, const Point& rPos );
+ BOOL ImplMouseMove( ImplBorderFrameData* pData, const MouseEvent& rMEvt );
+ BOOL ImplMouseButtonDown( ImplBorderFrameData* pData, const MouseEvent& rMEvt );
+ BOOL ImplTracking( ImplBorderFrameData* pData, const TrackingEvent& rTEvt );
+ USHORT ImplRequestHelp( ImplBorderFrameData* pData, const Point& rPos, Rectangle& rHelpRect );
+ long ImplCalcTitleWidth( const ImplBorderFrameData* pData ) const;
+};
+
+// -----------------------------------------------------------------------
+
+ImplBorderWindowView::~ImplBorderWindowView()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplBorderWindowView::MouseMove( const MouseEvent& rMEvt )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplBorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplBorderWindowView::Tracking( const TrackingEvent& rTEvt )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplBorderWindowView::RequestHelp( const Point& rPos, Rectangle& rHelpRect )
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindowView::ImplInitTitle( ImplBorderFrameData* pData )
+{
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+
+ if ( !(pBorderWindow->GetStyle() & WB_MOVEABLE) ||
+ (pData->mnTitleType == BORDERWINDOW_TITLE_NONE) )
+ {
+ pData->mnTitleType = BORDERWINDOW_TITLE_NONE;
+ pData->mnTitleHeight = 0;
+ }
+ else
+ {
+ const StyleSettings& rStyleSettings = pData->mpOutDev->GetSettings().GetStyleSettings();
+ if ( pData->mnTitleType == BORDERWINDOW_TITLE_TEAROFF )
+ pData->mnTitleHeight = rStyleSettings.GetTearOffTitleHeight();
+ else
+ {
+ if ( pData->mnTitleType == BORDERWINDOW_TITLE_SMALL )
+ {
+ pBorderWindow->SetPointFont( rStyleSettings.GetFloatTitleFont() );
+ pData->mnTitleHeight = rStyleSettings.GetFloatTitleHeight();
+ }
+ else // pData->mnTitleType == BORDERWINDOW_TITLE_NORMAL
+ {
+ pBorderWindow->SetPointFont( rStyleSettings.GetTitleFont() );
+ pData->mnTitleHeight = rStyleSettings.GetTitleHeight();
+ }
+ long nTextHeight = pBorderWindow->GetTextHeight();
+ if ( nTextHeight > pData->mnTitleHeight )
+ pData->mnTitleHeight = nTextHeight;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplBorderWindowView::ImplHitTest( ImplBorderFrameData* pData, const Point& rPos )
+{
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+
+ if ( pData->maTitleRect.IsInside( rPos ) )
+ {
+ if ( pData->maCloseRect.IsInside( rPos ) )
+ return BORDERWINDOW_HITTEST_CLOSE;
+ else if ( pData->maRollRect.IsInside( rPos ) )
+ return BORDERWINDOW_HITTEST_ROLL;
+ else if ( pData->maDockRect.IsInside( rPos ) )
+ return BORDERWINDOW_HITTEST_DOCK;
+ else if ( pData->maHideRect.IsInside( rPos ) )
+ return BORDERWINDOW_HITTEST_HIDE;
+ else if ( pData->maHelpRect.IsInside( rPos ) )
+ return BORDERWINDOW_HITTEST_HELP;
+ else if ( pData->maPinRect.IsInside( rPos ) )
+ return BORDERWINDOW_HITTEST_PIN;
+ else
+ return BORDERWINDOW_HITTEST_TITLE;
+ }
+
+ if ( (pBorderWindow->GetStyle() & WB_SIZEABLE) &&
+ !pBorderWindow->mbRollUp )
+ {
+ long nSizeWidth = pData->mnNoTitleTop+pData->mnTitleHeight;
+ if ( nSizeWidth < 16 )
+ nSizeWidth = 16;
+ if ( rPos.X() < pData->mnLeftBorder )
+ {
+ if ( rPos.Y() < nSizeWidth )
+ return BORDERWINDOW_HITTEST_TOPLEFT;
+ else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
+ return BORDERWINDOW_HITTEST_BOTTOMLEFT;
+ else
+ return BORDERWINDOW_HITTEST_LEFT;
+ }
+ else if ( rPos.X() >= pData->mnWidth-pData->mnRightBorder )
+ {
+ if ( rPos.Y() < nSizeWidth )
+ return BORDERWINDOW_HITTEST_TOPRIGHT;
+ else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
+ return BORDERWINDOW_HITTEST_BOTTOMRIGHT;
+ else
+ return BORDERWINDOW_HITTEST_RIGHT;
+ }
+ else if ( rPos.Y() < pData->mnNoTitleTop )
+ {
+ if ( rPos.X() < nSizeWidth )
+ return BORDERWINDOW_HITTEST_TOPLEFT;
+ else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
+ return BORDERWINDOW_HITTEST_TOPRIGHT;
+ else
+ return BORDERWINDOW_HITTEST_TOP;
+ }
+ else if ( rPos.Y() >= pData->mnHeight-pData->mnBottomBorder )
+ {
+ if ( rPos.X() < nSizeWidth )
+ return BORDERWINDOW_HITTEST_BOTTOMLEFT;
+ else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
+ return BORDERWINDOW_HITTEST_BOTTOMRIGHT;
+ else
+ return BORDERWINDOW_HITTEST_BOTTOM;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplBorderWindowView::ImplMouseMove( ImplBorderFrameData* pData, const MouseEvent& rMEvt )
+{
+ Point aMousePos = rMEvt.GetPosPixel();
+ USHORT nHitTest = ImplHitTest( pData, aMousePos );
+ PointerStyle ePtrStyle = POINTER_ARROW;
+ if ( nHitTest & BORDERWINDOW_HITTEST_LEFT )
+ ePtrStyle = POINTER_WINDOW_WSIZE;
+ else if ( nHitTest & BORDERWINDOW_HITTEST_RIGHT )
+ ePtrStyle = POINTER_WINDOW_ESIZE;
+ else if ( nHitTest & BORDERWINDOW_HITTEST_TOP )
+ ePtrStyle = POINTER_WINDOW_NSIZE;
+ else if ( nHitTest & BORDERWINDOW_HITTEST_BOTTOM )
+ ePtrStyle = POINTER_WINDOW_SSIZE;
+ else if ( nHitTest & BORDERWINDOW_HITTEST_TOPLEFT )
+ ePtrStyle = POINTER_WINDOW_NWSIZE;
+ else if ( nHitTest & BORDERWINDOW_HITTEST_BOTTOMRIGHT )
+ ePtrStyle = POINTER_WINDOW_SESIZE;
+ else if ( nHitTest & BORDERWINDOW_HITTEST_TOPRIGHT )
+ ePtrStyle = POINTER_WINDOW_NESIZE;
+ else if ( nHitTest & BORDERWINDOW_HITTEST_BOTTOMLEFT )
+ ePtrStyle = POINTER_WINDOW_SWSIZE;
+ pData->mpBorderWindow->SetPointer( Pointer( ePtrStyle ) );
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplBorderWindowView::ImplMouseButtonDown( ImplBorderFrameData* pData, const MouseEvent& rMEvt )
+{
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+
+ if ( rMEvt.IsLeft() || rMEvt.IsRight() )
+ {
+ pData->maMouseOff = rMEvt.GetPosPixel();
+ pData->mnHitTest = ImplHitTest( pData, pData->maMouseOff );
+ USHORT nDragFullTest = 0;
+ if ( pData->mnHitTest )
+ {
+ BOOL bTracking = TRUE;
+ BOOL bHitTest = TRUE;
+
+ if ( pData->mnHitTest & BORDERWINDOW_HITTEST_CLOSE )
+ {
+ pData->mnCloseState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_CLOSE );
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_ROLL )
+ {
+ pData->mnRollState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_ROLL );
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_DOCK )
+ {
+ pData->mnDockState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_DOCK );
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_HIDE )
+ {
+ pData->mnHideState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_HIDE );
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_HELP )
+ {
+ pData->mnHelpState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_HELP );
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_PIN )
+ {
+ pData->mnPinState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_PIN );
+ }
+ else
+ {
+ if ( rMEvt.GetClicks() == 1 )
+ {
+ // Bei DockingWindows wollen wir Docking
+ if ( (pData->mnHitTest & BORDERWINDOW_HITTEST_TITLE) &&
+ pBorderWindow->ImplGetClientWindow()->ImplGetClientWindow() &&
+ pBorderWindow->ImplGetClientWindow()->ImplGetClientWindow()->ImplIsDockingWindow() )
+ {
+ if ( !pBorderWindow->mbRollUp )
+ {
+ Point aMousePos = pData->maMouseOff;
+ aMousePos.X() -= pData->mnLeftBorder;
+ aMousePos.Y() -= pData->mnTopBorder;
+ bTracking = !(((DockingWindow*)(pBorderWindow->ImplGetClientWindow()->ImplGetClientWindow()))->ImplStartDocking( aMousePos ));
+ }
+ }
+
+ if ( bTracking )
+ {
+ Point aPos = pBorderWindow->GetPosPixel();
+ Size aSize = pBorderWindow->GetOutputSizePixel();
+ pData->mnTrackX = aPos.X();
+ pData->mnTrackY = aPos.Y();
+ pData->mnTrackWidth = aSize.Width();
+ pData->mnTrackHeight = aSize.Height();
+
+ if ( pData->mnHitTest & BORDERWINDOW_HITTEST_TITLE )
+ nDragFullTest = DRAGFULL_OPTION_WINDOWMOVE;
+ else
+ nDragFullTest = DRAGFULL_OPTION_WINDOWSIZE;
+ }
+ }
+ else
+ {
+ bTracking = FALSE;
+
+ if ( (pData->mnHitTest & BORDERWINDOW_DRAW_TITLE) &&
+ ((rMEvt.GetClicks() % 2) == 0) )
+ {
+ pData->mnHitTest = 0;
+ bHitTest = FALSE;
+
+ if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
+ {
+ SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
+ if ( pBorderWindow->mbDockBtn )
+ pClientWindow->TitleButtonClick( TITLE_BUTTON_DOCKING );
+ else if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
+ {
+ if ( pClientWindow->IsRollUp() )
+ pClientWindow->RollDown();
+ else
+ pClientWindow->RollUp();
+ pClientWindow->Roll();
+ }
+ }
+ }
+ }
+ }
+
+ if ( bTracking )
+ {
+ pData->mbDragFull = FALSE;
+ if ( nDragFullTest )
+ {
+ if ( pBorderWindow->GetSettings().GetStyleSettings().GetDragFullOptions() & nDragFullTest )
+ pData->mbDragFull = TRUE;
+ else
+ {
+ pBorderWindow->ImplUpdateAll();
+ pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
+ }
+ }
+ pBorderWindow->StartTracking();
+ }
+ else if ( bHitTest )
+ pData->mnHitTest = 0;
+ }
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplBorderWindowView::ImplTracking( ImplBorderFrameData* pData, const TrackingEvent& rTEvt )
+{
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ USHORT nHitTest = pData->mnHitTest;
+ pData->mnHitTest = 0;
+
+ if ( nHitTest & BORDERWINDOW_HITTEST_CLOSE )
+ {
+ if ( pData->mnCloseState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnCloseState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_CLOSE );
+
+ // Bei Abbruch kein Click-Handler rufen
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
+ ((SystemWindow*)pBorderWindow->ImplGetClientWindow())->Close();
+ }
+ }
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_ROLL )
+ {
+ if ( pData->mnRollState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnRollState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_ROLL );
+
+ // Bei Abbruch kein Click-Handler rufen
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
+ {
+ SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
+ if ( pClientWindow->IsRollUp() )
+ pClientWindow->RollDown();
+ else
+ pClientWindow->RollUp();
+ pClientWindow->Roll();
+ }
+ }
+ }
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_DOCK )
+ {
+ if ( pData->mnDockState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnDockState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_DOCK );
+
+ // Bei Abbruch kein Click-Handler rufen
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
+ {
+ SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
+ pClientWindow->TitleButtonClick( TITLE_BUTTON_DOCKING );
+ }
+ }
+ }
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_HIDE )
+ {
+ if ( pData->mnHideState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnHideState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_HIDE );
+
+ // Bei Abbruch kein Click-Handler rufen
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
+ {
+ SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
+ pClientWindow->TitleButtonClick( TITLE_BUTTON_HIDE );
+ }
+ }
+ }
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_HELP )
+ {
+ if ( pData->mnHelpState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnHelpState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_HELP );
+
+ // Bei Abbruch kein Click-Handler rufen
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ }
+ }
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_PIN )
+ {
+ if ( pData->mnPinState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnPinState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_PIN );
+
+ // Bei Abbruch kein Click-Handler rufen
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
+ {
+ SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
+ pClientWindow->SetPin( !pClientWindow->IsPined() );
+ pClientWindow->Pin();
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( pData->mbDragFull )
+ {
+ // Bei Abbruch alten Zustand wieder herstellen
+ if ( rTEvt.IsTrackingCanceled() )
+ pBorderWindow->SetPosSizePixel( Point( pData->mnTrackX, pData->mnTrackY ), Size( pData->mnTrackWidth, pData->mnTrackHeight ) );
+ }
+ else
+ {
+ pBorderWindow->HideTracking();
+ if ( !rTEvt.IsTrackingCanceled() )
+ pBorderWindow->SetPosSizePixel( Point( pData->mnTrackX, pData->mnTrackY ), Size( pData->mnTrackWidth, pData->mnTrackHeight ) );
+ }
+
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ if ( pBorderWindow->ImplGetClientWindow()->ImplIsFloatingWindow() )
+ {
+ if ( ((FloatingWindow*)pBorderWindow->ImplGetClientWindow())->IsInPopupMode() )
+ ((FloatingWindow*)pBorderWindow->ImplGetClientWindow())->EndPopupMode( FLOATWIN_POPUPMODEEND_TEAROFF );
+ }
+ }
+ }
+ }
+ else if ( !rTEvt.GetMouseEvent().IsSynthetic() )
+ {
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+
+ if ( pData->mnHitTest & BORDERWINDOW_HITTEST_CLOSE )
+ {
+ if ( pData->maCloseRect.IsInside( aMousePos ) )
+ {
+ if ( !(pData->mnCloseState & BUTTON_DRAW_PRESSED) )
+ {
+ pData->mnCloseState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_CLOSE );
+ }
+ }
+ else
+ {
+ if ( pData->mnCloseState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnCloseState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_CLOSE );
+ }
+ }
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_ROLL )
+ {
+ if ( pData->maRollRect.IsInside( aMousePos ) )
+ {
+ if ( !(pData->mnRollState & BUTTON_DRAW_PRESSED) )
+ {
+ pData->mnRollState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_ROLL );
+ }
+ }
+ else
+ {
+ if ( pData->mnRollState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnRollState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_ROLL );
+ }
+ }
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_DOCK )
+ {
+ if ( pData->maDockRect.IsInside( aMousePos ) )
+ {
+ if ( !(pData->mnDockState & BUTTON_DRAW_PRESSED) )
+ {
+ pData->mnDockState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_DOCK );
+ }
+ }
+ else
+ {
+ if ( pData->mnDockState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnDockState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_DOCK );
+ }
+ }
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_HIDE )
+ {
+ if ( pData->maHideRect.IsInside( aMousePos ) )
+ {
+ if ( !(pData->mnHideState & BUTTON_DRAW_PRESSED) )
+ {
+ pData->mnHideState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_HIDE );
+ }
+ }
+ else
+ {
+ if ( pData->mnHideState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnHideState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_HIDE );
+ }
+ }
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_HELP )
+ {
+ if ( pData->maHelpRect.IsInside( aMousePos ) )
+ {
+ if ( !(pData->mnHelpState & BUTTON_DRAW_PRESSED) )
+ {
+ pData->mnHelpState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_HELP );
+ }
+ }
+ else
+ {
+ if ( pData->mnHelpState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnHelpState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_HELP );
+ }
+ }
+ }
+ else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_PIN )
+ {
+ if ( pData->maPinRect.IsInside( aMousePos ) )
+ {
+ if ( !(pData->mnPinState & BUTTON_DRAW_PRESSED) )
+ {
+ pData->mnPinState |= BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_PIN );
+ }
+ }
+ else
+ {
+ if ( pData->mnPinState & BUTTON_DRAW_PRESSED )
+ {
+ pData->mnPinState &= ~BUTTON_DRAW_PRESSED;
+ DrawWindow( BORDERWINDOW_DRAW_PIN );
+ }
+ }
+ }
+ else
+ {
+ Point aFrameMousePos = pBorderWindow->ImplOutputToFrame( aMousePos );
+ Size aFrameSize = pBorderWindow->ImplGetFrameWindow()->GetOutputSizePixel();
+ if ( aFrameMousePos.X() < 0 )
+ aFrameMousePos.X() = 0;
+ if ( aFrameMousePos.Y() < 0 )
+ aFrameMousePos.Y() = 0;
+ if ( aFrameMousePos.X() > aFrameSize.Width()-1 )
+ aFrameMousePos.X() = aFrameSize.Width()-1;
+ if ( aFrameMousePos.Y() > aFrameSize.Height()-1 )
+ aFrameMousePos.Y() = aFrameSize.Height()-1;
+ aMousePos = pBorderWindow->ImplFrameToOutput( aFrameMousePos );
+
+ aMousePos.X() -= pData->maMouseOff.X();
+ aMousePos.Y() -= pData->maMouseOff.Y();
+
+ if ( pData->mnHitTest & BORDERWINDOW_HITTEST_TITLE )
+ {
+ Point aPos = pBorderWindow->GetPosPixel();
+ aPos.X() += aMousePos.X();
+ aPos.Y() += aMousePos.Y();
+ if ( pData->mbDragFull )
+ {
+ pBorderWindow->SetPosPixel( aPos );
+ pBorderWindow->ImplUpdateAll();
+ pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
+ }
+ else
+ {
+ pData->mnTrackX = aPos.X();
+ pData->mnTrackY = aPos.Y();
+ pBorderWindow->ShowTracking( Rectangle( pBorderWindow->ScreenToOutputPixel( aPos ), pBorderWindow->GetOutputSizePixel() ), SHOWTRACK_BIG );
+ }
+ }
+ else
+ {
+ Point aPos = pBorderWindow->GetPosPixel();
+ Size aSize = pBorderWindow->GetSizePixel();
+ Rectangle aNewRect( aPos, aSize );
+ long nOldWidth = aSize.Width();
+ long nOldHeight = aSize.Height();
+ long nBorderWidth = pData->mnLeftBorder+pData->mnRightBorder;
+ long nBorderHeight = pData->mnTopBorder+pData->mnBottomBorder;
+ long nMinWidth = pBorderWindow->mnMinWidth+nBorderWidth;
+ long nMinHeight = pBorderWindow->mnMinHeight+nBorderHeight;
+ long nMinWidth2 = nBorderWidth;
+
+ if ( pData->mnTitleHeight )
+ {
+ nMinWidth2 += 4;
+
+ if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
+ nMinWidth2 += pData->maCloseRect.GetWidth();
+ }
+ if ( nMinWidth2 > nMinWidth )
+ nMinWidth = nMinWidth2;
+ if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_LEFT | BORDERWINDOW_HITTEST_TOPLEFT | BORDERWINDOW_HITTEST_BOTTOMLEFT) )
+ {
+ aNewRect.Left() += aMousePos.X();
+ if ( aNewRect.GetWidth() < nMinWidth )
+ aNewRect.Left() = aNewRect.Right()-nMinWidth+1;
+ }
+ else if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_RIGHT | BORDERWINDOW_HITTEST_TOPRIGHT | BORDERWINDOW_HITTEST_BOTTOMRIGHT) )
+ {
+ aNewRect.Right() += aMousePos.X();
+ if ( aNewRect.GetWidth() < nMinWidth )
+ aNewRect.Right() = aNewRect.Left()+nMinWidth+1;
+ }
+ if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_TOP | BORDERWINDOW_HITTEST_TOPLEFT | BORDERWINDOW_HITTEST_TOPRIGHT) )
+ {
+ aNewRect.Top() += aMousePos.Y();
+ if ( aNewRect.GetHeight() < nMinHeight )
+ aNewRect.Top() = aNewRect.Bottom()-nMinHeight+1;
+ }
+ else if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_BOTTOM | BORDERWINDOW_HITTEST_BOTTOMLEFT | BORDERWINDOW_HITTEST_BOTTOMRIGHT) )
+ {
+ aNewRect.Bottom() += aMousePos.Y();
+ if ( aNewRect.GetHeight() < nMinHeight )
+ aNewRect.Bottom() = aNewRect.Top()+nMinHeight+1;
+ }
+
+ // Bei SystemWindows rufen wir den Resizing-Handler
+ if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
+ {
+ // Groesse fuer Resizing-Aufruf anpassen
+ aSize = aNewRect.GetSize();
+ aSize.Width() -= nBorderWidth;
+ aSize.Height() -= nBorderHeight;
+ ((SystemWindow*)pBorderWindow->ImplGetClientWindow())->Resizing( aSize );
+ aSize.Width() += nBorderWidth;
+ aSize.Height() += nBorderHeight;
+ if ( aSize.Width() < nMinWidth )
+ aSize.Width() = nMinWidth;
+ if ( aSize.Height() < nMinHeight )
+ aSize.Height() = nMinHeight;
+ if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_LEFT | BORDERWINDOW_HITTEST_TOPLEFT | BORDERWINDOW_HITTEST_BOTTOMLEFT) )
+ aNewRect.Left() = aNewRect.Right()-aSize.Width()+1;
+ else
+ aNewRect.Right() = aNewRect.Left()+aSize.Width()-1;
+ if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_TOP | BORDERWINDOW_HITTEST_TOPLEFT | BORDERWINDOW_HITTEST_TOPRIGHT) )
+ aNewRect.Top() = aNewRect.Bottom()-aSize.Height()+1;
+ else
+ aNewRect.Bottom() = aNewRect.Top()+aSize.Height()-1;
+ }
+
+ if ( pData->mbDragFull )
+ {
+ pBorderWindow->SetPosSizePixel( aNewRect.Left(), aNewRect.Top(),
+ aNewRect.GetWidth(), aNewRect.GetHeight(), WINDOW_POSSIZE_POSSIZE );
+ pBorderWindow->ImplUpdateAll();
+ pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
+ if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_RIGHT | BORDERWINDOW_HITTEST_TOPRIGHT | BORDERWINDOW_HITTEST_BOTTOMRIGHT) )
+ pData->maMouseOff.X() += aNewRect.GetWidth()-nOldWidth;
+ if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_BOTTOM | BORDERWINDOW_HITTEST_BOTTOMLEFT | BORDERWINDOW_HITTEST_BOTTOMRIGHT) )
+ pData->maMouseOff.Y() += aNewRect.GetHeight()-nOldHeight;
+ }
+ else
+ {
+ pData->mnTrackX = aNewRect.Left();
+ pData->mnTrackY = aNewRect.Top();
+ pData->mnTrackWidth = aNewRect.GetWidth();
+ pData->mnTrackHeight = aNewRect.GetHeight();
+ pBorderWindow->ShowTracking( Rectangle( pBorderWindow->ScreenToOutputPixel( aNewRect.TopLeft() ), aNewRect.GetSize() ), SHOWTRACK_BIG );
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplBorderWindowView::ImplRequestHelp( ImplBorderFrameData* pData,
+ const Point& rPos,
+ Rectangle& rHelpRect )
+{
+ USHORT nHelpId = 0;
+ USHORT nHitTest = ImplHitTest( pData, rPos );
+ if ( nHitTest )
+ {
+ if ( nHitTest & BORDERWINDOW_HITTEST_CLOSE )
+ {
+ nHelpId = SV_HELPTEXT_CLOSE;
+ rHelpRect = pData->maCloseRect;
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_ROLL )
+ {
+ if ( pData->mpBorderWindow->mbRollUp )
+ nHelpId = SV_HELPTEXT_ROLLDOWN;
+ else
+ nHelpId = SV_HELPTEXT_ROLLUP;
+ rHelpRect = pData->maRollRect;
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_DOCK )
+ {
+ nHelpId = SV_HELPTEXT_MAXIMIZE;
+ rHelpRect = pData->maDockRect;
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_HIDE )
+ {
+ nHelpId = SV_HELPTEXT_MINIMIZE;
+ rHelpRect = pData->maHideRect;
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_HELP )
+ {
+ nHelpId = SV_HELPTEXT_HELP;
+ rHelpRect = pData->maHelpRect;
+ }
+ else if ( nHitTest & BORDERWINDOW_HITTEST_PIN )
+ {
+ nHelpId = SV_HELPTEXT_ALWAYSVISIBLE;
+ rHelpRect = pData->maPinRect;
+ }
+ }
+
+ return nHelpId;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplBorderWindowView::ImplCalcTitleWidth( const ImplBorderFrameData* pData ) const
+{
+ // kein sichtbarer Title, dann auch keine Breite
+ if ( !pData->mnTitleHeight )
+ return 0;
+
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+ long nTitleWidth = pBorderWindow->GetTextWidth( pBorderWindow->GetText() )+6;
+ nTitleWidth += pData->maPinRect.GetWidth();
+ nTitleWidth += pData->maCloseRect.GetWidth();
+ nTitleWidth += pData->maRollRect.GetWidth();
+ nTitleWidth += pData->maDockRect.GetWidth();
+ nTitleWidth += pData->maHideRect.GetWidth();
+ nTitleWidth += pData->maHelpRect.GetWidth();
+ nTitleWidth += pData->mnLeftBorder+pData->mnRightBorder;
+ return nTitleWidth;
+}
+
+// =======================================================================
+
+// --------------------------
+// - ImplNoBorderWindowView -
+// --------------------------
+
+class ImplNoBorderWindowView : public ImplBorderWindowView
+{
+public:
+ ImplNoBorderWindowView( ImplBorderWindow* pBorderWindow );
+
+ virtual void Init( OutputDevice* pDev, long nWidth, long nHeight );
+ virtual void GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const;
+ virtual long CalcTitleWidth() const;
+ virtual void DrawWindow( USHORT nDrawFlags );
+};
+
+// =======================================================================
+
+ImplNoBorderWindowView::ImplNoBorderWindowView( ImplBorderWindow* pBorderWindow )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ImplNoBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ImplNoBorderWindowView::GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const
+{
+ rLeftBorder = 0;
+ rTopBorder = 0;
+ rRightBorder = 0;
+ rBottomBorder = 0;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplNoBorderWindowView::CalcTitleWidth() const
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplNoBorderWindowView::DrawWindow( USHORT nDrawFlags )
+{
+}
+
+// =======================================================================
+
+// -----------------------------
+// - ImplSmallBorderWindowView -
+// -----------------------------
+
+class ImplSmallBorderWindowView : public ImplBorderWindowView
+{
+ ImplBorderWindow* mpBorderWindow;
+ OutputDevice* mpOutDev;
+ long mnWidth;
+ long mnHeight;
+ long mnLeftBorder;
+ long mnTopBorder;
+ long mnRightBorder;
+ long mnBottomBorder;
+
+public:
+ ImplSmallBorderWindowView( ImplBorderWindow* pBorderWindow );
+
+ virtual void Init( OutputDevice* pOutDev, long nWidth, long nHeight );
+ virtual void GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const;
+ virtual long CalcTitleWidth() const;
+ virtual void DrawWindow( USHORT nDrawFlags );
+};
+
+// =======================================================================
+
+ImplSmallBorderWindowView::ImplSmallBorderWindowView( ImplBorderWindow* pBorderWindow )
+{
+ mpBorderWindow = pBorderWindow;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSmallBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
+{
+ mpOutDev = pDev;
+ mnWidth = nWidth;
+ mnHeight = nHeight;
+
+ USHORT nBorderStyle = mpBorderWindow->GetBorderStyle();
+ if ( nBorderStyle & WINDOW_BORDER_NOBORDER )
+ {
+ mnLeftBorder = 0;
+ mnTopBorder = 0;
+ mnRightBorder = 0;
+ mnBottomBorder = 0;
+ }
+ else
+ {
+ USHORT nStyle = FRAME_DRAW_NODRAW;
+ // Wenn Border umgesetzt wurde oder BorderWindow ein Frame-Fenster
+ // ist, dann Border nach aussen
+ if ( (nBorderStyle & WINDOW_BORDER_DOUBLEOUT) || mpBorderWindow->mbSmallOutBorder )
+ nStyle |= FRAME_DRAW_DOUBLEOUT;
+ else
+ nStyle |= FRAME_DRAW_DOUBLEIN;
+ if ( nBorderStyle & WINDOW_BORDER_MONO )
+ nStyle |= FRAME_DRAW_MONO;
+
+ DecorationView aDecoView( mpOutDev );
+ Rectangle aRect( 0, 0, 10, 10 );
+ Rectangle aCalcRect = aDecoView.DrawFrame( aRect, nStyle );
+ mnLeftBorder = aCalcRect.Left();
+ mnTopBorder = aCalcRect.Top();
+ mnRightBorder = aRect.Right()-aCalcRect.Right();
+ mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSmallBorderWindowView::GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const
+{
+ rLeftBorder = mnLeftBorder;
+ rTopBorder = mnTopBorder;
+ rRightBorder = mnRightBorder;
+ rBottomBorder = mnBottomBorder;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplSmallBorderWindowView::CalcTitleWidth() const
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSmallBorderWindowView::DrawWindow( USHORT nDrawFlags )
+{
+ USHORT nBorderStyle = mpBorderWindow->GetBorderStyle();
+ if ( nBorderStyle & WINDOW_BORDER_NOBORDER )
+ return;
+
+ if ( nDrawFlags & BORDERWINDOW_DRAW_FRAME )
+ {
+ if ( nBorderStyle & WINDOW_BORDER_ACTIVE )
+ {
+ Color aColor = mpOutDev->GetSettings().GetStyleSettings().GetHighlightColor();
+ mpOutDev->SetLineColor();
+ mpOutDev->SetFillColor( aColor );
+ mpOutDev->DrawRect( Rectangle( 0, 0, mnWidth-1, mnTopBorder ) );
+ mpOutDev->DrawRect( Rectangle( 0, mnHeight-mnBottomBorder, mnWidth-1, mnHeight-1 ) );
+ mpOutDev->DrawRect( Rectangle( 0, 0, mnLeftBorder, mnHeight-1 ) );
+ mpOutDev->DrawRect( Rectangle( mnWidth-mnRightBorder, 0, mnWidth-1, mnHeight-1 ) );
+ }
+ else
+ {
+ USHORT nStyle = 0;
+ // Wenn Border umgesetzt wurde oder BorderWindow ein Frame-Fenster
+ // ist, dann Border nach aussen
+ if ( (nBorderStyle & WINDOW_BORDER_DOUBLEOUT) || mpBorderWindow->mbSmallOutBorder )
+ nStyle |= FRAME_DRAW_DOUBLEOUT;
+ else
+ nStyle |= FRAME_DRAW_DOUBLEIN;
+ if ( nBorderStyle & WINDOW_BORDER_MONO )
+ nStyle |= FRAME_DRAW_MONO;
+
+ DecorationView aDecoView( mpOutDev );
+ Point aTmpPoint;
+ Rectangle aInRect( aTmpPoint, Size( mnWidth, mnHeight ) );
+ aDecoView.DrawFrame( aInRect, nStyle );
+ }
+ }
+}
+
+// =======================================================================
+
+// ---------------------------
+// - ImplStdBorderWindowView -
+// ---------------------------
+
+class ImplStdBorderWindowView : public ImplBorderWindowView
+{
+ ImplBorderFrameData maFrameData;
+ VirtualDevice* mpATitleVirDev;
+ VirtualDevice* mpDTitleVirDev;
+
+public:
+ ImplStdBorderWindowView( ImplBorderWindow* pBorderWindow );
+ ~ImplStdBorderWindowView();
+
+ virtual BOOL MouseMove( const MouseEvent& rMEvt );
+ virtual BOOL MouseButtonDown( const MouseEvent& rMEvt );
+ virtual BOOL Tracking( const TrackingEvent& rTEvt );
+ virtual USHORT RequestHelp( const Point& rPos, Rectangle& rHelpRect );
+
+ virtual void Init( OutputDevice* pDev, long nWidth, long nHeight );
+ virtual void GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const;
+ virtual long CalcTitleWidth() const;
+ virtual void DrawWindow( USHORT nDrawFlags );
+};
+
+// =======================================================================
+
+ImplStdBorderWindowView::ImplStdBorderWindowView( ImplBorderWindow* pBorderWindow )
+{
+ maFrameData.mpBorderWindow = pBorderWindow;
+ maFrameData.mbDragFull = FALSE;
+ maFrameData.mnHitTest = 0;
+ maFrameData.mnPinState = 0;
+ maFrameData.mnCloseState = 0;
+ maFrameData.mnRollState = 0;
+ maFrameData.mnDockState = 0;
+ maFrameData.mnHideState = 0;
+ maFrameData.mnHelpState = 0;
+
+ mpATitleVirDev = NULL;
+ mpDTitleVirDev = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplStdBorderWindowView::~ImplStdBorderWindowView()
+{
+ if ( mpATitleVirDev )
+ delete mpATitleVirDev;
+ if ( mpDTitleVirDev )
+ delete mpDTitleVirDev;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplStdBorderWindowView::MouseMove( const MouseEvent& rMEvt )
+{
+ return ImplMouseMove( &maFrameData, rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplStdBorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ return ImplMouseButtonDown( &maFrameData, rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplStdBorderWindowView::Tracking( const TrackingEvent& rTEvt )
+{
+ return ImplTracking( &maFrameData, rTEvt );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplStdBorderWindowView::RequestHelp( const Point& rPos, Rectangle& rHelpRect )
+{
+ return ImplRequestHelp( &maFrameData, rPos, rHelpRect );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplStdBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
+{
+ ImplBorderFrameData* pData = &maFrameData;
+ ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ DecorationView aDecoView( pDev );
+ Rectangle aRect( 0, 0, 10, 10 );
+ Rectangle aCalcRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEOUT | FRAME_DRAW_NODRAW );
+
+ pData->mpOutDev = pDev;
+ pData->mnWidth = nWidth;
+ pData->mnHeight = nHeight;
+
+ pData->mnTitleType = pBorderWindow->mnTitleType;
+ pData->mbFloatWindow = pBorderWindow->mbFloatWindow;
+
+ if ( !(pBorderWindow->GetStyle() & WB_MOVEABLE) || (pData->mnTitleType == BORDERWINDOW_TITLE_NONE) )
+ pData->mnBorderSize = 0;
+ else if ( pData->mnTitleType == BORDERWINDOW_TITLE_TEAROFF )
+ pData->mnBorderSize = 0;
+ else
+ pData->mnBorderSize = rStyleSettings.GetBorderSize();
+ pData->mnLeftBorder = aCalcRect.Left();
+ pData->mnTopBorder = aCalcRect.Top();
+ pData->mnRightBorder = aRect.Right()-aCalcRect.Right();
+ pData->mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
+ pData->mnLeftBorder += pData->mnBorderSize;
+ pData->mnTopBorder += pData->mnBorderSize;
+ pData->mnRightBorder += pData->mnBorderSize;
+ pData->mnBottomBorder += pData->mnBorderSize;
+ pData->mnNoTitleTop = pData->mnTopBorder;
+
+ ImplInitTitle( &maFrameData );
+ if ( pData->mnTitleHeight )
+ {
+ pData->maTitleRect.Left() = pData->mnLeftBorder;
+ pData->maTitleRect.Right() = nWidth-pData->mnRightBorder-1;
+ pData->maTitleRect.Top() = pData->mnTopBorder;
+ pData->maTitleRect.Bottom() = pData->maTitleRect.Top()+pData->mnTitleHeight-1;
+
+ if ( pData->mnTitleType & (BORDERWINDOW_TITLE_NORMAL | BORDERWINDOW_TITLE_SMALL) )
+ {
+ long nLeft = pData->maTitleRect.Left();
+ long nRight = pData->maTitleRect.Right();
+ long nItemTop = pData->maTitleRect.Top();
+ long nItemBottom = pData->maTitleRect.Bottom();
+ nLeft += 1;
+ nRight -= 3;
+ nItemTop += 2;
+ nItemBottom -= 2;
+
+ if ( pBorderWindow->GetStyle() & WB_PINABLE )
+ {
+ Image aImage;
+ ImplGetPinImage( 0, 0, aImage );
+ pData->maPinRect.Top() = nItemTop;
+ pData->maPinRect.Bottom() = nItemBottom;
+ pData->maPinRect.Left() = nLeft;
+ pData->maPinRect.Right() = pData->maPinRect.Left()+aImage.GetSizePixel().Width();
+ nLeft += pData->maPinRect.GetWidth()+3;
+ }
+
+ if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
+ {
+ pData->maCloseRect.Top() = nItemTop;
+ pData->maCloseRect.Bottom() = nItemBottom;
+ pData->maCloseRect.Right() = nRight;
+ pData->maCloseRect.Left() = pData->maCloseRect.Right()-pData->maCloseRect.GetHeight()+1;
+ nRight -= pData->maCloseRect.GetWidth()+3;
+ }
+
+ if ( pBorderWindow->mbDockBtn )
+ {
+ pData->maDockRect.Top() = nItemTop;
+ pData->maDockRect.Bottom() = nItemBottom;
+ pData->maDockRect.Right() = nRight;
+ pData->maDockRect.Left() = pData->maDockRect.Right()-pData->maDockRect.GetHeight()+1;
+ nRight -= pData->maDockRect.GetWidth();
+ if ( !pBorderWindow->mbHideBtn &&
+ !(pBorderWindow->GetStyle() & WB_ROLLABLE) )
+ nRight -= 3;
+ }
+
+ if ( pBorderWindow->mbHideBtn )
+ {
+ pData->maHideRect.Top() = nItemTop;
+ pData->maHideRect.Bottom() = nItemBottom;
+ pData->maHideRect.Right() = nRight;
+ pData->maHideRect.Left() = pData->maHideRect.Right()-pData->maHideRect.GetHeight()+1;
+ nRight -= pData->maHideRect.GetWidth();
+ if ( !(pBorderWindow->GetStyle() & WB_ROLLABLE) )
+ nRight -= 3;
+ }
+
+ if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
+ {
+ pData->maRollRect.Top() = nItemTop;
+ pData->maRollRect.Bottom() = nItemBottom;
+ pData->maRollRect.Right() = nRight;
+ pData->maRollRect.Left() = pData->maRollRect.Right()-pData->maRollRect.GetHeight()+1;
+ nRight -= pData->maRollRect.GetWidth();
+ }
+
+ if ( pBorderWindow->mbHelpBtn )
+ {
+ pData->maHelpRect.Top() = nItemTop;
+ pData->maHelpRect.Bottom() = nItemBottom;
+ pData->maHelpRect.Right() = nRight;
+ pData->maHelpRect.Left() = pData->maHelpRect.Right()-pData->maHelpRect.GetHeight()+1;
+ nRight -= pData->maHelpRect.GetWidth()+3;
+ }
+ }
+ else
+ {
+ pData->maPinRect.SetEmpty();
+ pData->maCloseRect.SetEmpty();
+ pData->maDockRect.SetEmpty();
+ pData->maHideRect.SetEmpty();
+ pData->maRollRect.SetEmpty();
+ pData->maHelpRect.SetEmpty();
+ }
+
+ pData->mnTopBorder += pData->mnTitleHeight;
+ }
+ else
+ {
+ pData->maTitleRect.SetEmpty();
+ pData->maPinRect.SetEmpty();
+ pData->maCloseRect.SetEmpty();
+ pData->maDockRect.SetEmpty();
+ pData->maHideRect.SetEmpty();
+ pData->maRollRect.SetEmpty();
+ pData->maHelpRect.SetEmpty();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplStdBorderWindowView::GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const
+{
+ rLeftBorder = maFrameData.mnLeftBorder;
+ rTopBorder = maFrameData.mnTopBorder;
+ rRightBorder = maFrameData.mnRightBorder;
+ rBottomBorder = maFrameData.mnBottomBorder;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplStdBorderWindowView::CalcTitleWidth() const
+{
+ return ImplCalcTitleWidth( &maFrameData );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplStdBorderWindowView::DrawWindow( USHORT nDrawFlags )
+{
+ ImplBorderFrameData* pData = &maFrameData;
+ OutputDevice* pDev = pData->mpOutDev;
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+ Point aTmpPoint;
+ Rectangle aInRect( aTmpPoint, Size( pData->mnWidth, pData->mnHeight ) );
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ DecorationView aDecoView( pDev );
+ USHORT nStyle;
+ BOOL bActive = pBorderWindow->IsDisplayActive();
+
+ // Draw Frame
+ if ( nDrawFlags & BORDERWINDOW_DRAW_FRAME )
+ nStyle = 0;
+ else
+ nStyle = FRAME_DRAW_NODRAW;
+ aInRect = aDecoView.DrawFrame( aInRect, FRAME_DRAW_DOUBLEOUT | nStyle );
+
+ // Draw Border
+ pDev->SetLineColor();
+ long nBorderSize = pData->mnBorderSize;
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_BORDER) && nBorderSize )
+ {
+ if ( bActive )
+ pDev->SetFillColor( rStyleSettings.GetActiveBorderColor() );
+ else
+ pDev->SetFillColor( rStyleSettings.GetDeactiveBorderColor() );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Top() ),
+ Size( aInRect.GetWidth(), nBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Top()+nBorderSize ),
+ Size( nBorderSize, aInRect.GetHeight()-nBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Bottom()-nBorderSize+1 ),
+ Size( aInRect.GetWidth(), nBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( aInRect.Right()-nBorderSize+1, aInRect.Top()+nBorderSize ),
+ Size( nBorderSize, aInRect.GetHeight()-nBorderSize ) ) );
+ }
+
+ // Draw Title
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_TITLE) && !pData->maTitleRect.IsEmpty() )
+ {
+ aInRect = pData->maTitleRect;
+
+ Color aColor2;
+ if ( bActive )
+ {
+ pDev->SetFillColor( rStyleSettings.GetActiveColor() );
+ pDev->SetTextColor( rStyleSettings.GetActiveTextColor() );
+ aColor2 = rStyleSettings.GetActiveColor2();
+ }
+ else
+ {
+ pDev->SetFillColor( rStyleSettings.GetDeactiveColor() );
+ pDev->SetTextColor( rStyleSettings.GetDeactiveTextColor() );
+ aColor2 = rStyleSettings.GetDeactiveColor2();
+ }
+#ifndef REMOTE_APPSERVER
+ BOOL bDrawRect;
+ if ( pDev->GetColorCount() >= 256 )
+ {
+ Point aTempPoint;
+ Size aRectSize = aInRect.GetSize();
+ VirtualDevice* pVirDev;
+ if ( bActive )
+ pVirDev = mpATitleVirDev;
+ else
+ pVirDev = mpDTitleVirDev;
+ bDrawRect = FALSE;
+ if ( !pVirDev || (aRectSize != pVirDev->GetOutputSizePixel()) )
+ {
+ if ( !pVirDev )
+ {
+ pVirDev = new VirtualDevice( *pDev );
+ if ( bActive )
+ mpATitleVirDev = pVirDev;
+ else
+ mpDTitleVirDev = pVirDev;
+ }
+
+ Gradient aGradient( GRADIENT_LINEAR, pDev->GetFillColor(), aColor2 );
+ aGradient.SetAngle( 900 );
+ aGradient.SetBorder( 50 );
+ if ( pVirDev->SetOutputSizePixel( aRectSize ) )
+ pVirDev->DrawGradient( Rectangle( aTempPoint, aRectSize ), aGradient );
+ else
+ bDrawRect = TRUE;
+ }
+
+ if ( !bDrawRect )
+ {
+ pDev->DrawOutDev( aInRect.TopLeft(), aRectSize,
+ aTempPoint, aRectSize, *pVirDev );
+ }
+ }
+ else
+ bDrawRect = TRUE;
+
+ if ( bDrawRect )
+#endif
+ pDev->DrawRect( aInRect );
+
+ if ( pData->mnTitleType != BORDERWINDOW_TITLE_TEAROFF )
+ {
+ aInRect.Left() += 2;
+ aInRect.Right() -= 2;
+
+ if ( !pData->maPinRect.IsEmpty() )
+ aInRect.Left() = pData->maPinRect.Right()+2;
+
+ if ( !pData->maHelpRect.IsEmpty() )
+ aInRect.Right() = pData->maHelpRect.Left()-2;
+ else if ( !pData->maRollRect.IsEmpty() )
+ aInRect.Right() = pData->maRollRect.Left()-2;
+ else if ( !pData->maHideRect.IsEmpty() )
+ aInRect.Right() = pData->maHideRect.Left()-2;
+ else if ( !pData->maDockRect.IsEmpty() )
+ aInRect.Right() = pData->maDockRect.Left()-2;
+ else if ( !pData->maCloseRect.IsEmpty() )
+ aInRect.Right() = pData->maCloseRect.Left()-2;
+ pDev->DrawText( aInRect, pBorderWindow->GetText(),
+ TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER |
+ TEXT_DRAW_ENDELLIPSIS | TEXT_DRAW_CLIP );
+ }
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_CLOSE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maCloseRect.IsEmpty() )
+ ImplDrawBrdWinSymbolButton( pDev, pData->maCloseRect, SYMBOL_CLOSE, pData->mnCloseState );
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_DOCK) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maDockRect.IsEmpty() )
+ ImplDrawBrdWinSymbolButton( pDev, pData->maDockRect, SYMBOL_DOCK, pData->mnDockState );
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_HIDE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maHideRect.IsEmpty() )
+ ImplDrawBrdWinSymbolButton( pDev, pData->maHideRect, SYMBOL_HIDE, pData->mnHideState );
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_ROLL) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maRollRect.IsEmpty() )
+ {
+ SymbolType eType;
+ if ( pBorderWindow->mbRollUp )
+ eType = SYMBOL_ROLLDOWN;
+ else
+ eType = SYMBOL_ROLLUP;
+ ImplDrawBrdWinSymbolButton( pDev, pData->maRollRect, eType, pData->mnRollState );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_HELP) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maHelpRect.IsEmpty() )
+ ImplDrawBrdWinSymbolButton( pDev, pData->maHelpRect, SYMBOL_HELP, pData->mnHelpState );
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_PIN) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maPinRect.IsEmpty() )
+ {
+ Image aImage;
+ ImplGetPinImage( pData->mnPinState, pBorderWindow->mbPined, aImage );
+ Size aImageSize = aImage.GetSizePixel();
+ long nRectHeight = pData->maPinRect.GetHeight();
+ if ( nRectHeight < aImageSize.Height() )
+ {
+ pDev->DrawImage( Point( pData->maPinRect.Left(), pData->maPinRect.Top() ),
+ Size( aImageSize.Width(), nRectHeight ),
+ aImage );
+ }
+ else
+ {
+ pDev->DrawImage( Point( pData->maPinRect.Left(),
+ pData->maPinRect.Top()+(nRectHeight-aImageSize.Height())/2 ),
+ aImage );
+ }
+ }
+}
+
+// =======================================================================
+
+// ---------------------------
+// - ImplOS2BorderWindowView -
+// ---------------------------
+
+class ImplOS2BorderWindowView : public ImplBorderWindowView
+{
+ ImplBorderFrameData maFrameData;
+
+public:
+ ImplOS2BorderWindowView( ImplBorderWindow* pBorderWindow );
+ ~ImplOS2BorderWindowView();
+
+ virtual BOOL MouseMove( const MouseEvent& rMEvt );
+ virtual BOOL MouseButtonDown( const MouseEvent& rMEvt );
+ virtual BOOL Tracking( const TrackingEvent& rTEvt );
+ virtual USHORT RequestHelp( const Point& rPos, Rectangle& rHelpRect );
+
+ virtual void Init( OutputDevice* pDev, long nWidth, long nHeight );
+ virtual void GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const;
+ virtual long CalcTitleWidth() const;
+ virtual void DrawWindow( USHORT nDrawFlags );
+
+ Rectangle DrawOS2TitleButton( const Rectangle& rRect, USHORT nStyle );
+};
+
+// Aus decoview.cxx
+void ImplDrawOS2Symbol( OutputDevice* pDev, const Rectangle& rRect,
+ USHORT nStyle, BOOL bClose );
+
+// =======================================================================
+
+ImplOS2BorderWindowView::ImplOS2BorderWindowView( ImplBorderWindow* pBorderWindow )
+{
+ maFrameData.mpBorderWindow = pBorderWindow;
+ maFrameData.mbDragFull = FALSE;
+ maFrameData.mnHitTest = 0;
+ maFrameData.mnPinState = 0;
+ maFrameData.mnCloseState = 0;
+ maFrameData.mnRollState = 0;
+ maFrameData.mnDockState = 0;
+ maFrameData.mnHideState = 0;
+ maFrameData.mnHelpState = 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImplOS2BorderWindowView::~ImplOS2BorderWindowView()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplOS2BorderWindowView::MouseMove( const MouseEvent& rMEvt )
+{
+ return ImplMouseMove( &maFrameData, rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplOS2BorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ return ImplMouseButtonDown( &maFrameData, rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplOS2BorderWindowView::Tracking( const TrackingEvent& rTEvt )
+{
+ return ImplTracking( &maFrameData, rTEvt );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplOS2BorderWindowView::RequestHelp( const Point& rPos, Rectangle& rHelpRect )
+{
+ return ImplRequestHelp( &maFrameData, rPos, rHelpRect );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplOS2BorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
+{
+ ImplBorderFrameData* pData = &maFrameData;
+ ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ DecorationView aDecoView( pDev );
+ Rectangle aRect( 0, 0, 10, 10 );
+ Rectangle aCalcRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEOUT | FRAME_DRAW_NODRAW );
+
+ pData->mpOutDev = pDev;
+ pData->mnWidth = nWidth;
+ pData->mnHeight = nHeight;
+
+ pData->mnTitleType = pBorderWindow->mnTitleType;
+ pData->mbFloatWindow = pBorderWindow->mbFloatWindow;
+
+ if ( !(pBorderWindow->GetStyle() & WB_MOVEABLE) || (pData->mnTitleType == BORDERWINDOW_TITLE_NONE) )
+ pData->mnBorderSize = 0;
+ else if ( pData->mnTitleType == BORDERWINDOW_TITLE_TEAROFF )
+ pData->mnBorderSize = 0;
+ else
+ pData->mnBorderSize = rStyleSettings.GetBorderSize();
+ pData->mnLeftBorder = aCalcRect.Left();
+ pData->mnTopBorder = aCalcRect.Top();
+ pData->mnRightBorder = aRect.Right()-aCalcRect.Right();
+ pData->mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
+ pData->mnLeftBorder += pData->mnBorderSize;
+ pData->mnTopBorder += pData->mnBorderSize;
+ pData->mnRightBorder += pData->mnBorderSize;
+ pData->mnBottomBorder += pData->mnBorderSize;
+ pData->mnNoTitleTop = pData->mnTopBorder;
+
+ ImplInitTitle( &maFrameData );
+ if ( pData->mnTitleHeight )
+ {
+ // Wegen 3D-Border bei aktiver Darstellung
+ if ( pData->mnTitleType != BORDERWINDOW_TITLE_TEAROFF )
+ {
+ long nTextHeight = pBorderWindow->GetTextHeight();
+ nTextHeight += 2;
+ if ( nTextHeight > pData->mnTitleHeight )
+ pData->mnTitleHeight = nTextHeight;
+ }
+
+ pData->maTitleRect.Left() = pData->mnLeftBorder;
+ pData->maTitleRect.Right() = nWidth-pData->mnRightBorder-1;
+ pData->maTitleRect.Top() = pData->mnTopBorder;
+ pData->maTitleRect.Bottom() = pData->maTitleRect.Top()+pData->mnTitleHeight-1;
+
+ if ( pData->mnTitleType & (BORDERWINDOW_TITLE_NORMAL | BORDERWINDOW_TITLE_SMALL) )
+ {
+ long nLeft = pData->maTitleRect.Left();
+ long nRight = pData->maTitleRect.Right();
+ long nItemTop = pData->maTitleRect.Top();
+ long nItemBottom = pData->maTitleRect.Bottom();
+
+ if ( pBorderWindow->mbHelpBtn )
+ {
+ pData->maHelpRect.Top() = nItemTop;
+ pData->maHelpRect.Bottom() = nItemBottom;
+ pData->maHelpRect.Left() = nLeft;
+ pData->maHelpRect.Right() = pData->maHelpRect.Left()+pData->maHelpRect.GetHeight()-1;
+ nLeft += pData->maHelpRect.GetWidth();
+ }
+
+ if ( pBorderWindow->GetStyle() & WB_PINABLE )
+ {
+ nLeft += 2;
+ Image aImage;
+ ImplGetPinImage( 0, 0, aImage );
+ pData->maPinRect.Top() = nItemTop;
+ pData->maPinRect.Bottom() = nItemBottom;
+ pData->maPinRect.Left() = nLeft;
+ pData->maPinRect.Right() = pData->maPinRect.Left()+aImage.GetSizePixel().Width();
+ nLeft += pData->maPinRect.GetWidth();
+ }
+
+ if ( pBorderWindow->mbDockBtn )
+ {
+ pData->maDockRect.Top() = nItemTop;
+ pData->maDockRect.Bottom() = nItemBottom;
+ pData->maDockRect.Right() = nRight;
+ pData->maDockRect.Left() = pData->maDockRect.Right()-pData->maDockRect.GetHeight()+1;
+ nRight -= pData->maDockRect.GetWidth();
+ }
+
+ if ( pBorderWindow->mbHideBtn )
+ {
+ pData->maHideRect.Top() = nItemTop;
+ pData->maHideRect.Bottom() = nItemBottom;
+ pData->maHideRect.Right() = nRight;
+ pData->maHideRect.Left() = pData->maHideRect.Right()-pData->maHideRect.GetHeight()+1;
+ nRight -= pData->maHideRect.GetWidth();
+ }
+
+ if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
+ {
+ pData->maRollRect.Top() = nItemTop;
+ pData->maRollRect.Bottom() = nItemBottom;
+ pData->maRollRect.Right() = nRight;
+ pData->maRollRect.Left() = pData->maRollRect.Right()-pData->maRollRect.GetHeight()+1;
+ nRight -= pData->maRollRect.GetWidth();
+ }
+
+ if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
+ {
+ pData->maCloseRect.Top() = nItemTop;
+ pData->maCloseRect.Bottom() = nItemBottom;
+ pData->maCloseRect.Right() = nRight;
+ pData->maCloseRect.Left() = pData->maCloseRect.Right()-pData->maCloseRect.GetHeight()+1;
+ nRight -= pData->maCloseRect.GetWidth();
+ }
+ }
+ else
+ {
+ pData->maPinRect.SetEmpty();
+ pData->maCloseRect.SetEmpty();
+ pData->maDockRect.SetEmpty();
+ pData->maHideRect.SetEmpty();
+ pData->maRollRect.SetEmpty();
+ pData->maHelpRect.SetEmpty();
+ }
+
+ pData->mnTopBorder += pData->mnTitleHeight;
+ }
+ else
+ {
+ pData->maTitleRect.SetEmpty();
+ pData->maPinRect.SetEmpty();
+ pData->maCloseRect.SetEmpty();
+ pData->maDockRect.SetEmpty();
+ pData->maHideRect.SetEmpty();
+ pData->maRollRect.SetEmpty();
+ pData->maHelpRect.SetEmpty();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplOS2BorderWindowView::GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const
+{
+ rLeftBorder = maFrameData.mnLeftBorder;
+ rTopBorder = maFrameData.mnTopBorder;
+ rRightBorder = maFrameData.mnRightBorder;
+ rBottomBorder = maFrameData.mnBottomBorder;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplOS2BorderWindowView::CalcTitleWidth() const
+{
+ return ImplCalcTitleWidth( &maFrameData );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplOS2BorderWindowView::DrawWindow( USHORT nDrawFlags )
+{
+ ImplBorderFrameData* pData = &maFrameData;
+ OutputDevice* pDev = pData->mpOutDev;
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+ Point aTmpPoint;
+ Rectangle aInRect( aTmpPoint, Size( pData->mnWidth, pData->mnHeight ) );
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ DecorationView aDecoView( pDev );
+ USHORT nStyle;
+ BOOL bActive = pBorderWindow->IsDisplayActive();
+
+ // Draw Frame
+ if ( nDrawFlags & BORDERWINDOW_DRAW_FRAME )
+ nStyle = 0;
+ else
+ nStyle = FRAME_DRAW_NODRAW;
+ aInRect = aDecoView.DrawFrame( aInRect, FRAME_DRAW_DOUBLEOUT | nStyle );
+
+ // Draw Border
+ pDev->SetLineColor();
+ long nBorderSize = pData->mnBorderSize;
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_BORDER) && nBorderSize )
+ {
+ if ( bActive )
+ pDev->SetFillColor( rStyleSettings.GetActiveBorderColor() );
+ else
+ pDev->SetFillColor( rStyleSettings.GetDeactiveBorderColor() );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Top() ),
+ Size( aInRect.GetWidth(), nBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Top()+nBorderSize ),
+ Size( nBorderSize, aInRect.GetHeight()-nBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Bottom()-nBorderSize+1 ),
+ Size( aInRect.GetWidth(), nBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( aInRect.Right()-nBorderSize+1, aInRect.Top()+nBorderSize ),
+ Size( nBorderSize, aInRect.GetHeight()-nBorderSize ) ) );
+ }
+
+ // Draw Title
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_TITLE) && !pData->maTitleRect.IsEmpty() )
+ {
+ aInRect = pData->maTitleRect;
+
+ if ( !pData->maHelpRect.IsEmpty() )
+ aInRect.Left() = pData->maHelpRect.Right()+1;
+
+ if ( !pData->maCloseRect.IsEmpty() )
+ aInRect.Right() = pData->maCloseRect.Left()-1;
+ else if ( !pData->maRollRect.IsEmpty() )
+ aInRect.Right() = pData->maRollRect.Left()-1;
+ else if ( !pData->maHideRect.IsEmpty() )
+ aInRect.Right() = pData->maHideRect.Left()-1;
+ else if ( !pData->maDockRect.IsEmpty() )
+ aInRect.Right() = pData->maDockRect.Left()-1;
+
+ if ( bActive )
+ {
+ pDev->SetFillColor( rStyleSettings.GetActiveColor() );
+ pDev->SetTextColor( rStyleSettings.GetActiveTextColor() );
+ }
+ else
+ {
+ pDev->SetFillColor( rStyleSettings.GetDeactiveColor() );
+ pDev->SetTextColor( rStyleSettings.GetDeactiveTextColor() );
+ }
+ pDev->DrawRect( aInRect );
+
+ if ( pData->mnTitleType != BORDERWINDOW_TITLE_TEAROFF )
+ {
+ Rectangle aOrgInRect = aInRect;
+
+ if ( !pData->maPinRect.IsEmpty() )
+ aInRect.Left() = pData->maPinRect.Right();
+
+ aInRect.Left() += 2;
+ aInRect.Right() -= 2;
+
+ pDev->DrawText( aInRect, pBorderWindow->GetText(),
+ TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER |
+ TEXT_DRAW_ENDELLIPSIS | TEXT_DRAW_CLIP );
+
+ if ( bActive )
+ aDecoView.DrawFrame( aOrgInRect, rStyleSettings.GetShadowColor(), rStyleSettings.GetLightColor() );
+ }
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_CLOSE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maCloseRect.IsEmpty() )
+ {
+ Rectangle aRect = DrawOS2TitleButton( pData->maCloseRect, pData->mnCloseState );
+ ImplDrawOS2Symbol( pDev, aRect, pData->mnCloseState, TRUE );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_DOCK) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maDockRect.IsEmpty() )
+ {
+ Rectangle aRect = DrawOS2TitleButton( pData->maDockRect, pData->mnDockState );
+ ImplDrawOS2Symbol( pDev, aRect, pData->mnDockState, FALSE );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_HIDE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maHideRect.IsEmpty() )
+ {
+ Rectangle aRect = DrawOS2TitleButton( pData->maHideRect, pData->mnHideState );
+ aRect.Left() += 2;
+ aRect.Top() += 2;
+ aRect.Right() -= 2;
+ aRect.Bottom() -= 2;
+ ImplDrawOS2Symbol( pDev, aRect, pData->mnHideState, FALSE );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_ROLL) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maRollRect.IsEmpty() )
+ {
+ Rectangle aRect = DrawOS2TitleButton( pData->maRollRect, pData->mnRollState );
+ if ( !pBorderWindow->mbRollUp )
+ aRect.Bottom() = aRect.Top()+6;
+ ImplDrawOS2Symbol( pDev, aRect, pData->mnRollState, FALSE );
+ if ( pBorderWindow->mbRollUp )
+ {
+ aRect.Left() += 3;
+ aRect.Top() += 3;
+ aRect.Right() -= 3;
+ aRect.Bottom() -= 3;
+ pDev->SetFillColor();
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ else
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( aRect.TopLeft(), aRect.TopRight() );
+ aRect.Top()++;
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ else
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( aRect.TopLeft(), aRect.TopRight() );
+ }
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_HELP) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maHelpRect.IsEmpty() )
+ {
+ Rectangle aRect = DrawOS2TitleButton( pData->maHelpRect, pData->mnHelpState );
+ ImplDrawBrdWinSymbol( pDev, aRect, SYMBOL_HELP );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_PIN) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maPinRect.IsEmpty() )
+ {
+ Image aImage;
+ ImplGetPinImage( pData->mnPinState, pBorderWindow->mbPined, aImage );
+ Size aImageSize = aImage.GetSizePixel();
+ long nRectHeight = pData->maPinRect.GetHeight();
+ if ( nRectHeight < aImageSize.Height() )
+ {
+ pDev->DrawImage( Point( pData->maPinRect.Left(), pData->maPinRect.Top() ),
+ Size( aImageSize.Width(), nRectHeight ),
+ aImage );
+ }
+ else
+ {
+ pDev->DrawImage( Point( pData->maPinRect.Left(),
+ pData->maPinRect.Top()+(nRectHeight-aImageSize.Height())/2 ),
+ aImage );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle ImplOS2BorderWindowView::DrawOS2TitleButton( const Rectangle& rRect, USHORT )
+{
+ OutputDevice* pDev = maFrameData.mpOutDev;
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ Rectangle aRect = rRect;
+
+ pDev->SetLineColor();
+ pDev->SetFillColor( rStyleSettings.GetFaceColor() );
+ pDev->DrawRect( aRect );
+
+ long nExtraWidth = ((aRect.GetWidth()*150)+500)/1000;
+ long nExtraHeight = ((aRect.GetHeight()*150)+500)/1000;
+ if ( !nExtraWidth )
+ nExtraWidth = 1;
+ if ( !nExtraHeight )
+ nExtraHeight = 1;
+ aRect.Left() += nExtraWidth;
+ aRect.Right() -= nExtraWidth;
+ aRect.Top() += nExtraHeight;
+ aRect.Bottom() -= nExtraHeight;
+ return aRect;
+}
+
+// =======================================================================
+
+// ---------------------------
+// - ImplUnxBorderWindowView -
+// ---------------------------
+
+class ImplUnxBorderWindowView : public ImplBorderWindowView
+{
+ ImplBorderFrameData maFrameData;
+
+public:
+ ImplUnxBorderWindowView( ImplBorderWindow* pBorderWindow );
+ ~ImplUnxBorderWindowView();
+
+ virtual BOOL MouseMove( const MouseEvent& rMEvt );
+ virtual BOOL MouseButtonDown( const MouseEvent& rMEvt );
+ virtual BOOL Tracking( const TrackingEvent& rTEvt );
+ virtual USHORT RequestHelp( const Point& rPos, Rectangle& rHelpRect );
+
+ virtual void Init( OutputDevice* pDev, long nWidth, long nHeight );
+ virtual void GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const;
+ virtual long CalcTitleWidth() const;
+ virtual void DrawWindow( USHORT nDrawFlags );
+
+ Rectangle DrawUnxTitleButton( const Rectangle& rRect, USHORT nStyle );
+};
+
+// =======================================================================
+
+ImplUnxBorderWindowView::ImplUnxBorderWindowView( ImplBorderWindow* pBorderWindow )
+{
+ maFrameData.mpBorderWindow = pBorderWindow;
+ maFrameData.mbDragFull = FALSE;
+ maFrameData.mnHitTest = 0;
+ maFrameData.mnPinState = 0;
+ maFrameData.mnCloseState = 0;
+ maFrameData.mnRollState = 0;
+ maFrameData.mnDockState = 0;
+ maFrameData.mnHideState = 0;
+ maFrameData.mnHelpState = 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImplUnxBorderWindowView::~ImplUnxBorderWindowView()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplUnxBorderWindowView::MouseMove( const MouseEvent& rMEvt )
+{
+ return ImplMouseMove( &maFrameData, rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplUnxBorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ return ImplMouseButtonDown( &maFrameData, rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplUnxBorderWindowView::Tracking( const TrackingEvent& rTEvt )
+{
+ return ImplTracking( &maFrameData, rTEvt );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplUnxBorderWindowView::RequestHelp( const Point& rPos, Rectangle& rHelpRect )
+{
+ return ImplRequestHelp( &maFrameData, rPos, rHelpRect );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplUnxBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
+{
+ ImplBorderFrameData* pData = &maFrameData;
+ ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ DecorationView aDecoView( pDev );
+ Rectangle aRect( 0, 0, 10, 10 );
+ Rectangle aCalcRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEOUT | FRAME_DRAW_NODRAW );
+
+ pData->mpOutDev = pDev;
+ pData->mnWidth = nWidth;
+ pData->mnHeight = nHeight;
+
+ pData->mnTitleType = pBorderWindow->mnTitleType;
+ pData->mbFloatWindow = pBorderWindow->mbFloatWindow;
+
+ if ( !(pBorderWindow->GetStyle() & WB_MOVEABLE) ||
+ (pData->mnTitleType == BORDERWINDOW_TITLE_NONE) )
+ pData->mnBorderSize = 0;
+ else if ( pData->mnTitleType == BORDERWINDOW_TITLE_TEAROFF )
+ pData->mnBorderSize = 0;
+ else
+ {
+ pData->mnBorderSize = rStyleSettings.GetBorderSize();
+ if ( pData->mnBorderSize < 3 )
+ pData->mnBorderSize = 3;
+ aCalcRect = aRect;
+ }
+ pData->mnLeftBorder = aCalcRect.Left();
+ pData->mnTopBorder = aCalcRect.Top();
+ pData->mnRightBorder = aRect.Right()-aCalcRect.Right();
+ pData->mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
+ pData->mnLeftBorder += pData->mnBorderSize;
+ pData->mnTopBorder += pData->mnBorderSize;
+ pData->mnRightBorder += pData->mnBorderSize;
+ pData->mnBottomBorder += pData->mnBorderSize;
+ pData->mnNoTitleTop = pData->mnTopBorder;
+
+ ImplInitTitle( &maFrameData );
+ if ( pData->mnTitleHeight )
+ {
+ pData->maTitleRect.Left() = pData->mnLeftBorder;
+ pData->maTitleRect.Right() = nWidth-pData->mnRightBorder-1;
+ pData->maTitleRect.Top() = pData->mnTopBorder;
+ pData->maTitleRect.Bottom() = pData->maTitleRect.Top() + pData->mnTitleHeight - 1;
+
+ if ( pData->mnTitleType & (BORDERWINDOW_TITLE_NORMAL | BORDERWINDOW_TITLE_SMALL) )
+ {
+ long nLeft = pData->maTitleRect.Left();
+ long nRight = pData->maTitleRect.Right();
+ long nItemTop = pData->maTitleRect.Top();
+ long nItemBottom = pData->maTitleRect.Bottom();
+
+ if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
+ {
+ pData->maCloseRect.Top() = nItemTop;
+ pData->maCloseRect.Bottom() = nItemBottom;
+ pData->maCloseRect.Left() = nLeft;
+ pData->maCloseRect.Right() = nLeft + pData->maCloseRect.GetHeight();
+ nLeft += pData->maCloseRect.GetWidth() + 2;
+ }
+
+ if ( pBorderWindow->GetStyle() & WB_PINABLE )
+ {
+ Image aImage;
+ ImplGetPinImage( 0, 0, aImage );
+ pData->maPinRect.Top() = nItemTop;
+ pData->maPinRect.Bottom() = nItemBottom;
+ pData->maPinRect.Left() = nLeft;
+ pData->maPinRect.Right() = pData->maPinRect.Left() + aImage.GetSizePixel().Width();
+ nLeft += pData->maPinRect.GetWidth();
+ }
+
+ if ( pBorderWindow->mbDockBtn )
+ {
+ pData->maDockRect.Top() = nItemTop;
+ pData->maDockRect.Bottom() = nItemBottom;
+ pData->maDockRect.Right() = nRight;
+ pData->maDockRect.Left() = pData->maDockRect.Right()-pData->maDockRect.GetHeight()+1;
+ nRight -= pData->maDockRect.GetWidth();
+ }
+
+ if ( pBorderWindow->mbHideBtn )
+ {
+ pData->maHideRect.Top() = nItemTop;
+ pData->maHideRect.Bottom() = nItemBottom;
+ pData->maHideRect.Right() = nRight;
+ pData->maHideRect.Left() = pData->maHideRect.Right()-pData->maHideRect.GetHeight()+1;
+ nRight -= pData->maHideRect.GetWidth();
+ }
+
+ if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
+ {
+ pData->maRollRect.Top() = nItemTop;
+ pData->maRollRect.Bottom() = nItemBottom;
+ pData->maRollRect.Right() = nRight;
+ pData->maRollRect.Left() = pData->maRollRect.Right()-pData->maRollRect.GetHeight()+1;
+ nRight -= pData->maRollRect.GetWidth();
+ }
+
+ if ( pBorderWindow->mbHelpBtn )
+ {
+ pData->maHelpRect.Top() = nItemTop;
+ pData->maHelpRect.Bottom() = nItemBottom;
+ pData->maHelpRect.Right() = nRight;
+ pData->maHelpRect.Left() = pData->maHelpRect.Right()-pData->maHelpRect.GetHeight()+1;
+ nRight -= pData->maHelpRect.GetWidth();
+ }
+ }
+ else
+ {
+ pData->maPinRect.SetEmpty();
+ pData->maCloseRect.SetEmpty();
+ pData->maDockRect.SetEmpty();
+ pData->maHideRect.SetEmpty();
+ pData->maRollRect.SetEmpty();
+ pData->maHelpRect.SetEmpty();
+ }
+
+ pData->mnTopBorder += pData->mnTitleHeight;
+ }
+ else
+ {
+ pData->maTitleRect.SetEmpty();
+ pData->maPinRect.SetEmpty();
+ pData->maCloseRect.SetEmpty();
+ pData->maDockRect.SetEmpty();
+ pData->maHideRect.SetEmpty();
+ pData->maRollRect.SetEmpty();
+ pData->maHelpRect.SetEmpty();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplUnxBorderWindowView::GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const
+{
+ rLeftBorder = maFrameData.mnLeftBorder;
+ rTopBorder = maFrameData.mnTopBorder;
+ rRightBorder = maFrameData.mnRightBorder;
+ rBottomBorder = maFrameData.mnBottomBorder;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplUnxBorderWindowView::CalcTitleWidth() const
+{
+ return ImplCalcTitleWidth( &maFrameData );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplUnxBorderWindowView::DrawWindow( USHORT nDrawFlags )
+{
+ ImplBorderFrameData* pData = &maFrameData;
+ OutputDevice* pDev = pData->mpOutDev;
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+ Point aTmpPoint;
+ Rectangle aInRect( aTmpPoint, Size( pData->mnWidth, pData->mnHeight ) );
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ DecorationView aDecoView( pDev );
+ USHORT nStyle;
+ BOOL bActive = pBorderWindow->IsDisplayActive();
+
+ // Color-Management for 3D-like Border
+ Color aLineColor;
+ Color aFillColor;
+ Color aLightColor;
+ Color aDarkColor;
+ Color aTextColor;
+ if ( bActive )
+ {
+ aLineColor = rStyleSettings.GetActiveBorderColor();
+ aFillColor = rStyleSettings.GetActiveColor();
+ aTextColor = rStyleSettings.GetActiveTextColor();
+ }
+ else
+ {
+ aLineColor = rStyleSettings.GetDeactiveBorderColor();
+ aFillColor = rStyleSettings.GetDeactiveColor();
+ aTextColor = rStyleSettings.GetDeactiveTextColor();
+ }
+ aLightColor = aLineColor;
+ aDarkColor = aLineColor;
+ aLightColor.IncreaseLuminance( 64 );
+ aDarkColor.DecreaseLuminance( 64 );
+
+ // Draw Frame
+ long nBorderSize = pData->mnBorderSize;
+ if ( !nBorderSize )
+ {
+ if ( nDrawFlags & BORDERWINDOW_DRAW_FRAME )
+ nStyle = 0;
+ else
+ nStyle = FRAME_DRAW_NODRAW;
+ aInRect = aDecoView.DrawFrame( aInRect, FRAME_DRAW_DOUBLEOUT | nStyle );
+ }
+ else
+ {
+ // Draw Border
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_BORDER) && nBorderSize )
+ {
+ // Geometry Presettings
+ long nOffset = 0;
+ long nEffBorderSize;
+ long nLeft = aInRect.Left();
+ long nRight = aInRect.Right();
+ long nTop = aInRect.Top();
+ long nBottom = aInRect.Bottom();
+
+ nEffBorderSize = nBorderSize > 2 ? nBorderSize - 2 : 1;
+
+ // outer border
+ pDev->SetLineColor( aLightColor );
+ pDev->DrawLine( Point( nLeft, nTop ), Point( nLeft, nBottom ) );
+ pDev->DrawLine( Point( nLeft, nTop ), Point( nRight, nTop ) );
+
+ pDev->SetLineColor( aDarkColor );
+ nTop++; nLeft++;
+ pDev->DrawLine( Point( nRight, nTop ), Point( nRight, nBottom ) );
+ pDev->DrawLine( Point( nLeft, nBottom ), Point( nRight, nBottom ) );
+
+ // middle border
+ pDev->SetLineColor();
+ pDev->SetFillColor( aLineColor );
+ nRight--; nBottom--;
+ pDev->DrawRect( Rectangle( Point( nLeft, nTop ),
+ Size( nRight - nLeft, nEffBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( nLeft, nTop ),
+ Size( nEffBorderSize, nBottom - nTop ) ) );
+ nRight -= nEffBorderSize;
+ nBottom -= nEffBorderSize;
+ pDev->DrawRect( Rectangle( Point( nRight + 1, nTop ),
+ Size( nEffBorderSize, nBottom - nTop + 1) ) );
+ pDev->DrawRect( Rectangle( Point( nLeft, nBottom + 1),
+ Size( nRight - nLeft + 1, nEffBorderSize ) ) );
+
+ // inner Border
+ pDev->SetLineColor( aDarkColor );
+ nTop += nEffBorderSize; nLeft += nEffBorderSize;
+ pDev->DrawLine( Point( nLeft, nTop ), Point( nLeft, nBottom ) );
+ pDev->DrawLine( Point( nLeft, nTop ), Point( nRight, nTop ) );
+
+ pDev->SetLineColor( aLightColor );
+ nTop++; nLeft++;
+ pDev->DrawLine( Point( nRight, nTop ), Point( nRight, nBottom ) );
+ pDev->DrawLine( Point( nLeft, nBottom ), Point( nRight, nBottom ) );
+
+ // edge intersections
+ if ( pBorderWindow->GetStyle() & WB_SIZEABLE )
+ {
+ nLeft = aInRect.Left();
+ nRight = aInRect.Right();
+ nTop = aInRect.Top();
+ nBottom = aInRect.Bottom();
+
+ if ( !pData->maTitleRect.IsEmpty() )
+ nOffset = pData->maTitleRect.GetHeight() + nEffBorderSize + 2;
+
+ pDev->SetLineColor( aDarkColor );
+ pDev->DrawLine( Point( nLeft + 1, nTop + nOffset ),
+ Point( nLeft + nEffBorderSize, nTop + nOffset ));
+ pDev->DrawLine( Point( nLeft + nOffset, nTop + 1 ),
+ Point( nLeft + nOffset, nTop + nEffBorderSize));
+ pDev->DrawLine( Point( nRight - 1, nTop + nOffset ),
+ Point( nRight - nEffBorderSize,nTop + nOffset ));
+ pDev->DrawLine( Point( nRight - nOffset, nTop + 1 ),
+ Point( nRight - nOffset, nTop + nEffBorderSize));
+
+ pDev->DrawLine( Point( nLeft + 1, nBottom - nOffset ),
+ Point( nLeft + nEffBorderSize, nBottom - nOffset ));
+ pDev->DrawLine( Point( nLeft + nOffset, nBottom - 1 ),
+ Point( nLeft + nOffset, nBottom - nEffBorderSize));
+ pDev->DrawLine( Point( nRight - 1, nBottom - nOffset ),
+ Point( nRight - nEffBorderSize,nBottom - nOffset ));
+ pDev->DrawLine( Point( nRight - nOffset, nBottom - 1 ),
+ Point( nRight - nOffset, nBottom - nEffBorderSize));
+ pDev->SetLineColor( aLightColor );
+ nEffBorderSize = nBorderSize > 1 ? nBorderSize - 1 : 1;
+ nOffset += 1;
+
+ pDev->DrawLine( Point( nLeft, nTop + nOffset ),
+ Point( nLeft + nEffBorderSize, nTop + nOffset ));
+ pDev->DrawLine( Point( nLeft + nOffset, nTop ),
+ Point( nLeft + nOffset, nTop + nEffBorderSize));
+ pDev->DrawLine( Point( nRight, nTop + nOffset ),
+ Point( nRight - nEffBorderSize,nTop + nOffset ));
+ pDev->DrawLine( Point( nLeft + nOffset, nBottom ),
+ Point( nLeft + nOffset, nBottom - nEffBorderSize));
+ nOffset -= 2;
+ pDev->DrawLine( Point( nRight - nOffset, nTop ),
+ Point( nRight - nOffset, nTop + nEffBorderSize));
+ pDev->DrawLine( Point( nLeft, nBottom - nOffset ),
+ Point( nLeft + nEffBorderSize, nBottom - nOffset ));
+ pDev->DrawLine( Point( nRight, nBottom - nOffset ),
+ Point( nRight - nEffBorderSize,nBottom - nOffset ));
+ pDev->DrawLine( Point( nRight - nOffset, nBottom ),
+ Point( nRight - nOffset, nBottom - nEffBorderSize));
+ }
+
+ // Reset Linecolor
+ pDev->SetLineColor();
+ }
+ }
+
+ // Draw Title
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_TITLE) && !pData->maTitleRect.IsEmpty() )
+ {
+ // Title Rect
+ aInRect = pData->maTitleRect;
+
+ pDev->SetFillColor( aFillColor );
+ pDev->SetTextColor( aTextColor );
+ pDev->DrawRect( aInRect );
+
+ // Title Rect Decoration
+ pDev->SetLineColor( aDarkColor );
+ pDev->DrawLine( Point( aInRect.Left(), aInRect.Bottom() ),
+ Point( aInRect.Right(), aInRect.Bottom() ) );
+ pDev->DrawLine( Point( aInRect.Right(), aInRect.Top() ),
+ Point( aInRect.Right(), aInRect.Bottom() ) );
+ pDev->SetLineColor( aLightColor );
+ pDev->DrawLine( Point( aInRect.Left(), aInRect.Top() ),
+ Point( aInRect.Right(), aInRect.Top() ) );
+ pDev->DrawLine( Point( aInRect.Left(), aInRect.Top() ),
+ Point( aInRect.Left(), aInRect.Bottom() ) );
+
+ long nLeft;
+ if ( !pData->maCloseRect.IsEmpty() )
+ nLeft = pData->maCloseRect.Right()+1;
+ else
+ nLeft = aInRect.Left()+1;
+
+ // Title Text
+ if ( pData->mnTitleType != BORDERWINDOW_TITLE_TEAROFF )
+ {
+ if ( !pData->maPinRect.IsEmpty() )
+ aInRect.Left() = pData->maPinRect.Right()+1;
+ else if ( !pData->maCloseRect.IsEmpty() )
+ aInRect.Left() = pData->maCloseRect.Right()+1;
+
+ if ( !pData->maHelpRect.IsEmpty() )
+ aInRect.Right() = pData->maHelpRect.Left()-1;
+ else if ( !pData->maRollRect.IsEmpty() )
+ aInRect.Right() = pData->maRollRect.Left()-1;
+ else if ( !pData->maHideRect.IsEmpty() )
+ aInRect.Right() = pData->maHideRect.Left()-1;
+ else if ( !pData->maDockRect.IsEmpty() )
+ aInRect.Right() = pData->maDockRect.Left()-1;
+
+ pDev->DrawText( aInRect, pBorderWindow->GetText(),
+ TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER |
+ TEXT_DRAW_ENDELLIPSIS | TEXT_DRAW_CLIP );
+ }
+
+ // more Title Rect Decoration
+ pDev->SetLineColor( aLightColor );
+ pDev->DrawLine( Point( nLeft, aInRect.Bottom() ),
+ Point( nLeft, aInRect.Top() ));
+ pDev->SetLineColor( aDarkColor );
+ pDev->DrawLine( Point( aInRect.Right(), aInRect.Top() ),
+ Point( aInRect.Right(), aInRect.Bottom() ) );
+ }
+
+ // Draw the buttons
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_CLOSE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maCloseRect.IsEmpty() )
+ {
+ Rectangle aInCloseRect = DrawUnxTitleButton( pData->maCloseRect,
+ pData->mnCloseState );
+ aDecoView.DrawSymbol( aInCloseRect, SYMBOL_CLOSE, aTextColor, 0 );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_DOCK) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maDockRect.IsEmpty() )
+ {
+ Rectangle aInDockRect = DrawUnxTitleButton( pData->maDockRect,
+ pData->mnDockState );
+ aDecoView.DrawSymbol( aInDockRect, SYMBOL_DOCK, aTextColor, 0 );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_HIDE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maHideRect.IsEmpty() )
+ {
+ Rectangle aInHideRect = DrawUnxTitleButton( pData->maHideRect,
+ pData->mnHideState );
+ aDecoView.DrawSymbol( aInHideRect, SYMBOL_HIDE, aTextColor, 0 );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_ROLL) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maRollRect.IsEmpty() )
+ {
+ Rectangle aInRollRect = DrawUnxTitleButton( pData->maRollRect,
+ pData->mnRollState );
+ SymbolType eType;
+ if ( pBorderWindow->mbRollUp )
+ eType = SYMBOL_ROLLDOWN;
+ else
+ eType = SYMBOL_ROLLUP;
+ aDecoView.DrawSymbol( aInRollRect, eType, aTextColor, 0 );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_HELP) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maHelpRect.IsEmpty() )
+ {
+ Rectangle aInHelpRect = DrawUnxTitleButton( pData->maHelpRect,
+ pData->mnHelpState );
+ aDecoView.DrawSymbol( aInHelpRect, SYMBOL_HELP, aTextColor, 0 );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_PIN) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maPinRect.IsEmpty() )
+ {
+ Image aImage;
+ ImplGetPinImage( pData->mnPinState, pBorderWindow->mbPined, aImage );
+ Size aImageSize = aImage.GetSizePixel();
+ long nRectHeight = pData->maPinRect.GetHeight();
+ if ( nRectHeight < aImageSize.Height() )
+ {
+ pDev->DrawImage( Point( pData->maPinRect.Left(),
+ pData->maPinRect.Top() ),
+ Size( aImageSize.Width(), nRectHeight ),
+ aImage );
+ }
+ else
+ {
+ pDev->DrawImage( Point( pData->maPinRect.Left(),
+ pData->maPinRect.Top()+(nRectHeight-aImageSize.Height())/2 ),
+ aImage );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle ImplUnxBorderWindowView::DrawUnxTitleButton( const Rectangle& rRect, USHORT nStyle )
+{
+ Rectangle aFillRect = rRect;
+ OutputDevice* pDev = maFrameData.mpOutDev;
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ ImplBorderFrameData* pData = &maFrameData;
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+ BOOL bActive = pBorderWindow->IsDisplayActive();
+
+ // Color-Management for 3D-like Border
+ Color aLineColor;
+ Color aLightColor;
+ Color aDarkColor;
+ if ( bActive )
+ aLineColor = rStyleSettings.GetActiveBorderColor();
+ else
+ aLineColor = rStyleSettings.GetDeactiveBorderColor();
+ aLightColor = aLineColor;
+ aDarkColor = aLineColor;
+ aLightColor.IncreaseLuminance( 64 );
+ aDarkColor.DecreaseLuminance( 64 );
+
+ // Draw Button
+ if ( !(nStyle & BUTTON_DRAW_NODRAW) )
+ {
+ // left and upper button-border
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ pDev->SetLineColor( aDarkColor );
+ else
+ pDev->SetLineColor( aLightColor );
+ pDev->DrawLine( Point( aFillRect.Left(), aFillRect.Top() ),
+ Point( aFillRect.Right(), aFillRect.Top() ) );
+ pDev->DrawLine( Point( aFillRect.Left(), aFillRect.Top() ),
+ Point( aFillRect.Left(), aFillRect.Bottom() ) );
+
+ aFillRect.Left()++;
+ aFillRect.Top()++;
+
+ // right and bottom button-border
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ pDev->SetLineColor( aLightColor );
+ else
+ pDev->SetLineColor( aDarkColor );
+ pDev->DrawLine( Point( aFillRect.Right(), aFillRect.Top() ),
+ Point( aFillRect.Right(), aFillRect.Bottom() ) );
+ pDev->DrawLine( Point( aFillRect.Left(), aFillRect.Bottom() ),
+ Point( aFillRect.Right(), aFillRect.Bottom() ) );
+
+ aFillRect.Right()--;
+ aFillRect.Bottom()--;
+
+ // button area
+ pDev->SetFillColor( aLineColor );
+ pDev->SetLineColor();
+
+ pDev->DrawRect( Rectangle( aFillRect.Left(), aFillRect.Top(),
+ aFillRect.Right(), aFillRect.Bottom() ) );
+ }
+
+ aFillRect.Left() += 3;
+ aFillRect.Top() += 3;
+ aFillRect.Right() -= 2;
+ aFillRect.Bottom() -= 2;
+ return aFillRect;
+}
+
+// =======================================================================
+
+// ---------------------------
+// - ImplMacBorderWindowView -
+// ---------------------------
+
+class ImplMacBorderWindowView : public ImplBorderWindowView
+{
+ ImplBorderFrameData maFrameData;
+ VirtualDevice maVirDev;
+ BOOL mbPressed;
+
+public:
+ ImplMacBorderWindowView( ImplBorderWindow* pBorderWindow );
+ ~ImplMacBorderWindowView();
+
+ virtual BOOL MouseMove( const MouseEvent& rMEvt );
+ virtual BOOL MouseButtonDown( const MouseEvent& rMEvt );
+ virtual BOOL Tracking( const TrackingEvent& rTEvt );
+ virtual USHORT RequestHelp( const Point& rPos, Rectangle& rHelpRect );
+
+ virtual void Init( OutputDevice* pDev, long nWidth, long nHeight );
+ virtual void GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const;
+ virtual long CalcTitleWidth() const;
+ virtual void DrawWindow( USHORT nDrawFlags );
+
+ Rectangle DrawMacTitleButton( const Rectangle& rRect, USHORT nStyle );
+};
+
+// =======================================================================
+
+ImplMacBorderWindowView::ImplMacBorderWindowView( ImplBorderWindow* pBorderWindow )
+{
+ maFrameData.mpBorderWindow = pBorderWindow;
+ maFrameData.mbDragFull = FALSE;
+ maFrameData.mnHitTest = 0;
+ maFrameData.mnPinState = 0;
+ maFrameData.mnCloseState = 0;
+ maFrameData.mnRollState = 0;
+ maFrameData.mnDockState = 0;
+ maFrameData.mnHideState = 0;
+ maFrameData.mnHelpState = 0;
+
+ mbPressed = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplMacBorderWindowView::~ImplMacBorderWindowView()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplMacBorderWindowView::MouseMove( const MouseEvent& rMEvt )
+{
+ return ImplMouseMove( &maFrameData, rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplMacBorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ return ImplMouseButtonDown( &maFrameData, rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplMacBorderWindowView::Tracking( const TrackingEvent& rTEvt )
+{
+ return ImplTracking( &maFrameData, rTEvt );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplMacBorderWindowView::RequestHelp( const Point& rPos, Rectangle& rHelpRect )
+{
+ return ImplRequestHelp( &maFrameData, rPos, rHelpRect );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplMacBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
+{
+ ImplBorderFrameData* pData = &maFrameData;
+ ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+
+ pData->mpOutDev = pDev;
+ pData->mnWidth = nWidth;
+ pData->mnHeight = nHeight;
+
+ pData->mnTitleType = pBorderWindow->mnTitleType;
+ pData->mbFloatWindow = pBorderWindow->mbFloatWindow;
+
+ if ( !(pBorderWindow->GetStyle() & WB_MOVEABLE) || (pData->mnTitleType == BORDERWINDOW_TITLE_NONE) )
+ pData->mnBorderSize = 0;
+ else if ( pData->mnTitleType == BORDERWINDOW_TITLE_TEAROFF )
+ pData->mnBorderSize = 1;
+ else
+ pData->mnBorderSize = rStyleSettings.GetBorderSize();
+ pData->mnLeftBorder = 2;
+ pData->mnTopBorder = 2;
+ pData->mnRightBorder = 2;
+ pData->mnBottomBorder = 2;
+ pData->mnLeftBorder += pData->mnBorderSize;
+ pData->mnTopBorder += pData->mnBorderSize;
+ pData->mnRightBorder += pData->mnBorderSize;
+ pData->mnBottomBorder += pData->mnBorderSize;
+ pData->mnNoTitleTop = pData->mnTopBorder;
+ pData->mnTitleOff = 0;
+
+ ImplInitTitle( &maFrameData );
+ if ( pData->mnTitleHeight )
+ {
+ if ( (pData->mnTitleType & (BORDERWINDOW_TITLE_NORMAL | BORDERWINDOW_TITLE_SMALL)) &&
+ pData->mnBorderSize )
+ pData->mnTitleOff = 3; // 3 damit Hoehe auf dem MAC stimmt, ansonsten waere 2 richtig
+ pData->mnTitleHeight -= pData->mnTitleOff;
+ pData->maTitleRect.Left() = pData->mnLeftBorder;
+ pData->maTitleRect.Right() = nWidth-pData->mnRightBorder-1;
+ pData->maTitleRect.Top() = pData->mnTopBorder;
+ pData->maTitleRect.Bottom() = pData->maTitleRect.Top()+pData->mnTitleHeight-1;
+
+ if ( pData->mnTitleType & (BORDERWINDOW_TITLE_NORMAL | BORDERWINDOW_TITLE_SMALL) )
+ {
+ long nLeft = pData->maTitleRect.Left();
+ long nRight = pData->maTitleRect.Right();
+ long nItemTop = pData->maTitleRect.Top();
+ long nItemBottom = pData->maTitleRect.Bottom();
+
+ if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
+ {
+ pData->maCloseRect.Top() = nItemTop;
+ pData->maCloseRect.Bottom() = nItemBottom;
+ pData->maCloseRect.Left() = nLeft;
+ pData->maCloseRect.Right() = pData->maCloseRect.Left()+pData->maCloseRect.GetHeight()-1;
+ nLeft += pData->maCloseRect.GetWidth()+3;
+ }
+
+ if ( pBorderWindow->GetStyle() & WB_PINABLE )
+ {
+ Image aImage;
+ ImplGetPinImage( 0, 0, aImage );
+ pData->maPinRect.Top() = nItemTop;
+ pData->maPinRect.Bottom() = nItemBottom;
+ pData->maPinRect.Left() = nLeft;
+ pData->maPinRect.Right() = pData->maPinRect.Left()+aImage.GetSizePixel().Width();
+ nLeft += pData->maPinRect.GetWidth()+3;
+ }
+
+ if ( pBorderWindow->mbDockBtn )
+ {
+ pData->maDockRect.Top() = nItemTop;
+ pData->maDockRect.Bottom() = nItemBottom;
+ pData->maDockRect.Right() = nRight;
+ pData->maDockRect.Left() = pData->maDockRect.Right()-pData->maDockRect.GetHeight()+1;
+ nRight -= pData->maDockRect.GetWidth()+3;
+ }
+
+ if ( pBorderWindow->mbHideBtn )
+ {
+ pData->maHideRect.Top() = nItemTop;
+ pData->maHideRect.Bottom() = nItemBottom;
+ pData->maHideRect.Right() = nRight;
+ pData->maHideRect.Left() = pData->maHideRect.Right()-pData->maHideRect.GetHeight()+1;
+ nRight -= pData->maHideRect.GetWidth()+3;
+ }
+
+ if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
+ {
+ pData->maRollRect.Top() = nItemTop;
+ pData->maRollRect.Bottom() = nItemBottom;
+ pData->maRollRect.Right() = nRight;
+ pData->maRollRect.Left() = pData->maRollRect.Right()-pData->maRollRect.GetHeight()+1;
+ nRight -= pData->maRollRect.GetWidth()+3;
+ }
+
+ if ( pBorderWindow->mbHelpBtn )
+ {
+ pData->maHelpRect.Top() = nItemTop;
+ pData->maHelpRect.Bottom() = nItemBottom;
+ pData->maHelpRect.Right() = nRight;
+ pData->maHelpRect.Left() = pData->maHelpRect.Right()-pData->maHelpRect.GetHeight()+1;
+ nRight -= pData->maHelpRect.GetWidth()+3;
+ }
+ }
+ else
+ {
+ pData->maCloseRect.SetEmpty();
+ pData->maDockRect.SetEmpty();
+ pData->maHideRect.SetEmpty();
+ pData->maRollRect.SetEmpty();
+ pData->maHelpRect.SetEmpty();
+ }
+
+ pData->mnTopBorder += pData->mnTitleHeight;
+
+ // Innerer Border nur, wenn wir auch eine TitleBar haben
+ if ( !pBorderWindow->mbRollUp || pBorderWindow->mnRollHeight )
+ {
+ pData->mnTopBorder += 3+pData->mnBorderSize;
+ pData->mnBottomBorder += 3;
+ }
+ pData->mnLeftBorder += 3;
+ pData->mnRightBorder += 3;
+ }
+ else
+ {
+ pData->maTitleRect.SetEmpty();
+ pData->maPinRect.SetEmpty();
+ pData->maCloseRect.SetEmpty();
+ pData->maDockRect.SetEmpty();
+ pData->maHideRect.SetEmpty();
+ pData->maRollRect.SetEmpty();
+ pData->maHelpRect.SetEmpty();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplMacBorderWindowView::GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const
+{
+ rLeftBorder = maFrameData.mnLeftBorder;
+ rTopBorder = maFrameData.mnTopBorder;
+ rRightBorder = maFrameData.mnRightBorder;
+ rBottomBorder = maFrameData.mnBottomBorder;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplMacBorderWindowView::CalcTitleWidth() const
+{
+ return ImplCalcTitleWidth( &maFrameData );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplMacBorderWindowView::DrawWindow( USHORT nDrawFlags )
+{
+ ImplBorderFrameData* pData = &maFrameData;
+ OutputDevice* pDev = pData->mpOutDev;
+ ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
+ Point aTmpPoint;
+ Rectangle aInRect( aTmpPoint, Size( pData->mnWidth, pData->mnHeight ) );
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ BOOL bActive = pBorderWindow->IsDisplayActive();
+
+ // DrawFrame
+ pBorderWindow->SetFillColor();
+ if ( nDrawFlags & BORDERWINDOW_DRAW_FRAME )
+ {
+ if ( bActive )
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ else
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawRect( aInRect );
+ aInRect.Left()++;
+ aInRect.Top()++;
+ aInRect.Right()--;
+ aInRect.Bottom()--;
+ if ( bActive )
+ {
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( aInRect.TopLeft(), Point( aInRect.Left(), aInRect.Bottom() ) );
+ pDev->DrawLine( aInRect.TopLeft(), Point( aInRect.Right(), aInRect.Top() ) );
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( aInRect.Left()+1, aInRect.Bottom() ), aInRect.BottomRight() );
+ pDev->DrawLine( Point( aInRect.Right(), aInRect.Top()+1 ), aInRect.BottomRight() );
+ }
+ else
+ {
+ pDev->SetLineColor( rStyleSettings.GetDeactiveBorderColor() );
+ pDev->DrawRect( aInRect );
+ }
+ aInRect.Left()++;
+ aInRect.Top()++;
+ aInRect.Right()--;
+ aInRect.Bottom()--;
+ }
+ else
+ {
+ aInRect.Left() += 2;
+ aInRect.Top() += 2;
+ aInRect.Right() -= 2;
+ aInRect.Bottom() -= 2;
+ }
+
+ pBorderWindow->SetLineColor();
+ long nBorderSize = pData->mnBorderSize;
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_BORDER) && nBorderSize )
+ {
+ if ( bActive )
+ pDev->SetFillColor( rStyleSettings.GetActiveBorderColor() );
+ else
+ pDev->SetFillColor( rStyleSettings.GetDeactiveBorderColor() );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Top() ),
+ Size( aInRect.GetWidth(), nBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Top()+nBorderSize ),
+ Size( nBorderSize, aInRect.GetHeight()-nBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Bottom()-nBorderSize+1 ),
+ Size( aInRect.GetWidth(), nBorderSize ) ) );
+ pDev->DrawRect( Rectangle( Point( aInRect.Right()-nBorderSize+1, aInRect.Top()+nBorderSize ),
+ Size( nBorderSize, aInRect.GetHeight()-nBorderSize ) ) );
+ }
+ aInRect.Left() += nBorderSize;
+ aInRect.Top() += nBorderSize;
+ aInRect.Right() -= nBorderSize;
+ aInRect.Bottom() -= nBorderSize;
+
+ Rectangle aTitleRect = pData->maTitleRect;
+ XubString aText = pBorderWindow->GetText();
+ BOOL bDrawText = FALSE;
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_TITLE) && !pData->maTitleRect.IsEmpty() )
+ {
+ Rectangle aTextRect;
+ if ( bActive )
+ {
+ pDev->SetFillColor( rStyleSettings.GetActiveColor() );
+ pDev->SetTextColor( rStyleSettings.GetActiveTextColor() );
+ }
+ else
+ {
+ pDev->SetFillColor( rStyleSettings.GetDeactiveColor() );
+ pDev->SetTextColor( rStyleSettings.GetDeactiveTextColor() );
+ }
+ pDev->DrawRect( aTitleRect );
+
+ if ( pData->mnTitleType != BORDERWINDOW_TITLE_TEAROFF )
+ {
+ if ( !pData->maPinRect.IsEmpty() )
+ aTitleRect.Left() = pData->maPinRect.Right()+3;
+ else if ( !pData->maCloseRect.IsEmpty() )
+ aTitleRect.Left() = pData->maCloseRect.Right()+3;
+
+ if ( !pData->maHelpRect.IsEmpty() )
+ aTitleRect.Right() = pData->maHelpRect.Left()-3;
+ else if ( !pData->maHideRect.IsEmpty() )
+ aTitleRect.Right() = pData->maHideRect.Left()-3;
+ else if ( !pData->maDockRect.IsEmpty() )
+ aTitleRect.Right() = pData->maDockRect.Left()-3;
+ else if ( !pData->maRollRect.IsEmpty() )
+ aTitleRect.Right() = pData->maRollRect.Left()-3;
+
+ if ( aText.Len() )
+ {
+ aTextRect = pDev->GetTextRect( aTitleRect, aText,
+ TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER |
+ TEXT_DRAW_ENDELLIPSIS );
+ bDrawText = TRUE;
+ }
+ }
+
+ if ( bActive )
+ {
+ long nY = aTitleRect.Top();
+ long nYMax = nY+pData->mnTitleHeight-2+(pData->mnTitleHeight%2);
+ long nX1 = aTitleRect.Left();
+ long nX2;
+ long nX3;
+ long nX4;
+ BOOL bLines;
+ BOOL b2Lines;
+ if ( aTextRect.IsEmpty() )
+ {
+ nX2 = aTitleRect.Right();
+ bLines = nX2-2 > nX1;
+ b2Lines = FALSE;
+ }
+ else
+ {
+ aTextRect.Left() -= 4;
+ aTextRect.Right() += 4;
+ if ( (aTextRect.Left() > aTitleRect.Left()) &&
+ (aTextRect.Right() < aTitleRect.Right()) )
+ {
+ nX2 = aTextRect.Left();
+ nX3 = aTextRect.Right();
+ nX4 = aTitleRect.Right();
+ bLines = TRUE;
+ b2Lines = TRUE;
+ }
+ else
+ bLines = FALSE;
+ }
+
+ if ( bLines )
+ {
+ for ( ; nY < nYMax; nY += 2 )
+ {
+ if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
+ pDev->SetLineColor( Color( COL_BLACK ) );
+ else
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( Point( nX1, nY ), Point( nX2-1, nY ) );
+ if ( b2Lines )
+ pDev->DrawLine( Point( nX3, nY ), Point( nX4-1, nY ) );
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( nX1+1, nY+1 ), Point( nX2, nY+1 ) );
+ if ( b2Lines )
+ pDev->DrawLine( Point( nX3+1, nY+1 ), Point( nX4, nY+1 ) );
+ }
+ }
+ }
+ }
+ }
+ aInRect.Top() += pData->mnTitleHeight;
+
+ if ( bActive )
+ {
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_CLOSE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maCloseRect.IsEmpty() )
+ DrawMacTitleButton( pData->maCloseRect, pData->mnCloseState );
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_PIN) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maPinRect.IsEmpty() )
+ {
+ Image aImage;
+ ImplGetPinImage( pData->mnPinState, pBorderWindow->mbPined, aImage );
+ Size aImageSize = aImage.GetSizePixel();
+ long nRectHeight = pData->maPinRect.GetHeight();
+ if ( nRectHeight < aImageSize.Height() )
+ {
+ pDev->DrawImage( Point( pData->maPinRect.Left(), pData->maPinRect.Top() ),
+ Size( aImageSize.Width(), nRectHeight ),
+ aImage );
+ }
+ else
+ {
+ pDev->DrawImage( Point( pData->maPinRect.Left(),
+ pData->maPinRect.Top()+(nRectHeight-aImageSize.Height())/2 ),
+ aImage );
+ }
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_DOCK) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maDockRect.IsEmpty() )
+ {
+ Rectangle aInDockRect = DrawMacTitleButton( pData->maDockRect, pData->mnDockState );
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ pDev->SetFillColor();
+ aInDockRect.Left()++;
+ aInDockRect.Top()++;
+ aInDockRect.Right()--;
+ aInDockRect.Bottom()--;
+ pDev->DrawRect( aInDockRect );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_HIDE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maHideRect.IsEmpty() )
+ {
+ Rectangle aInHideRect = DrawMacTitleButton( pData->maHideRect, pData->mnHideState );
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ pDev->DrawLine( Point( aInHideRect.Left(), aInHideRect.Bottom()-1 ), Point( aInHideRect.Right(), aInHideRect.Bottom()-1 ) );
+ pDev->DrawLine( Point( aInHideRect.Left(), aInHideRect.Bottom() ), Point( aInHideRect.Right(), aInHideRect.Bottom() ) );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_ROLL) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maRollRect.IsEmpty() )
+ {
+ Rectangle aInRollRect = DrawMacTitleButton( pData->maRollRect, pData->mnRollState );
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ long nY = aInRollRect.Center().Y();
+ pDev->DrawLine( Point( aInRollRect.Left(), nY-1 ), Point( aInRollRect.Right(), nY-1 ) );
+ pDev->DrawLine( Point( aInRollRect.Left(), nY+1 ), Point( aInRollRect.Right(), nY+1 ) );
+ }
+
+ if ( ((nDrawFlags & BORDERWINDOW_DRAW_HELP) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
+ !pData->maHelpRect.IsEmpty() )
+ {
+ Rectangle aInHelpRect = DrawMacTitleButton( pData->maHelpRect, pData->mnHelpState );
+ // ...
+ }
+ }
+
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_BORDER) && nBorderSize && !pData->maTitleRect.IsEmpty() )
+ {
+ pBorderWindow->SetLineColor();
+ if ( bActive )
+ pDev->SetFillColor( rStyleSettings.GetActiveColor() );
+ else
+ pDev->SetFillColor( rStyleSettings.GetDeactiveColor() );
+ pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Top() ),
+ Size( aInRect.GetWidth(), nBorderSize ) ) );
+ }
+ aInRect.Top() += nBorderSize;
+
+ if ( (nDrawFlags & BORDERWINDOW_DRAW_FRAME) && !pData->maTitleRect.IsEmpty() &&
+ (!pBorderWindow->mbRollUp || pBorderWindow->mnRollHeight) )
+ {
+ pBorderWindow->SetFillColor();
+ if ( bActive )
+ {
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( aInRect.TopLeft(), Point( aInRect.Left(), aInRect.Bottom() ) );
+ pDev->DrawLine( aInRect.TopLeft(), Point( aInRect.Right(), aInRect.Top() ) );
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( Point( aInRect.Left()+1, aInRect.Bottom() ), aInRect.BottomRight() );
+ pDev->DrawLine( Point( aInRect.Right(), aInRect.Top()+1 ), aInRect.BottomRight() );
+ }
+ else
+ {
+ pDev->SetLineColor( rStyleSettings.GetDeactiveBorderColor() );
+ pDev->DrawRect( aInRect );
+ }
+ aInRect.Left()++;
+ aInRect.Top()++;
+ aInRect.Right()--;
+ aInRect.Bottom()--;
+ if ( bActive )
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ else
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawRect( aInRect );
+ aInRect.Left()++;
+ aInRect.Top()++;
+ aInRect.Right()--;
+ aInRect.Bottom()--;
+ if ( bActive )
+ {
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( aInRect.TopLeft(), Point( aInRect.Left(), aInRect.Bottom() ) );
+ pDev->DrawLine( aInRect.TopLeft(), Point( aInRect.Right(), aInRect.Top() ) );
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( aInRect.Left()+1, aInRect.Bottom() ), aInRect.BottomRight() );
+ pDev->DrawLine( Point( aInRect.Right(), aInRect.Top()+1 ), aInRect.BottomRight() );
+ }
+ else
+ {
+ pDev->SetLineColor( rStyleSettings.GetDeactiveBorderColor() );
+ pDev->DrawRect( aInRect );
+ }
+ }
+
+ // Text als letztes zeichen, da auf dem MAC unter/ober-Laengen in
+ // den Border gezeichnet werden
+ if ( bDrawText )
+ {
+ pDev->DrawText( aTitleRect, aText,
+ TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER |
+ TEXT_DRAW_ENDELLIPSIS );
+ }
+}
+
+//fuer WIN16 Borland
+#ifdef WIN
+#pragma codeseg BRWDIN_SEG1
+#endif
+
+// -----------------------------------------------------------------------
+
+Rectangle ImplMacBorderWindowView::DrawMacTitleButton( const Rectangle& rRect, USHORT nStyle )
+{
+ OutputDevice* pDev = maFrameData.mpOutDev;
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ Rectangle aRect = rRect;
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) );
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( Point( aRect.Left()+1, aRect.Bottom() ), aRect.BottomRight() );
+ pDev->DrawLine( Point( aRect.Right(), aRect.Top()+1 ), aRect.BottomRight() );
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ BOOL bDrawRect;
+ if ( pDev->GetColorCount() >= 256 )
+ {
+ Point aTempPoint;
+ Size aRectSize = aRect.GetSize();
+ BOOL bNewPressed = (nStyle & BUTTON_DRAW_PRESSED) != 0;
+ bDrawRect = FALSE;
+ if ( (aRectSize != maVirDev.GetOutputSizePixel()) ||
+ (bNewPressed != mbPressed) )
+ {
+ Gradient aGradient( GRADIENT_LINEAR,
+ rStyleSettings.GetShadowColor(),
+ rStyleSettings.GetLightColor() );
+ if ( bNewPressed )
+ {
+ aGradient.SetStartColor( rStyleSettings.GetDarkShadowColor() );
+ aGradient.SetEndColor( rStyleSettings.GetFaceColor() );
+ }
+ aGradient.SetAngle( 450 );
+ if ( maVirDev.SetOutputSizePixel( aRectSize ) )
+ maVirDev.DrawGradient( Rectangle( aTempPoint, aRectSize ), aGradient );
+ else
+ bDrawRect = TRUE;
+ mbPressed = bNewPressed;
+ }
+ if ( !bDrawRect )
+ {
+ pDev->DrawOutDev( aRect.TopLeft(), aRectSize,
+ aTempPoint, aRectSize, maVirDev );
+ pDev->SetFillColor();
+ }
+ }
+ else
+ bDrawRect = TRUE;
+ if ( bDrawRect )
+ {
+ if ( nStyle & BUTTON_DRAW_PRESSED )
+ pDev->SetFillColor( rStyleSettings.GetShadowColor() );
+ else
+ pDev->SetFillColor( rStyleSettings.GetActiveColor() );
+ }
+ pDev->DrawRect( aRect );
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( nStyle & BUTTON_DRAW_PRESSED )
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ else
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) );
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( aRect.Left()+1, aRect.Bottom() ), aRect.BottomRight() );
+ pDev->DrawLine( Point( aRect.Right(), aRect.Top()+1 ), aRect.BottomRight() );
+ }
+ else
+ {
+ pDev->SetLineColor( Color( COL_BLACK ) );
+ if ( nStyle & BUTTON_DRAW_PRESSED )
+ pDev->SetFillColor( Color( COL_BLACK ) );
+ else
+ pDev->SetFillColor( rStyleSettings.GetActiveColor() );
+ pDev->DrawRect( aRect );
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ }
+
+ return aRect;
+}
+
+// =======================================================================
+#ifdef REMOTE_APPSERVER
+void ImplBorderWindow::ImplInit( Window* pParent,
+ WinBits nStyle, USHORT nTypeStyle,
+ SystemParentData* pSystemParentData
+ )
+{
+ static ::com::sun::star::uno::Any aVoid;
+
+ DBG_ASSERT( pSystemParentData, "remote and non remote confusion, please clarify" );
+ ImplInit( pParent, nStyle, nTypeStyle, aVoid );
+}
+#else
+void ImplBorderWindow::ImplInit( Window* pParent,
+ WinBits nStyle, USHORT nTypeStyle,
+ const ::com::sun::star::uno::Any& aSystemToken )
+{
+ ImplInit( pParent, nStyle, nTypeStyle, NULL );
+}
+#endif
+
+#ifndef REMOTE_APPSERVER
+void ImplBorderWindow::ImplInit( Window* pParent,
+ WinBits nStyle, USHORT nTypeStyle,
+ SystemParentData* pSystemParentData
+ )
+#else
+void ImplBorderWindow::ImplInit( Window* pParent,
+ WinBits nStyle,
+ USHORT nTypeStyle,
+ const ::com::sun::star::uno::Any& aSystemToken
+ )
+#endif
+{
+ // Alle WindowBits entfernen, die wir nicht haben wollen
+ WinBits nOrgStyle = nStyle;
+ WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_PINABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL);
+ if ( nTypeStyle & BORDERWINDOW_STYLE_APP )
+ nTestStyle |= WB_APP;
+ nStyle &= nTestStyle;
+
+ mbBorderWin = TRUE;
+ mbSmallOutBorder = FALSE;
+ if ( nTypeStyle & BORDERWINDOW_STYLE_FRAME )
+ {
+ mbOverlapWin = TRUE;
+ mbFrame = TRUE;
+ mbFrameBorder = FALSE;
+ if ( (nOrgStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE)) == WB_BORDER )
+ mbSmallOutBorder = TRUE;
+ }
+ else if ( nTypeStyle & BORDERWINDOW_STYLE_OVERLAP )
+ {
+ mbOverlapWin = TRUE;
+ mbFrameBorder = TRUE;
+ }
+ else
+ mbFrameBorder = FALSE;
+
+ if ( nTypeStyle & BORDERWINDOW_STYLE_FLOAT )
+ mbFloatWindow = TRUE;
+ else
+ mbFloatWindow = FALSE;
+
+#ifndef REMOTE_APPSERVER
+ Window::ImplInit( pParent, nStyle, pSystemParentData );
+#else
+ Window::ImplInit( pParent, nStyle, aSystemToken );
+#endif
+ SetBackground();
+ SetTextFillColor();
+
+ mpMenuBarWindow = NULL;
+ mnMinWidth = 0;
+ mnMinHeight = 0;
+ mnRollHeight = 0;
+ mnOrgMenuHeight = 0;
+ mbPined = FALSE;
+ mbRollUp = FALSE;
+ mbMenuHide = FALSE;
+ mbDockBtn = FALSE;
+ mbHideBtn = FALSE;
+ mbHelpBtn = FALSE;
+ mbDisplayActive = IsActive();
+
+ if ( nTypeStyle & BORDERWINDOW_STYLE_FLOAT )
+ mnTitleType = BORDERWINDOW_TITLE_SMALL;
+ else
+ mnTitleType = BORDERWINDOW_TITLE_NORMAL;
+ mnBorderStyle = WINDOW_BORDER_NORMAL;
+ InitView();
+}
+
+// =======================================================================
+
+ImplBorderWindow::ImplBorderWindow( Window* pParent,
+ SystemParentData* pSystemParentData,
+ WinBits nStyle, USHORT nTypeStyle
+ ) : Window( WINDOW_BORDERWINDOW )
+{
+ ImplInit( pParent, nStyle, nTypeStyle, pSystemParentData );
+}
+
+// -----------------------------------------------------------------------
+
+ImplBorderWindow::ImplBorderWindow( Window* pParent, WinBits nStyle ,
+ USHORT nTypeStyle ) :
+ Window( WINDOW_BORDERWINDOW )
+{
+ Reference< ::com::sun::star::portal::client::XRmFrameWindow > rxFrameWin;
+ ImplInit( pParent, nStyle, nTypeStyle, ::com::sun::star::uno::Any() );
+}
+
+ImplBorderWindow::ImplBorderWindow( Window* pParent,
+ WinBits nStyle, USHORT nTypeStyle,
+ const ::com::sun::star::uno::Any& aSystemToken ) :
+ Window( WINDOW_BORDERWINDOW )
+{
+ ImplInit( pParent, nStyle, nTypeStyle, aSystemToken );
+}
+
+// -----------------------------------------------------------------------
+
+ImplBorderWindow::~ImplBorderWindow()
+{
+ delete mpBorderView;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ mpBorderView->MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ mpBorderView->MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::Tracking( const TrackingEvent& rTEvt )
+{
+ mpBorderView->Tracking( rTEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::Paint( const Rectangle& rRect )
+{
+ mpBorderView->DrawWindow( BORDERWINDOW_DRAW_ALL );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::Activate()
+{
+ SetDisplayActive( TRUE );
+ Window::Activate();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::Deactivate()
+{
+ // Fenster die immer Active sind, nehmen wir von dieser Regel aus,
+ // genauso, wenn ein Menu aktiv wird, ignorieren wir das Deactivate
+ if ( GetActivateMode() && !ImplGetSVData()->maWinData.mbNoDeactivate )
+ SetDisplayActive( FALSE );
+ Window::Deactivate();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
+ {
+ Point aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
+ Rectangle aHelpRect;
+ USHORT nHelpResId = mpBorderView->RequestHelp( aMousePosPixel, aHelpRect );
+
+ // Rechteck ermitteln
+ if ( nHelpResId )
+ {
+ Point aPt = OutputToScreenPixel( aHelpRect.TopLeft() );
+ aHelpRect.Left() = aPt.X();
+ aHelpRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aHelpRect.BottomRight() );
+ aHelpRect.Right() = aPt.X();
+ aHelpRect.Bottom() = aPt.Y();
+
+ // Text ermitteln und anzeigen
+ XubString aStr( ResId( nHelpResId, ImplGetResMgr() ) );
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aStr );
+ else
+ Help::ShowQuickHelp( this, aHelpRect, aStr );
+ return;
+ }
+ }
+
+ Window::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::Resize()
+{
+ Size aSize = GetOutputSizePixel();
+
+ if ( !mbRollUp )
+ {
+ Window* pClientWindow = ImplGetClientWindow();
+
+ if ( mpMenuBarWindow )
+ {
+ long nLeftBorder;
+ long nTopBorder;
+ long nRightBorder;
+ long nBottomBorder;
+ long nMenuHeight = mpMenuBarWindow->GetSizePixel().Height();
+ if ( mbMenuHide )
+ {
+ if ( nMenuHeight )
+ mnOrgMenuHeight = nMenuHeight;
+ nMenuHeight = 0;
+ }
+ else
+ {
+ if ( !nMenuHeight )
+ nMenuHeight = mnOrgMenuHeight;
+ }
+ mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
+ mpMenuBarWindow->SetPosSizePixel( nLeftBorder,
+ nTopBorder,
+ aSize.Width()-nLeftBorder-nRightBorder,
+ nMenuHeight,
+ WINDOW_POSSIZE_POS |
+ WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT );
+ }
+
+ GetBorder( pClientWindow->mnLeftBorder, pClientWindow->mnTopBorder,
+ pClientWindow->mnRightBorder, pClientWindow->mnBottomBorder );
+ pClientWindow->ImplPosSizeWindow( pClientWindow->mnLeftBorder,
+ pClientWindow->mnTopBorder,
+ aSize.Width()-pClientWindow->mnLeftBorder-pClientWindow->mnRightBorder,
+ aSize.Height()-pClientWindow->mnTopBorder-pClientWindow->mnBottomBorder,
+ WINDOW_POSSIZE_X | WINDOW_POSSIZE_Y |
+ WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT );
+ }
+
+ // UpdateView
+ mpBorderView->Init( this, aSize.Width(), aSize.Height() );
+ InvalidateBorder();
+
+ Window::Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::StateChanged( StateChangedType nType )
+{
+ if ( (nType == STATE_CHANGE_TEXT) ||
+ (nType == STATE_CHANGE_IMAGE) ||
+ (nType == STATE_CHANGE_DATA) )
+ {
+ if ( IsReallyVisible() && mbFrameBorder )
+ {
+ if ( HasPaintEvent() )
+ InvalidateBorder();
+ else
+ mpBorderView->DrawWindow( BORDERWINDOW_DRAW_TITLE );
+ }
+ }
+
+ Window::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ if ( !mbFrame )
+ UpdateView( TRUE, ImplGetWindow()->GetOutputSizePixel() );
+ }
+
+ Window::DataChanged( rDCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::InitView()
+{
+ if ( mbSmallOutBorder )
+ mpBorderView = new ImplSmallBorderWindowView( this );
+ else if ( mbFrame )
+ mpBorderView = new ImplNoBorderWindowView( this );
+ else if ( !mbFrameBorder )
+ mpBorderView = new ImplSmallBorderWindowView( this );
+ else if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_MACSTYLE )
+ mpBorderView = new ImplMacBorderWindowView( this );
+ else if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_OS2STYLE )
+ mpBorderView = new ImplOS2BorderWindowView( this );
+ else if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_UNIXSTYLE )
+ mpBorderView = new ImplUnxBorderWindowView( this );
+ else
+ mpBorderView = new ImplStdBorderWindowView( this );
+ Size aSize = GetOutputSizePixel();
+ mpBorderView->Init( this, aSize.Width(), aSize.Height() );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::UpdateView( BOOL bNewView, const Size& rNewOutSize )
+{
+ long nLeftBorder;
+ long nTopBorder;
+ long nRightBorder;
+ long nBottomBorder;
+ Size aOldSize = GetSizePixel();
+ Size aOutputSize = rNewOutSize;
+
+ if ( bNewView )
+ {
+ delete mpBorderView;
+ InitView();
+ }
+ else
+ {
+ Size aSize = aOutputSize;
+ mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
+ aSize.Width() += nLeftBorder+nRightBorder;
+ aSize.Height() += nTopBorder+nBottomBorder;
+ mpBorderView->Init( this, aSize.Width(), aSize.Height() );
+ }
+
+ Window* pClientWindow = ImplGetClientWindow();
+ if ( pClientWindow )
+ {
+ GetBorder( pClientWindow->mnLeftBorder, pClientWindow->mnTopBorder,
+ pClientWindow->mnRightBorder, pClientWindow->mnBottomBorder );
+ }
+ GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
+ if ( aOldSize.Width() || aOldSize.Height() )
+ {
+ aOutputSize.Width() += nLeftBorder+nRightBorder;
+ aOutputSize.Height() += nTopBorder+nBottomBorder;
+ if ( aOutputSize == GetSizePixel() )
+ InvalidateBorder();
+ else
+ SetSizePixel( aOutputSize );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::InvalidateBorder()
+{
+ if ( IsReallyVisible() )
+ {
+ // Nur wenn wir einen Border haben, muessen wir auch invalidieren
+ long nLeftBorder;
+ long nTopBorder;
+ long nRightBorder;
+ long nBottomBorder;
+ mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
+ if ( nLeftBorder || nTopBorder || nRightBorder || nBottomBorder )
+ {
+ Rectangle aWinRect( Point( 0, 0 ), GetOutputSizePixel() );
+ Region aRegion( aWinRect );
+ aWinRect.Left() += nLeftBorder;
+ aWinRect.Top() += nTopBorder;
+ aWinRect.Right() -= nRightBorder;
+ aWinRect.Bottom() -= nBottomBorder;
+ // kein Output-Bereich mehr, dann alles invalidieren
+ if ( (aWinRect.Right() < aWinRect.Left()) ||
+ (aWinRect.Bottom() < aWinRect.Top()) )
+ Invalidate( INVALIDATE_NOCHILDREN );
+ else
+ {
+ aRegion.Exclude( aWinRect );
+ Invalidate( aRegion, INVALIDATE_NOCHILDREN );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetDisplayActive( BOOL bActive )
+{
+ if ( mbDisplayActive != bActive )
+ {
+ mbDisplayActive = bActive;
+ if ( mbFrameBorder )
+ InvalidateBorder();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetTitleType( USHORT nTitleType, const Size& rSize )
+{
+ mnTitleType = nTitleType;
+ UpdateView( FALSE, rSize );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetBorderStyle( USHORT nStyle )
+{
+ if ( !mbFrameBorder && (mnBorderStyle != nStyle) )
+ {
+ mnBorderStyle = nStyle;
+ UpdateView( FALSE, ImplGetWindow()->GetOutputSizePixel() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetPin( BOOL bPin )
+{
+ mbPined = bPin;
+ InvalidateBorder();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetRollUp( BOOL bRollUp, const Size& rSize )
+{
+ mbRollUp = bRollUp;
+ mnRollHeight = rSize.Height();
+ UpdateView( FALSE, rSize );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetCloser()
+{
+ SetStyle( GetStyle() | WB_CLOSEABLE );
+ Size aSize = GetOutputSizePixel();
+ mpBorderView->Init( this, aSize.Width(), aSize.Height() );
+ InvalidateBorder();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetDockButton( BOOL bDockButton )
+{
+ mbDockBtn = bDockButton;
+ Size aSize = GetOutputSizePixel();
+ mpBorderView->Init( this, aSize.Width(), aSize.Height() );
+ InvalidateBorder();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetHideButton( BOOL bHideButton )
+{
+ mbHideBtn = bHideButton;
+ Size aSize = GetOutputSizePixel();
+ mpBorderView->Init( this, aSize.Width(), aSize.Height() );
+ InvalidateBorder();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetHelpButton( BOOL bHelpButton )
+{
+ mbHelpBtn = bHelpButton;
+ Size aSize = GetOutputSizePixel();
+ mpBorderView->Init( this, aSize.Width(), aSize.Height() );
+ InvalidateBorder();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::UpdateMenuHeight()
+{
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetMenuBarWindow( Window* pWindow )
+{
+ mpMenuBarWindow = pWindow;
+ UpdateMenuHeight();
+ if ( pWindow )
+ pWindow->Show();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::SetMenuBarMode( BOOL bHide )
+{
+ mbMenuHide = bHide;
+ UpdateMenuHeight();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplBorderWindow::GetBorder( long& rLeftBorder, long& rTopBorder,
+ long& rRightBorder, long& rBottomBorder ) const
+{
+ mpBorderView->GetBorder( rLeftBorder, rTopBorder, rRightBorder, rBottomBorder );
+ if ( mpMenuBarWindow && !mbMenuHide )
+ rTopBorder += mpMenuBarWindow->GetSizePixel().Height();
+}
+
+// -----------------------------------------------------------------------
+
+long ImplBorderWindow::CalcTitleWidth() const
+{
+ return mpBorderView->CalcTitleWidth();
+}
diff --git a/vcl/source/window/btndlg.cxx b/vcl/source/window/btndlg.cxx
new file mode 100644
index 000000000000..185da6bd83e0
--- /dev/null
+++ b/vcl/source/window/btndlg.cxx
@@ -0,0 +1,584 @@
+/*************************************************************************
+ *
+ * $RCSfile: btndlg.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_BTNDLG_CXX
+#include <tools/ref.hxx>
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_BUTTON_HXX
+#include <button.hxx>
+#endif
+#ifndef _SV_BTNDLG_HXX
+#include <btndlg.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+
+
+#pragma hdrstop
+
+// =======================================================================
+
+struct ImplBtnDlgItem
+{
+ USHORT mnId;
+ BOOL mbOwnButton;
+ BOOL mbDummyAlign;
+ long mnSepSize;
+ PushButton* mpPushButton;
+};
+
+DECLARE_LIST( ImplBtnDlgItemList, ImplBtnDlgItem* );
+
+// =======================================================================
+
+void ButtonDialog::ImplInitData()
+{
+ mpItemList = new ImplBtnDlgItemList( 8, 8 );
+ mnButtonSize = 0;
+ mnCurButtonId = 0;
+ mnFocusButtonId = BUTTONDIALOG_BUTTON_NOTFOUND;
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+ButtonDialog::ButtonDialog( WindowType nType ) :
+ Dialog( nType )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+ButtonDialog::ButtonDialog( Window* pParent, WinBits nStyle ) :
+ Dialog( WINDOW_TABDIALOG )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+ButtonDialog::ButtonDialog( Window* pParent, const ResId& rResId ) :
+ Dialog( WINDOW_BUTTONDIALOG )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_DIALOG ); // !!!!!!!!!! RSC_BUTTONDIALOG !!!!!!!!
+ ImplInit( pParent, ImplInitRes( rResId ) );
+ ImplLoadRes( rResId );
+}
+
+// -----------------------------------------------------------------------
+
+ButtonDialog::~ButtonDialog()
+{
+ ImplBtnDlgItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mpPushButton && pItem->mbOwnButton )
+ delete pItem->mpPushButton;
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ delete mpItemList;
+}
+
+// -----------------------------------------------------------------------
+
+PushButton* ButtonDialog::ImplCreatePushButton( USHORT nBtnFlags )
+{
+ PushButton* pBtn;
+ WinBits nStyle = 0;
+
+ if ( nBtnFlags & BUTTONDIALOG_DEFBUTTON )
+ nStyle |= WB_DEFBUTTON;
+ if ( nBtnFlags & BUTTONDIALOG_CANCELBUTTON )
+ pBtn = new CancelButton( this, nStyle );
+ else if ( nBtnFlags & BUTTONDIALOG_OKBUTTON )
+ pBtn = new OKButton( this, nStyle );
+ else if ( nBtnFlags & BUTTONDIALOG_HELPBUTTON )
+ pBtn = new HelpButton( this, nStyle );
+ else
+ pBtn = new PushButton( this, nStyle );
+
+ if ( !(nBtnFlags & BUTTONDIALOG_HELPBUTTON) )
+ pBtn->SetClickHdl( LINK( this, ButtonDialog, ImplClickHdl ) );
+
+ return pBtn;
+}
+
+// -----------------------------------------------------------------------
+
+ImplBtnDlgItem* ButtonDialog::ImplGetItem( USHORT nId ) const
+{
+ ImplBtnDlgItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nId )
+ return pItem;
+
+ pItem = mpItemList->Next();
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+long ButtonDialog::ImplGetButtonSize()
+{
+ if ( !mbFormat )
+ return mnButtonSize;
+
+ // Calculate ButtonSize
+ long nLastSepSize = 0;
+ long nSepSize = 0;
+ long nButtonCount = 0;
+ maCtrlSize = Size( IMPL_MINSIZE_BUTTON_WIDTH, IMPL_MINSIZE_BUTTON_HEIGHT );
+ ImplBtnDlgItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ nSepSize += nLastSepSize;
+
+ long nTxtWidth = pItem->mpPushButton->GetCtrlTextWidth( pItem->mpPushButton->GetText() );
+ nTxtWidth += IMPL_EXTRA_BUTTON_WIDTH;
+ if ( nTxtWidth > maCtrlSize.Width() )
+ maCtrlSize.Width() = nTxtWidth;
+ long nTxtHeight = pItem->mpPushButton->GetTextHeight();
+ nTxtHeight += IMPL_EXTRA_BUTTON_HEIGHT;
+ if ( nTxtHeight > maCtrlSize.Height() )
+ maCtrlSize.Height() = nTxtHeight;
+
+ nSepSize += pItem->mnSepSize;
+
+ if ( GetStyle() & WB_HORZ )
+ nLastSepSize = IMPL_SEP_BUTTON_X;
+ else
+ nLastSepSize = IMPL_SEP_BUTTON_Y;
+
+ nButtonCount++;
+
+ pItem = mpItemList->Next();
+ }
+
+ if ( GetStyle() & WB_HORZ )
+ mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Width());
+ else
+ mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Height());
+
+ return mnButtonSize;
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::ImplPosControls()
+{
+ if ( !mbFormat )
+ return;
+
+ // Create PushButtons and determine Sizes
+ ImplGetButtonSize();
+
+ // determine dialog size
+ ImplBtnDlgItem* pItem;
+ Size aDlgSize = maPageSize;
+ long nX;
+ long nY;
+ if ( GetStyle() & WB_HORZ )
+ {
+ if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Width() )
+ aDlgSize.Width() = mnButtonSize+(IMPL_DIALOG_OFFSET*2);
+ if ( GetStyle() & WB_LEFT )
+ nX = IMPL_DIALOG_OFFSET;
+ else if ( GetStyle() & WB_RIGHT )
+ nX = aDlgSize.Width()-mnButtonSize-IMPL_DIALOG_OFFSET;
+ else
+ nX = (aDlgSize.Width()-mnButtonSize)/2;
+
+ aDlgSize.Height() += IMPL_DIALOG_OFFSET+maCtrlSize.Height();
+ nY = aDlgSize.Height()-maCtrlSize.Height()-IMPL_DIALOG_OFFSET;
+ }
+ else
+ {
+ if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Height() )
+ aDlgSize.Height() = mnButtonSize+(IMPL_DIALOG_OFFSET*2);
+ if ( GetStyle() & WB_BOTTOM )
+ nY = aDlgSize.Height()-mnButtonSize-IMPL_DIALOG_OFFSET;
+ else if ( GetStyle() & WB_VCENTER )
+ nY = (aDlgSize.Height()-mnButtonSize)/2;
+ else
+ nY = IMPL_DIALOG_OFFSET;
+
+ aDlgSize.Width() += IMPL_DIALOG_OFFSET+maCtrlSize.Width();
+ nX = aDlgSize.Width()-maCtrlSize.Width()-IMPL_DIALOG_OFFSET;
+ }
+
+ // Arrange PushButtons
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( GetStyle() & WB_HORZ )
+ nX += pItem->mnSepSize;
+ else
+ nY += pItem->mnSepSize;
+ pItem->mpPushButton->SetPosSizePixel( Point( nX, nY ), maCtrlSize );
+ pItem->mpPushButton->Show();
+ if ( GetStyle() & WB_HORZ )
+ nX += maCtrlSize.Width()+IMPL_SEP_BUTTON_X;
+ else
+ nY += maCtrlSize.Height()+IMPL_SEP_BUTTON_Y;
+
+ pItem = mpItemList->Next();
+ }
+
+ SetOutputSizePixel( aDlgSize );
+
+ mbFormat = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ButtonDialog, ImplClickHdl, PushButton*, pBtn )
+{
+ ImplBtnDlgItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mpPushButton == pBtn )
+ {
+ mnCurButtonId = pItem->mnId;
+ Click();
+ break;
+ }
+
+ pItem = mpItemList->Next();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::Resize()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ ImplPosControls();
+
+ // Focus evt. auf den entsprechenden Button setzen
+ if ( mnFocusButtonId != BUTTONDIALOG_BUTTON_NOTFOUND )
+ {
+ ImplBtnDlgItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == mnFocusButtonId )
+ {
+ if ( pItem->mpPushButton->IsVisible() )
+ pItem->mpPushButton->GrabFocus();
+ break;
+ }
+
+ pItem = mpItemList->Next();
+ }
+ }
+ }
+
+ Dialog::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::Click()
+{
+ if ( !maClickHdl )
+ {
+ if ( IsInExecute() )
+ EndDialog( GetCurButtonId() );
+ }
+ else
+ maClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::AddButton( const XubString& rText, USHORT nId,
+ USHORT nBtnFlags, long nSepPixel )
+{
+ // PageItem anlegen
+ ImplBtnDlgItem* pItem = new ImplBtnDlgItem;
+ pItem->mnId = nId;
+ pItem->mbOwnButton = TRUE;
+ pItem->mnSepSize = nSepPixel;
+ pItem->mpPushButton = ImplCreatePushButton( nBtnFlags );
+ if ( rText.Len() )
+ pItem->mpPushButton->SetText( rText );
+
+ // In die StarView-Liste eintragen
+ mpItemList->Insert( pItem, LIST_APPEND );
+
+ if ( nBtnFlags & BUTTONDIALOG_FOCUSBUTTON )
+ mnFocusButtonId = nId;
+
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::AddButton( StandardButtonType eType, USHORT nId,
+ USHORT nBtnFlags, long nSepPixel )
+{
+ // PageItem anlegen
+ ImplBtnDlgItem* pItem = new ImplBtnDlgItem;
+ pItem->mnId = nId;
+ pItem->mbOwnButton = TRUE;
+ pItem->mnSepSize = nSepPixel;
+
+ if ( eType == BUTTON_HELP )
+ nBtnFlags |= BUTTONDIALOG_HELPBUTTON;
+ else if ( (eType == BUTTON_CANCEL) || (eType == BUTTON_CLOSE) )
+ nBtnFlags |= BUTTONDIALOG_CANCELBUTTON;
+ pItem->mpPushButton = ImplCreatePushButton( nBtnFlags );
+ pItem->mpPushButton->SetText( Button::GetStandardText( eType ) );
+ pItem->mpPushButton->SetHelpText( Button::GetStandardHelpText( eType ) );
+
+ if ( nBtnFlags & BUTTONDIALOG_FOCUSBUTTON )
+ mnFocusButtonId = nId;
+
+ // In die StarView-Liste eintragen
+ mpItemList->Insert( pItem, LIST_APPEND );
+
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::AddButton( PushButton* pBtn, USHORT nId,
+ USHORT nBtnFlags, long nSepPixel )
+{
+ // PageItem anlegen
+ ImplBtnDlgItem* pItem = new ImplBtnDlgItem;
+ pItem->mnId = nId;
+ pItem->mbOwnButton = FALSE;
+ pItem->mnSepSize = nSepPixel;
+ pItem->mpPushButton = pBtn;
+
+ if ( nBtnFlags & BUTTONDIALOG_FOCUSBUTTON )
+ mnFocusButtonId = nId;
+
+ // In die StarView-Liste eintragen
+ mpItemList->Insert( pItem, LIST_APPEND );
+
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::RemoveButton( USHORT nId )
+{
+ ImplBtnDlgItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nId )
+ {
+ pItem->mpPushButton->Hide();
+ if ( pItem->mbOwnButton )
+ delete pItem->mpPushButton;
+ delete pItem;
+ mpItemList->Remove();
+ mbFormat = TRUE;
+ break;
+ }
+
+ pItem = mpItemList->Next();
+ }
+
+ DBG_ERRORFILE( "ButtonDialog::RemoveButton(): ButtonId invalid" );
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::Clear()
+{
+ ImplBtnDlgItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ pItem->mpPushButton->Hide();
+ if ( pItem->mbOwnButton )
+ delete pItem->mpPushButton;
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ mpItemList->Clear();
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ButtonDialog::GetButtonCount() const
+{
+ return (USHORT)mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ButtonDialog::GetButtonId( USHORT nButton ) const
+{
+ if ( nButton < mpItemList->Count() )
+ return (USHORT)mpItemList->GetObject( nButton )->mnId;
+ else
+ return BUTTONDIALOG_BUTTON_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+PushButton* ButtonDialog::GetPushButton( USHORT nId ) const
+{
+ ImplBtnDlgItem* pItem = ImplGetItem( nId );
+
+ if ( pItem )
+ return pItem->mpPushButton;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::SetButtonText( USHORT nId, const XubString& rText )
+{
+ ImplBtnDlgItem* pItem = ImplGetItem( nId );
+
+ if ( pItem )
+ {
+ pItem->mpPushButton->SetText( rText );
+ mbFormat = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString ButtonDialog::GetButtonText( USHORT nId ) const
+{
+ ImplBtnDlgItem* pItem = ImplGetItem( nId );
+
+ if ( pItem )
+ return pItem->mpPushButton->GetText();
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::SetButtonHelpText( USHORT nId, const XubString& rText )
+{
+ ImplBtnDlgItem* pItem = ImplGetItem( nId );
+
+ if ( pItem )
+ pItem->mpPushButton->SetHelpText( rText );
+}
+
+// -----------------------------------------------------------------------
+
+XubString ButtonDialog::GetButtonHelpText( USHORT nId ) const
+{
+ ImplBtnDlgItem* pItem = ImplGetItem( nId );
+
+ if ( pItem )
+ return pItem->mpPushButton->GetHelpText();
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void ButtonDialog::SetButtonHelpId( USHORT nId, ULONG nHelpId )
+{
+ ImplBtnDlgItem* pItem = ImplGetItem( nId );
+
+ if ( pItem )
+ pItem->mpPushButton->SetHelpId( nHelpId );
+}
+
+// -----------------------------------------------------------------------
+
+ULONG ButtonDialog::GetButtonHelpId( USHORT nId ) const
+{
+ ImplBtnDlgItem* pItem = ImplGetItem( nId );
+
+ if ( pItem )
+ return pItem->mpPushButton->GetHelpId();
+ else
+ return 0;
+}
diff --git a/vcl/source/window/cursor.cxx b/vcl/source/window/cursor.cxx
new file mode 100644
index 000000000000..ec2bb1c80506
--- /dev/null
+++ b/vcl/source/window/cursor.cxx
@@ -0,0 +1,449 @@
+/*************************************************************************
+ *
+ * $RCSfile: cursor.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_CURSOR_CXX
+
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_CURSOR_HXX
+#include <cursor.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+struct ImplCursorData
+{
+ AutoTimer maTimer; // Timer
+ Point maPixPos; // Pixel-Position
+ Point maPixRotOff; // Pixel-Offset-Position
+ Size maPixSize; // Pixel-Size
+ long mnPixSlant; // Pixel-Slant
+ short mnOrientation; // Pixel-Orientation
+ USHORT mnStyle; // Cursor-Style
+ BOOL mbCurVisible; // Ist Cursor aktuell sichtbar
+ Window* mpWindow; // Zugeordnetes Windows
+};
+
+// =======================================================================
+
+static void ImplCursorInvert( ImplCursorData* pData )
+{
+ Window* pWindow = pData->mpWindow;
+ BOOL bMapMode = pWindow->IsMapModeEnabled();
+ pWindow->EnableMapMode( FALSE );
+ USHORT nInvertStyle;
+ if ( pData->mnStyle & CURSOR_SHADOW )
+ nInvertStyle = INVERT_50;
+ else
+ nInvertStyle = 0;
+ Rectangle aRect( pData->maPixPos, pData->maPixSize );
+ if ( pData->mnOrientation || pData->mnPixSlant )
+ {
+ Polygon aPoly( aRect );
+ if ( pData->mnPixSlant )
+ {
+ Point aPoint = aPoly.GetPoint( 0 );
+ aPoint.X() += pData->mnPixSlant;
+ aPoly.SetPoint( aPoint, 0 );
+ aPoly.SetPoint( aPoint, 4 );
+ aPoint = aPoly.GetPoint( 1 );
+ aPoint.X() += pData->mnPixSlant;
+ aPoly.SetPoint( aPoint, 1 );
+ }
+ if ( pData->mnOrientation )
+ aPoly.Rotate( pData->maPixRotOff, pData->mnOrientation );
+ pWindow->Invert( aPoly, nInvertStyle );
+ }
+ else
+ pWindow->Invert( aRect, nInvertStyle );
+ pWindow->EnableMapMode( bMapMode );
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::ImplDraw()
+{
+ if ( mpData && mpData->mpWindow && !mpData->mbCurVisible )
+ {
+ Window* pWindow = mpData->mpWindow;
+ mpData->maPixPos = pWindow->LogicToPixel( maPos );
+ mpData->maPixSize = pWindow->LogicToPixel( maSize );
+ mpData->mnPixSlant = pWindow->LogicToPixel( Size( mnSlant, 0 ) ).Width();
+ mpData->mnOrientation = mnOrientation;
+ long nOffsetY = pWindow->LogicToPixel( Size( 0, mnOffsetY ) ).Height();
+
+ // Position um den Offset korrigieren
+ mpData->maPixPos.Y() -= nOffsetY;
+ mpData->maPixRotOff = mpData->maPixPos;
+ mpData->maPixRotOff.Y() += nOffsetY;
+
+ // Wenn groesse 0 ist, nehmen wir die breite, die in den
+ // Settings eingestellt ist
+ if ( !mpData->maPixSize.Width() )
+ mpData->maPixSize.Width() = pWindow->GetSettings().GetStyleSettings().GetCursorSize();
+
+ // Ausgabeflaeche berechnen und ausgeben
+ ImplCursorInvert( mpData );
+ mpData->mbCurVisible = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::ImplRestore()
+{
+ if ( mpData && mpData->mbCurVisible )
+ {
+ ImplCursorInvert( mpData );
+ mpData->mbCurVisible = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::ImplShow( BOOL bDrawDirect )
+{
+ if ( mbVisible )
+ {
+ Window* pWindow;
+ if ( mpWindow )
+ pWindow = mpWindow;
+ else
+ {
+ // Gibt es ein aktives Fenster und ist der Cursor in dieses Fenster
+ // selektiert, dann zeige den Cursor an
+ pWindow = Application::GetFocusWindow();
+ if ( !pWindow || (pWindow->mpCursor != this) || pWindow->mbInPaint )
+ pWindow = NULL;
+ }
+
+ if ( pWindow )
+ {
+ if ( !mpData )
+ {
+ mpData = new ImplCursorData;
+ mpData->mbCurVisible = FALSE;
+ mpData->maTimer.SetTimeoutHdl( LINK( this, Cursor, ImplTimerHdl ) );
+ }
+
+ mpData->mpWindow = pWindow;
+ mpData->mnStyle = mnStyle;
+ if ( bDrawDirect )
+ ImplDraw();
+
+ if ( !mpWindow )
+ {
+ mpData->maTimer.SetTimeout( pWindow->GetSettings().GetStyleSettings().GetCursorBlinkTime() );
+ if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
+ mpData->maTimer.Start();
+ else if ( !mpData->mbCurVisible )
+ ImplDraw();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::ImplHide()
+{
+ if ( mpData && mpData->mpWindow )
+ {
+ if ( mpData->mbCurVisible )
+ ImplRestore();
+
+ mpData->maTimer.Stop();
+ mpData->mpWindow = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::ImplNew()
+{
+ if ( mbVisible && mpData && mpData->mpWindow )
+ {
+ if ( mpData->mbCurVisible )
+ ImplRestore();
+
+ ImplDraw();
+ if ( !mpWindow )
+ {
+ if ( mpData->maTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
+ mpData->maTimer.Start();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Cursor, ImplTimerHdl, AutoTimer*, EMPTYARG )
+{
+ if ( mpData->mbCurVisible )
+ ImplRestore();
+ else
+ ImplDraw();
+ return 0;
+}
+
+// =======================================================================
+
+Cursor::Cursor()
+{
+ mpData = NULL;
+ mpWindow = NULL;
+ mnSlant = 0;
+ mnOffsetY = 0;
+ mnOrientation = 0;
+ mnStyle = 0;
+ mbVisible = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Cursor::Cursor( const Cursor& rCursor ) :
+ maPos( rCursor.maPos ),
+ maSize( rCursor.maSize )
+{
+ mpData = NULL;
+ mpWindow = NULL;
+ mnSlant = rCursor.mnSlant;
+ mnOrientation = rCursor.mnOrientation;
+ mnStyle = 0;
+ mbVisible = rCursor.mbVisible;
+}
+
+// -----------------------------------------------------------------------
+
+Cursor::~Cursor()
+{
+ if ( mpData )
+ {
+ if ( mpData->mbCurVisible )
+ ImplRestore();
+
+ delete mpData;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::SetStyle( USHORT nStyle )
+{
+ if ( mnStyle != nStyle )
+ {
+ mnStyle = nStyle;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::Show()
+{
+ if ( !mbVisible )
+ {
+ mbVisible = TRUE;
+ ImplShow();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::Hide()
+{
+ if ( mbVisible )
+ {
+ mbVisible = FALSE;
+ ImplHide();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::SetWindow( Window* pWindow )
+{
+ if ( mpWindow != pWindow )
+ {
+ mpWindow = pWindow;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::SetPos( const Point& rPoint )
+{
+ if ( maPos != rPoint )
+ {
+ maPos = rPoint;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::SetOffsetY( long nNewOffsetY )
+{
+ if ( mnOffsetY != nNewOffsetY )
+ {
+ mnOffsetY = nNewOffsetY;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::SetSize( const Size& rSize )
+{
+ if ( maSize != rSize )
+ {
+ maSize = rSize;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::SetWidth( long nNewWidth )
+{
+ if ( maSize.Width() != nNewWidth )
+ {
+ maSize.Width() = nNewWidth;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::SetHeight( long nNewHeight )
+{
+ if ( maSize.Height() != nNewHeight )
+ {
+ maSize.Height() = nNewHeight;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::SetSlant( long nNewSlant )
+{
+ if ( mnSlant != nNewSlant )
+ {
+ mnSlant = nNewSlant;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Cursor::SetOrientation( short nNewOrientation )
+{
+ if ( mnOrientation != nNewOrientation )
+ {
+ mnOrientation = nNewOrientation;
+ ImplNew();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Cursor& Cursor::operator=( const Cursor& rCursor )
+{
+ maPos = rCursor.maPos;
+ maSize = rCursor.maSize;
+ mnSlant = rCursor.mnSlant;
+ mnOrientation = rCursor.mnOrientation;
+ mbVisible = rCursor.mbVisible;
+ ImplNew();
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Cursor::operator==( const Cursor& rCursor ) const
+{
+ if ( (maPos == rCursor.maPos) &&
+ (maSize == rCursor.maSize) &&
+ (mnSlant == rCursor.mnSlant) &&
+ (mnOrientation == rCursor.mnOrientation) &&
+ (mbVisible == rCursor.mbVisible) )
+ return TRUE;
+ else
+ return FALSE;
+}
diff --git a/vcl/source/window/decoview.cxx b/vcl/source/window/decoview.cxx
new file mode 100644
index 000000000000..e7169fee2131
--- /dev/null
+++ b/vcl/source/window/decoview.cxx
@@ -0,0 +1,1297 @@
+/*************************************************************************
+ *
+ * $RCSfile: decoview.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:39 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_DECOVIEW_CXX
+
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <outdev.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <bmpacc.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define BUTTON_DRAW_FLATTEST (BUTTON_DRAW_FLAT | \
+ BUTTON_DRAW_PRESSED | \
+ BUTTON_DRAW_CHECKED | \
+ BUTTON_DRAW_HIGHLIGHT)
+
+// =======================================================================
+
+void ImplDrawOS2Symbol( OutputDevice* pDev, const Rectangle& rRect,
+ USHORT nStyle, BOOL bClose )
+{
+ DecorationView aView( pDev );
+ const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
+ Rectangle aRect = rRect;
+ Color aColor1;
+ Color aColor2;
+
+ pDev->SetFillColor();
+
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ {
+ aColor1 = rStyleSettings.GetShadowColor();
+ aColor2 = rStyleSettings.GetLightColor();
+ }
+ else
+ {
+ aColor1 = rStyleSettings.GetLightColor();
+ aColor2 = rStyleSettings.GetShadowColor();
+ }
+ aView.DrawFrame( aRect, aColor1, aColor2 );
+
+ aRect.Left() += 2;
+ aRect.Top() += 2;
+ aRect.Right() -= 2;
+ aRect.Bottom() -= 2;
+
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ else
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ if ( bClose )
+ {
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-2 ) );
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right()-2, aRect.Top() ) );
+ pDev->DrawLine( Point( aRect.Left()+2, aRect.Bottom()-1 ),
+ Point( aRect.Right()-1, aRect.Top()+2 ) );
+ }
+ else
+ {
+ pDev->DrawLine( aRect.TopLeft(), aRect.BottomLeft() );
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
+ }
+
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ else
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ if ( bClose )
+ {
+ pDev->DrawLine( Point( aRect.Right(), aRect.Top()+2 ), aRect.BottomRight() );
+ pDev->DrawLine( Point( aRect.Left()+2, aRect.Bottom() ), aRect.BottomRight() );
+ pDev->DrawLine( Point( aRect.Right()-2, aRect.Top()+1 ),
+ Point( aRect.Left()+1, aRect.Bottom()-2 ) );
+ }
+ else
+ {
+ pDev->DrawLine( aRect.TopRight(), aRect.BottomRight() );
+ pDev->DrawLine( Point( aRect.Left()+1, aRect.Bottom() ), aRect.BottomRight() );
+ }
+}
+
+// =======================================================================
+
+static void ImplDrawSymbol( OutputDevice* pDev, const Rectangle& rRect,
+ SymbolType eType )
+{
+ // Groessen vorberechnen
+ long n;
+ long nHeight = rRect.GetHeight();
+ long nWidth = rRect.GetWidth();
+ if ( nWidth < nHeight )
+ n = nWidth;
+ else
+ n = nHeight;
+ if ( n & 0x01 )
+ n--;
+ Point aCenter = rRect.Center();
+ long nCenterX = aCenter.X();
+ long nCenterY = aCenter.Y();
+ long n2 = n / 2;
+ long n4 = n / 4;
+ long nLeft;
+ long nTop;
+ long nRight;
+ long nBottom;
+ long nTemp;
+ long i;
+
+ switch ( eType )
+ {
+ case SYMBOL_ARROW_UP:
+ {
+ if ( !(n & 0x01) )
+ {
+ n2--;
+ n4--;
+ }
+ nTop = nCenterY-n2;
+ nBottom = nCenterY;
+ pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nTop++;
+ nTemp = nCenterX-i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ nTemp = nCenterX+i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ i++;
+ }
+ pDev->DrawRect( Rectangle( nCenterX-n4, nBottom,
+ nCenterX+n4, nBottom+n2 ) );
+ }
+ break;
+
+ case SYMBOL_ARROW_DOWN:
+ {
+ if ( !(n & 0x01) )
+ {
+ n2--;
+ n4--;
+ }
+ nTop = nCenterY;
+ nBottom = nCenterY+n2;
+ pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nBottom--;
+ nTemp = nCenterX-i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ nTemp = nCenterX+i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ i++;
+ }
+ pDev->DrawRect( Rectangle( nCenterX-n4, nTop-n2,
+ nCenterX+n4, nTop ) );
+ }
+ break;
+
+ case SYMBOL_ARROW_LEFT:
+ {
+ if ( !(n & 0x01) )
+ {
+ n2--;
+ n4--;
+ }
+ nLeft = nCenterX-n2;
+ nRight = nCenterX;
+ pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nLeft++;
+ nTemp = nCenterY-i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ nTemp = nCenterY+i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ i++;
+ }
+ pDev->DrawRect( Rectangle( nRight, nCenterY-n4,
+ nRight+n2, nCenterY+n4 ) );
+ }
+ break;
+
+ case SYMBOL_ARROW_RIGHT:
+ {
+ if ( !(n & 0x01) )
+ {
+ n2--;
+ n4--;
+ }
+ nLeft = nCenterX;
+ nRight = nCenterX+n2;
+ pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nRight--;
+ nTemp = nCenterY-i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ nTemp = nCenterY+i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ i++;
+ }
+ pDev->DrawRect( Rectangle( nLeft-n2, nCenterY-n4,
+ nLeft, nCenterY+n4 ) );
+ }
+ break;
+
+
+ case SYMBOL_SPIN_UP:
+ {
+ if ( !(n & 0x01) )
+ n2--;
+ nTop = nCenterY-n4;
+ nBottom = nTop+n2;
+ pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nTop++;
+ nTemp = nCenterX-i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ nTemp = nCenterX+i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ i++;
+ }
+ }
+ break;
+
+ case SYMBOL_SPIN_DOWN:
+ {
+ if ( !(n & 0x01) )
+ n2--;
+ nTop = nCenterY-n4;
+ nBottom = nTop+n2;
+ pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nBottom--;
+ nTemp = nCenterX-i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ nTemp = nCenterX+i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ i++;
+ }
+ }
+ break;
+
+ case SYMBOL_SPIN_LEFT:
+ case SYMBOL_FIRST:
+ case SYMBOL_PREV:
+ case SYMBOL_REVERSEPLAY:
+ {
+ if ( !(n & 0x01) )
+ n2--;
+ nLeft = nCenterX-n4;
+ if ( eType == SYMBOL_FIRST )
+ nLeft++;
+ nRight = nLeft+n2;
+ pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nLeft++;
+ nTemp = nCenterY-i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ nTemp = nCenterY+i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ i++;
+ }
+ if ( eType == SYMBOL_FIRST )
+ {
+ pDev->DrawRect( Rectangle( nCenterX-n4-1, nCenterY-n2,
+ nCenterX-n4-1, nCenterY+n2 ) );
+ }
+ }
+ break;
+
+ case SYMBOL_SPIN_RIGHT:
+ case SYMBOL_LAST:
+ case SYMBOL_NEXT:
+ case SYMBOL_PLAY:
+ {
+ if ( !(n & 0x01) )
+ n2--;
+ nLeft = nCenterX-n4;
+ if ( eType == SYMBOL_LAST )
+ nLeft--;
+ nRight = nLeft+n2;
+ pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nRight--;
+ nTemp = nCenterY-i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ nTemp = nCenterY+i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ i++;
+ }
+ if ( eType == SYMBOL_LAST )
+ {
+ pDev->DrawRect( Rectangle( nCenterX+n4+1, nCenterY-n2,
+ nCenterX+n4+1, nCenterY+n2 ) );
+ }
+ }
+ break;
+
+ case SYMBOL_PAGEUP:
+ {
+ nTop = nCenterY-n2;
+ nBottom = nCenterY-1;
+ pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
+ pDev->DrawRect( Rectangle( nCenterX, nTop+n2+1, nCenterX, nBottom+n2+1 ) );
+ i = 1;
+ while ( i < n2 )
+ {
+ nTop++;
+ nTemp = nCenterX-i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ pDev->DrawRect( Rectangle( nTemp, nTop+n2+1, nTemp, nBottom+n2+1 ) );
+ nTemp = nCenterX+i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ pDev->DrawRect( Rectangle( nTemp, nTop+n2+1, nTemp, nBottom+n2+1 ) );
+ i++;
+ }
+ }
+ break;
+
+ case SYMBOL_PAGEDOWN:
+ {
+ nTop = nCenterY-n2;
+ nBottom = nCenterY-1;
+ pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
+ pDev->DrawRect( Rectangle( nCenterX, nTop+n2+1, nCenterX, nBottom+n2+1 ) );
+ i = 1;
+ while ( i < n2 )
+ {
+ nBottom--;
+ nTemp = nCenterX-i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ pDev->DrawRect( Rectangle( nTemp, nTop+n2+1, nTemp, nBottom+n2+1 ) );
+ nTemp = nCenterX+i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ pDev->DrawRect( Rectangle( nTemp, nTop+n2+1, nTemp, nBottom+n2+1 ) );
+ i++;
+ }
+ }
+ break;
+
+ case SYMBOL_RADIOCHECKMARK:
+ case SYMBOL_RECORD:
+ {
+ const long nExt = ( n2 << 1 ) + 1;
+ Bitmap aBmp( Size( nExt, nExt ), 1 );
+ BitmapWriteAccess* pWAcc = aBmp.AcquireWriteAccess();
+
+ if( pWAcc )
+ {
+ const Color aWhite( COL_WHITE );
+ const Color aBlack( COL_BLACK );
+
+ pWAcc->Erase( aWhite );
+ pWAcc->SetLineColor( aBlack );
+ pWAcc->SetFillColor( aBlack );
+ pWAcc->DrawPolygon( Polygon( Point( n2, n2 ), n2, n2 ) );
+ aBmp.ReleaseAccess( pWAcc );
+ pDev->DrawMask( Point( nCenterX - n2, nCenterY - n2 ), aBmp, pDev->GetFillColor() );
+ }
+ else
+ pDev->DrawPolygon( Polygon( Point( nCenterX, nCenterY ), n2, n2 ) );
+ }
+ break;
+
+ case SYMBOL_STOP:
+ {
+ nLeft = nCenterX-n2;
+ nRight = nCenterX+n2;
+ nTop = nCenterY-n2;
+ nBottom = nCenterY+n2;
+ pDev->DrawRect( Rectangle( nLeft, nTop, nRight, nBottom ) );
+ }
+ break;
+
+ case SYMBOL_PAUSE:
+ {
+ nLeft = nCenterX-n2;
+ nRight = nCenterX+n2-1;
+ nTop = nCenterY-n2;
+ nBottom = nCenterY+n2;
+ pDev->DrawRect( Rectangle( nLeft, nTop, nCenterX-2, nBottom ) );
+ pDev->DrawRect( Rectangle( nCenterX+1, nTop, nRight, nBottom ) );
+ }
+ break;
+
+ case SYMBOL_WINDSTART:
+ case SYMBOL_WINDBACKWARD:
+ {
+ nLeft = nCenterX-n2+1;
+ nRight = nCenterX;
+ pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
+ pDev->DrawRect( Rectangle( nLeft+n2, nCenterY, nRight+n2, nCenterY ) );
+ i = 1;
+ while ( i < n2 )
+ {
+ nLeft++;
+ nTemp = nCenterY-i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ pDev->DrawRect( Rectangle( nLeft+n2, nTemp, nRight+n2, nTemp ) );
+ nTemp = nCenterY+i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ pDev->DrawRect( Rectangle( nLeft+n2, nTemp, nRight+n2, nTemp ) );
+ i++;
+ }
+ if ( eType == SYMBOL_WINDSTART )
+ {
+ pDev->DrawRect( Rectangle( nCenterX-n2, nCenterY-n2,
+ nCenterX-n2, nCenterY+n2 ) );
+ }
+ }
+ break;
+
+ case SYMBOL_WINDEND:
+ case SYMBOL_WINDFORWARD:
+ {
+ nLeft = nCenterX-n2;
+ nRight = nCenterX-1;
+ pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
+ pDev->DrawRect( Rectangle( nLeft+n2, nCenterY, nRight+n2, nCenterY ) );
+ i = 1;
+ while ( i < n2 )
+ {
+ nRight--;
+ nTemp = nCenterY-i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ pDev->DrawRect( Rectangle( nLeft+n2, nTemp, nRight+n2, nTemp ) );
+ nTemp = nCenterY+i;
+ pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
+ pDev->DrawRect( Rectangle( nLeft+n2, nTemp, nRight+n2, nTemp ) );
+ i++;
+ }
+ if ( eType == SYMBOL_WINDEND )
+ {
+ pDev->DrawRect( Rectangle( nCenterX+n2, nCenterY-n2,
+ nCenterX+n2, nCenterY+n2 ) );
+ }
+ }
+ break;
+
+ case SYMBOL_CLOSE:
+ {
+ Size aRectSize( 2, 1 );
+ if ( n < 8 )
+ aRectSize.Width() = 1;
+ else if ( n > 20 )
+ aRectSize.Width() = n/10;
+ nLeft = nCenterX-n2+1;
+ nTop = nCenterY-n2+1;
+ nBottom = nCenterY-n2+n-aRectSize.Width()+1;
+ i = 0;
+ while ( i < n-aRectSize.Width()+1 )
+ {
+ pDev->DrawRect( Rectangle( Point( nLeft+i, nTop+i ), aRectSize ) );
+ pDev->DrawRect( Rectangle( Point( nLeft+i, nBottom-i ), aRectSize ) );
+ i++;
+ }
+ }
+ break;
+
+ case SYMBOL_ROLLUP:
+ case SYMBOL_ROLLDOWN:
+ {
+ Rectangle aRect( nCenterX-n2, nCenterY-n2,
+ nCenterX+n2, nCenterY-n2+1 );
+ pDev->DrawRect( aRect );
+ if ( eType == SYMBOL_ROLLDOWN )
+ {
+ Rectangle aTempRect = aRect;
+ aTempRect.Bottom() = nCenterY+n2;
+ aTempRect.Right() = aRect.Left();
+ pDev->DrawRect( aTempRect );
+ aTempRect.Left() = aRect.Right();
+ aTempRect.Right() = aRect.Right();
+ pDev->DrawRect( aTempRect );
+ aTempRect.Top() = aTempRect.Bottom();
+ aTempRect.Left() = aRect.Left();
+ pDev->DrawRect( aTempRect );
+ }
+ }
+ break;
+ case SYMBOL_CHECKMARK:
+ {
+ Point aPos1( rRect.Left(), rRect.Bottom() - rRect.GetHeight() / 3 );
+ Point aPos2( rRect.Left() + rRect.GetWidth()/3, rRect.Bottom() );
+ Point aPos3( rRect.TopRight() );
+ Size aRectSize( 1, 2 );
+ long nStepsY = aPos2.Y()-aPos1.Y();
+ long nX = aPos1.X();
+ long nY = aPos1.Y();
+ for ( long n = 0; n <= nStepsY; n++ )
+ {
+ pDev->DrawRect( Rectangle( Point( nX, nY++ ), aRectSize ) );
+ nX++;
+ }
+ nStepsY = aPos2.Y()-aPos3.Y();
+ nX = aPos2.X();
+ nY = aPos2.Y();
+ for ( n = 0; n <= nStepsY; n++ )
+ {
+ pDev->DrawRect( Rectangle( Point( nX, nY-- ), aRectSize ) );
+ nX++;
+ if ( nX > rRect.Right() )
+ break;
+ }
+ }
+ break;
+
+ case SYMBOL_SPIN_UPDOWN:
+ {
+ nTop = nCenterY-n2-1;
+ nBottom = nTop+n2;
+ pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nTop++;
+ nTemp = nCenterX-i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ nTemp = nCenterX+i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ i++;
+ }
+ nTop = nCenterY+1;
+ nBottom = nTop+n2;
+ pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
+ i = 1;
+ while ( i <= n2 )
+ {
+ nBottom--;
+ nTemp = nCenterX-i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ nTemp = nCenterX+i;
+ pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
+ i++;
+ }
+ }
+ break;
+
+
+ case SYMBOL_FLOAT:
+ {
+ Rectangle aRect( nCenterX-n2, nCenterY-n2+3,
+ nCenterX+n2-2, nCenterY-n2+4 );
+ pDev->DrawRect( aRect );
+ Rectangle aTempRect = aRect;
+ aTempRect.Bottom() = nCenterY+n2;
+ aTempRect.Right() = aRect.Left();
+ pDev->DrawRect( aTempRect );
+ aTempRect.Left() = aRect.Right();
+ aTempRect.Right() = aRect.Right();
+ pDev->DrawRect( aTempRect );
+ aTempRect.Top() = aTempRect.Bottom();
+ aTempRect.Left() = aRect.Left();
+ pDev->DrawRect( aTempRect );
+ aRect = Rectangle( nCenterX-n2+2, nCenterY-n2,
+ nCenterX+n2, nCenterY-n2+1 );
+ pDev->DrawRect( aRect );
+ aTempRect = aRect;
+ aTempRect.Bottom() = nCenterY+n2-3;
+ aTempRect.Right() = aRect.Left();
+ pDev->DrawRect( aTempRect );
+ aTempRect.Left() = aRect.Right();
+ aTempRect.Right() = aRect.Right();
+ pDev->DrawRect( aTempRect );
+ aTempRect.Top() = aTempRect.Bottom();
+ aTempRect.Left() = aRect.Left();
+ pDev->DrawRect( aTempRect );
+ }
+ break;
+ case SYMBOL_DOCK:
+ {
+ Rectangle aRect( nCenterX-n2, nCenterY-n2,
+ nCenterX+n2, nCenterY-n2 );
+ pDev->DrawRect( aRect );
+ Rectangle aTempRect = aRect;
+ aTempRect.Bottom() = nCenterY+n2;
+ aTempRect.Right() = aRect.Left();
+ pDev->DrawRect( aTempRect );
+ aTempRect.Left() = aRect.Right();
+ aTempRect.Right() = aRect.Right();
+ pDev->DrawRect( aTempRect );
+ aTempRect.Top() = aTempRect.Bottom();
+ aTempRect.Left() = aRect.Left();
+ pDev->DrawRect( aTempRect );
+ }
+ break;
+ case SYMBOL_HIDE:
+ {
+ long nExtra = n / 8;
+ Rectangle aRect( nCenterX-n2+nExtra, nCenterY+n2-1,
+ nCenterX+n2-nExtra, nCenterY+n2 );
+ pDev->DrawRect( aRect );
+ }
+ break;
+
+ case SYMBOL_OS2CLOSE:
+ {
+ Rectangle aRect( nCenterX-n2, nCenterY-n2,
+ nCenterX+n2, nCenterY+n2 );
+ ImplDrawOS2Symbol( pDev, aRect, 0, TRUE );
+ }
+ break;
+
+ case SYMBOL_OS2FLOAT:
+ {
+ Rectangle aRect( nCenterX-n2+4, nCenterY-n2+4,
+ nCenterX+n2-4, nCenterY+n2-3 );
+ ImplDrawOS2Symbol( pDev, aRect, 0, FALSE );
+ DecorationView aDecoView( pDev );
+ Rectangle aRect2( nCenterX-n2, nCenterY-n2,
+ nCenterX-n2+2, nCenterY+n2 );
+ aDecoView.DrawFrame( aRect2,
+ pDev->GetSettings().GetStyleSettings().GetLightColor(),
+ pDev->GetSettings().GetStyleSettings().GetShadowColor() );
+ Rectangle aRect3( nCenterX+n2-2, nCenterY-n2,
+ nCenterX+n2, nCenterY+n2 );
+ aDecoView.DrawFrame( aRect3,
+ pDev->GetSettings().GetStyleSettings().GetLightColor(),
+ pDev->GetSettings().GetStyleSettings().GetShadowColor() );
+ }
+ break;
+
+ case SYMBOL_OS2HIDE:
+ {
+ Rectangle aRect( nCenterX-n2+3, nCenterY-n2+3,
+ nCenterX+n2-3, nCenterY+n2-3 );
+ ImplDrawOS2Symbol( pDev, aRect, 0, FALSE );
+ }
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DecorationView::DrawSymbol( const Rectangle& rRect, SymbolType eType,
+ const Color& rColor, USHORT nStyle )
+{
+ const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
+ Rectangle aRect = mpOutDev->LogicToPixel( rRect );
+ Color aOldLineColor = mpOutDev->GetLineColor();
+ Color aOldFillColor = mpOutDev->GetFillColor();
+ BOOL bOldMapMode = mpOutDev->IsMapModeEnabled();
+ mpOutDev->SetLineColor();
+ mpOutDev->SetFillColor( rColor );
+ mpOutDev->EnableMapMode( FALSE );
+
+ if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
+ (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
+ nStyle |= BUTTON_DRAW_MONO;
+
+ if ( nStyle & SYMBOL_DRAW_MONO )
+ {
+ if ( nStyle & SYMBOL_DRAW_DISABLE )
+ mpOutDev->SetFillColor( Color( COL_GRAY ) );
+ else
+ mpOutDev->SetFillColor( Color( COL_BLACK ) );
+ }
+ else
+ {
+ if ( nStyle & SYMBOL_DRAW_DISABLE )
+ {
+ // Als Embosed ausgeben
+ mpOutDev->SetFillColor( rStyleSettings.GetLightColor() );
+ Rectangle aTempRect = aRect;
+ aTempRect.Move( 1, 1 );
+ ImplDrawSymbol( mpOutDev, aTempRect, eType );
+ mpOutDev->SetFillColor( rStyleSettings.GetShadowColor() );
+ }
+ else
+ mpOutDev->SetFillColor( rColor );
+ }
+
+ ImplDrawSymbol( mpOutDev, aRect, eType );
+
+ mpOutDev->SetLineColor( aOldLineColor );
+ mpOutDev->SetFillColor( aOldFillColor );
+ mpOutDev->EnableMapMode( bOldMapMode );
+}
+
+// =======================================================================
+
+void DecorationView::DrawFrame( const Rectangle& rRect,
+ const Color& rLeftTopColor,
+ const Color& rRightBottomColor )
+{
+ Rectangle aRect = mpOutDev->LogicToPixel( rRect );
+ Color aOldLineColor = mpOutDev->GetLineColor();
+ Color aOldFillColor = mpOutDev->GetFillColor();
+ BOOL bOldMapMode = mpOutDev->IsMapModeEnabled();
+ mpOutDev->EnableMapMode( FALSE );
+ mpOutDev->SetLineColor();
+ mpOutDev->ImplDraw2ColorFrame( aRect, rLeftTopColor, rRightBottomColor );
+ mpOutDev->SetLineColor( aOldLineColor );
+ mpOutDev->SetFillColor( aOldFillColor );
+ mpOutDev->EnableMapMode( bOldMapMode );
+}
+
+// =======================================================================
+
+void DecorationView::DrawHighlightFrame( const Rectangle& rRect,
+ USHORT nStyle )
+{
+ const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
+ Color aLightColor = rStyleSettings.GetLightColor();
+ Color aShadowColor = rStyleSettings.GetShadowColor();
+
+ if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
+ (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
+ {
+ aLightColor = Color( COL_BLACK );
+ aShadowColor = Color( COL_BLACK );
+ }
+ else if ( nStyle & FRAME_HIGHLIGHT_TESTBACKGROUND )
+ {
+ Wallpaper aBackground = mpOutDev->GetBackground();
+ if ( aBackground.IsBitmap() || aBackground.IsGradient() )
+ {
+ aLightColor = rStyleSettings.GetFaceColor();
+ aShadowColor = Color( COL_BLACK );
+ }
+ else
+ {
+ Color aBackColor = aBackground.GetColor();
+ if ( (aLightColor.GetColorError( aBackColor ) < 32) ||
+ (aShadowColor.GetColorError( aBackColor ) < 32) )
+ {
+ aLightColor = Color( COL_WHITE );
+ aShadowColor = Color( COL_BLACK );
+
+ if ( aLightColor.GetColorError( aBackColor ) < 32 )
+ aLightColor.DecreaseLuminance( 64 );
+ if ( aShadowColor.GetColorError( aBackColor ) < 32 )
+ aShadowColor.IncreaseLuminance( 64 );
+ }
+ }
+ }
+
+ if ( (nStyle & FRAME_HIGHLIGHT_STYLE) == FRAME_HIGHLIGHT_IN )
+ {
+ Color aTempColor = aLightColor;
+ aLightColor = aShadowColor;
+ aShadowColor = aTempColor;
+ }
+
+ DrawFrame( rRect, aLightColor, aShadowColor );
+}
+
+// =======================================================================
+
+static void ImplDrawDPILineRect( OutputDevice* pDev, Rectangle& rRect,
+ const Color* pColor )
+{
+ long nLineWidth = pDev->ImplGetDPIX()/300;
+ long nLineHeight = pDev->ImplGetDPIY()/300;
+ if ( !nLineWidth )
+ nLineWidth = 1;
+ if ( !nLineHeight )
+ nLineHeight = 1;
+
+ if ( pColor )
+ {
+ if ( (nLineWidth == 1) && (nLineHeight == 1) )
+ {
+ pDev->SetLineColor( *pColor );
+ pDev->SetFillColor();
+ pDev->DrawRect( rRect );
+ }
+ else
+ {
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ pDev->SetLineColor();
+ pDev->SetFillColor( *pColor );
+ pDev->DrawRect( Rectangle( rRect.TopLeft(), Size( nWidth, nLineHeight ) ) );
+ pDev->DrawRect( Rectangle( rRect.TopLeft(), Size( nLineWidth, nHeight ) ) );
+ pDev->DrawRect( Rectangle( Point( rRect.Left(), rRect.Bottom()-nLineHeight ),
+ Size( nWidth, nLineHeight ) ) );
+ pDev->DrawRect( Rectangle( Point( rRect.Right()-nLineWidth, rRect.Top() ),
+ Size( nLineWidth, nHeight ) ) );
+ }
+ }
+
+ rRect.Left() += nLineWidth;
+ rRect.Top() += nLineHeight;
+ rRect.Right() -= nLineWidth;
+ rRect.Bottom() -= nLineHeight;
+}
+
+// =======================================================================
+
+static void ImplDrawFrame( OutputDevice* pDev, Rectangle& rRect,
+ const StyleSettings& rStyleSettings, USHORT nStyle )
+{
+ if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
+ (pDev->GetOutDevType() == OUTDEV_PRINTER) )
+ nStyle |= FRAME_DRAW_MONO;
+
+ if ( nStyle & FRAME_DRAW_NODRAW )
+ {
+ if ( nStyle & FRAME_DRAW_MONO )
+ ImplDrawDPILineRect( pDev, rRect, NULL );
+ else
+ {
+ USHORT nFrameStyle = nStyle & FRAME_DRAW_STYLE;
+
+ if ( nFrameStyle == FRAME_DRAW_GROUP )
+ {
+ rRect.Left() += 2;
+ rRect.Top() += 2;
+ rRect.Right() -= 2;
+ rRect.Bottom() -= 2;
+ }
+ else if ( (nFrameStyle == FRAME_DRAW_IN) ||
+ (nFrameStyle == FRAME_DRAW_OUT) )
+ {
+ rRect.Left()++;
+ rRect.Top()++;
+ rRect.Right()--;
+ rRect.Bottom()--;
+ }
+ else // FRAME_DRAW_DOUBLEIN || FRAME_DRAW_DOUBLEOUT
+ {
+ rRect.Left() += 2;
+ rRect.Top() += 2;
+ rRect.Right() -= 2;
+ rRect.Bottom() -= 2;
+ }
+ }
+ }
+ else
+ {
+ if ( nStyle & FRAME_DRAW_MONO )
+ {
+ Color aColor( COL_BLACK );
+ ImplDrawDPILineRect( pDev, rRect, &aColor );
+ }
+ else
+ {
+ USHORT nFrameStyle = nStyle & FRAME_DRAW_STYLE;
+ if ( nFrameStyle == FRAME_DRAW_GROUP )
+ {
+ pDev->SetFillColor();
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ rRect.Top()++;
+ rRect.Left()++;
+ pDev->DrawRect( rRect );
+ rRect.Top()--;
+ rRect.Left()--;
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ rRect.Right()--;
+ rRect.Bottom()--;
+ pDev->DrawRect( rRect );
+ rRect.Right()++;
+ rRect.Bottom()++;
+ }
+ else
+ {
+ pDev->SetLineColor();
+
+ if ( (nFrameStyle == FRAME_DRAW_IN) ||
+ (nFrameStyle == FRAME_DRAW_OUT) )
+ {
+ if ( nFrameStyle == FRAME_DRAW_IN )
+ {
+ pDev->ImplDraw2ColorFrame( rRect,
+ rStyleSettings.GetShadowColor(),
+ rStyleSettings.GetLightColor() );
+ }
+ else
+ {
+ pDev->ImplDraw2ColorFrame( rRect,
+ rStyleSettings.GetLightColor(),
+ rStyleSettings.GetShadowColor() );
+ }
+
+ rRect.Left()++;
+ rRect.Top()++;
+ rRect.Right()--;
+ rRect.Bottom()--;
+ }
+ else // FRAME_DRAW_DOUBLEIN || FRAME_DRAW_DOUBLEOUT
+ {
+ if ( nFrameStyle == FRAME_DRAW_DOUBLEIN )
+ {
+ pDev->ImplDraw2ColorFrame( rRect,
+ rStyleSettings.GetShadowColor(),
+ rStyleSettings.GetLightColor() );
+ }
+ else
+ {
+ pDev->ImplDraw2ColorFrame( rRect,
+ rStyleSettings.GetLightBorderColor(),
+ rStyleSettings.GetDarkShadowColor() );
+ }
+
+ rRect.Left()++;
+ rRect.Top()++;
+ rRect.Right()--;
+ rRect.Bottom()--;
+
+ if ( nFrameStyle == FRAME_DRAW_DOUBLEIN )
+ {
+ pDev->ImplDraw2ColorFrame( rRect,
+ rStyleSettings.GetDarkShadowColor(),
+ rStyleSettings.GetLightBorderColor() );
+ }
+ else
+ {
+ pDev->ImplDraw2ColorFrame( rRect,
+ rStyleSettings.GetLightColor(),
+ rStyleSettings.GetShadowColor() );
+ }
+
+ rRect.Left()++;
+ rRect.Top()++;
+ rRect.Right()--;
+ rRect.Bottom()--;
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle DecorationView::DrawFrame( const Rectangle& rRect, USHORT nStyle )
+{
+ Rectangle aRect = rRect;
+ BOOL bOldMap = mpOutDev->IsMapModeEnabled();
+ if ( bOldMap )
+ {
+ aRect = mpOutDev->LogicToPixel( aRect );
+ mpOutDev->EnableMapMode( FALSE );
+ }
+
+ if ( !rRect.IsEmpty() )
+ {
+ if ( nStyle & FRAME_DRAW_NODRAW )
+ ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle );
+ else
+ {
+ Color maOldLineColor = mpOutDev->GetLineColor();
+ Color maOldFillColor = mpOutDev->GetFillColor();
+ ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle );
+ mpOutDev->SetLineColor( maOldLineColor );
+ mpOutDev->SetFillColor( maOldFillColor );
+ }
+ }
+
+ if ( bOldMap )
+ {
+ mpOutDev->EnableMapMode( bOldMap );
+ aRect = mpOutDev->PixelToLogic( aRect );
+ }
+
+ return aRect;
+}
+
+// =======================================================================
+
+static void ImplDrawButton( OutputDevice* pDev, Rectangle& rRect,
+ const StyleSettings& rStyleSettings, USHORT nStyle )
+{
+ Rectangle aFillRect = rRect;
+
+ if ( nStyle & BUTTON_DRAW_MONO )
+ {
+ if ( !(nStyle & BUTTON_DRAW_NODRAW) )
+ {
+ Color aBlackColor( COL_BLACK );
+
+ if ( nStyle & BUTTON_DRAW_DEFAULT )
+ ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );
+
+ ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );
+
+ Size aBrdSize( 1, 1 );
+ if ( pDev->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ MapMode aResMapMode( MAP_100TH_MM );
+ aBrdSize = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
+ if ( !aBrdSize.Width() )
+ aBrdSize.Width() = 1;
+ if ( !aBrdSize.Height() )
+ aBrdSize.Height() = 1;
+ }
+ pDev->SetLineColor();
+ pDev->SetFillColor( aBlackColor );
+ Rectangle aRect1;
+ Rectangle aRect2;
+ aRect1.Left() = aFillRect.Left();
+ aRect1.Right() = aFillRect.Right(),
+ aRect2.Top() = aFillRect.Top();
+ aRect2.Bottom() = aFillRect.Bottom();
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ {
+ aRect1.Top() = aFillRect.Top();
+ aRect1.Bottom() = aBrdSize.Height()-1;
+ aRect2.Left() = aFillRect.Left();
+ aRect2.Right() = aFillRect.Left()+aBrdSize.Width()-1;
+ aFillRect.Left() += aBrdSize.Width();
+ aFillRect.Top() += aBrdSize.Height();
+ }
+ else
+ {
+ aRect1.Top() = aFillRect.Bottom()-aBrdSize.Height()+1;
+ aRect1.Bottom() = aFillRect.Bottom();
+ aRect2.Left() = aFillRect.Right()-aBrdSize.Width()+1;
+ aRect2.Right() = aFillRect.Right(),
+ aFillRect.Right() -= aBrdSize.Width();
+ aFillRect.Bottom() -= aBrdSize.Height();
+ }
+ pDev->DrawRect( aRect1 );
+ pDev->DrawRect( aRect2 );
+ }
+ }
+ else
+ {
+ if ( !(nStyle & BUTTON_DRAW_NODRAW) )
+ {
+ if ( nStyle & BUTTON_DRAW_DEFAULT )
+ {
+ Color aDefBtnColor = rStyleSettings.GetDarkShadowColor();
+ ImplDrawDPILineRect( pDev, aFillRect, &aDefBtnColor );
+ }
+ }
+
+ if ( !(nStyle & BUTTON_DRAW_NODRAW) )
+ {
+ pDev->SetLineColor();
+ if ( nStyle & BUTTON_DRAW_NOLEFTLIGHTBORDER )
+ {
+ pDev->SetFillColor( rStyleSettings.GetLightBorderColor() );
+ pDev->DrawRect( Rectangle( aFillRect.Left(), aFillRect.Top(),
+ aFillRect.Left(), aFillRect.Bottom() ) );
+ aFillRect.Left()++;
+ }
+ if ( (nStyle & BUTTON_DRAW_NOTOPLIGHTBORDER) &&
+ !(nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED)) )
+ {
+ pDev->SetFillColor( rStyleSettings.GetLightBorderColor() );
+ pDev->DrawRect( Rectangle( aFillRect.Left(), aFillRect.Top(),
+ aFillRect.Right(), aFillRect.Top() ) );
+ aFillRect.Top()++;
+ }
+ if ( ((nStyle & BUTTON_DRAW_NOBOTTOMSHADOWBORDER | BUTTON_DRAW_FLAT) == (BUTTON_DRAW_NOBOTTOMSHADOWBORDER | BUTTON_DRAW_FLAT)) &&
+ !(nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED | BUTTON_DRAW_HIGHLIGHT)) )
+ {
+ pDev->SetFillColor( rStyleSettings.GetDarkShadowColor() );
+ pDev->DrawRect( Rectangle( aFillRect.Left(), aFillRect.Bottom(),
+ aFillRect.Right(), aFillRect.Bottom() ) );
+ aFillRect.Bottom()--;
+ }
+
+ Color aColor1;
+ Color aColor2;
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ {
+ aColor1 = rStyleSettings.GetDarkShadowColor();
+ aColor2 = rStyleSettings.GetLightColor();
+ }
+ else
+ {
+ if ( nStyle & BUTTON_DRAW_NOLIGHTBORDER )
+ aColor1 = rStyleSettings.GetLightBorderColor();
+ else
+ aColor1 = rStyleSettings.GetLightColor();
+ if ( (nStyle & BUTTON_DRAW_FLATTEST) == BUTTON_DRAW_FLAT )
+ aColor2 = rStyleSettings.GetShadowColor();
+ else
+ aColor2 = rStyleSettings.GetDarkShadowColor();
+ }
+ pDev->ImplDraw2ColorFrame( aFillRect, aColor1, aColor2 );
+ aFillRect.Left()++;
+ aFillRect.Top()++;
+ aFillRect.Right()--;
+ aFillRect.Bottom()--;
+
+ if ( !((nStyle & BUTTON_DRAW_FLATTEST) == BUTTON_DRAW_FLAT) )
+ {
+ if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
+ {
+ aColor1 = rStyleSettings.GetShadowColor();
+ aColor2 = rStyleSettings.GetLightBorderColor();
+ }
+ else
+ {
+ if ( nStyle & BUTTON_DRAW_NOLIGHTBORDER )
+ aColor1 = rStyleSettings.GetLightColor();
+ else
+ aColor1 = rStyleSettings.GetLightBorderColor();
+ aColor2 = rStyleSettings.GetShadowColor();
+ }
+ pDev->ImplDraw2ColorFrame( aFillRect, aColor1, aColor2 );
+ aFillRect.Left()++;
+ aFillRect.Top()++;
+ aFillRect.Right()--;
+ aFillRect.Bottom()--;
+ }
+ }
+ }
+
+ if ( !(nStyle & (BUTTON_DRAW_NOFILL | BUTTON_DRAW_NODRAW)) )
+ {
+ pDev->SetLineColor();
+ if ( nStyle & BUTTON_DRAW_MONO )
+ {
+ // Hack: Auf Druckern wollen wir im MonoChrom-Modus trotzdem
+ // erstmal graue Buttons haben
+ if ( pDev->GetOutDevType() == OUTDEV_PRINTER )
+ pDev->SetFillColor( Color( COL_LIGHTGRAY ) );
+ else
+ pDev->SetFillColor( Color( COL_WHITE ) );
+ }
+ else
+ {
+ if ( nStyle & (BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW) )
+ pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
+ else
+ pDev->SetFillColor( rStyleSettings.GetFaceColor() );
+ }
+ pDev->DrawRect( aFillRect );
+ }
+
+ // Ein Border freilassen, der jedoch bei Default-Darstellung
+ // mitbenutzt wird
+ rRect.Left()++;
+ rRect.Top()++;
+ rRect.Right()--;
+ rRect.Bottom()--;
+
+ if ( nStyle & BUTTON_DRAW_NOLIGHTBORDER )
+ {
+ rRect.Left()++;
+ rRect.Top()++;
+ }
+ else if ( nStyle & BUTTON_DRAW_NOLEFTLIGHTBORDER )
+ rRect.Left()++;
+
+ if ( nStyle & BUTTON_DRAW_PRESSED )
+ {
+ if ( (rRect.GetHeight() > 10) && (rRect.GetWidth() > 10) )
+ {
+ rRect.Left() += 4;
+ rRect.Top() += 4;
+ rRect.Right() -= 1;
+ rRect.Bottom() -= 1;
+ }
+ else
+ {
+ rRect.Left() += 3;
+ rRect.Top() += 3;
+ rRect.Right() -= 2;
+ rRect.Bottom() -= 2;
+ }
+ }
+ else if ( nStyle & BUTTON_DRAW_CHECKED )
+ {
+ rRect.Left() += 3;
+ rRect.Top() += 3;
+ rRect.Right() -= 2;
+ rRect.Bottom() -= 2;
+ }
+ else
+ {
+ rRect.Left() += 2;
+ rRect.Top() += 2;
+ rRect.Right() -= 3;
+ rRect.Bottom() -= 3;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle DecorationView::DrawButton( const Rectangle& rRect, USHORT nStyle )
+{
+ Rectangle aRect = rRect;
+ BOOL bOldMap = mpOutDev->IsMapModeEnabled();
+ if ( bOldMap )
+ {
+ aRect = mpOutDev->LogicToPixel( aRect );
+ mpOutDev->EnableMapMode( FALSE );
+ }
+
+ if ( !rRect.IsEmpty() )
+ {
+ const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
+
+ if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
+ (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
+ nStyle |= BUTTON_DRAW_MONO;
+
+ if ( nStyle & BUTTON_DRAW_NODRAW )
+ ImplDrawButton( mpOutDev, aRect, rStyleSettings, nStyle );
+ else
+ {
+ Color maOldLineColor = mpOutDev->GetLineColor();
+ Color maOldFillColor = mpOutDev->GetFillColor();
+ ImplDrawButton( mpOutDev, aRect, rStyleSettings, nStyle );
+ mpOutDev->SetLineColor( maOldLineColor );
+ mpOutDev->SetFillColor( maOldFillColor );
+ }
+ }
+
+ if ( bOldMap )
+ {
+ mpOutDev->EnableMapMode( bOldMap );
+ aRect = mpOutDev->PixelToLogic( aRect );
+ }
+
+ return aRect;
+}
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
new file mode 100644
index 000000000000..9a76a9a38923
--- /dev/null
+++ b/vcl/source/window/dialog.cxx
@@ -0,0 +1,847 @@
+/*************************************************************************
+ *
+ * $RCSfile: dialog.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_DIALOG_CXX
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_BUTTON_HXX
+#include <button.hxx>
+#endif
+#ifndef _SV_MNEMONIC_HXX
+#include <mnemonic.hxx>
+#endif
+#ifndef _SV_ACCESS_HXX
+#include <access.hxx>
+#endif
+#ifndef _SV_DIALOG_HXX
+#include <dialog.hxx>
+#endif
+
+#ifdef DBG_UTIL
+#ifndef _SV_MSGBOX_HXX
+#include <msgbox.hxx>
+#endif
+#endif
+
+#include <unowrap.hxx>
+
+#pragma hdrstop
+
+// =======================================================================
+
+#ifdef DBG_UTIL
+
+static ByteString ImplGetDialogText( Dialog* pDialog )
+{
+ ByteString aErrorStr( pDialog->GetText(), RTL_TEXTENCODING_UTF8 );
+ if ( (pDialog->GetType() == WINDOW_MESSBOX) ||
+ (pDialog->GetType() == WINDOW_INFOBOX) ||
+ (pDialog->GetType() == WINDOW_WARNINGBOX) ||
+ (pDialog->GetType() == WINDOW_ERRORBOX) ||
+ (pDialog->GetType() == WINDOW_QUERYBOX) )
+ {
+ aErrorStr += ", ";
+ aErrorStr += ByteString( ((MessBox*)pDialog)->GetMessText(), RTL_TEXTENCODING_UTF8 );
+ }
+ return aErrorStr;
+}
+
+#endif
+
+// =======================================================================
+
+static BOOL ImplIsMnemonicCtrl( Window* pWindow )
+{
+ if ( (pWindow->GetType() == WINDOW_RADIOBUTTON) ||
+ (pWindow->GetType() == WINDOW_CHECKBOX) ||
+ (pWindow->GetType() == WINDOW_TRISTATEBOX) ||
+ (pWindow->GetType() == WINDOW_PUSHBUTTON) )
+ return TRUE;
+
+ if ( pWindow->GetType() == WINDOW_FIXEDTEXT )
+ {
+ if ( pWindow->GetStyle() & (WB_INFO | WB_NOLABEL) )
+ return FALSE;
+ Window* pNextWindow = pWindow->GetWindow( WINDOW_NEXT );
+ if ( !pNextWindow )
+ return FALSE;
+ pNextWindow = pNextWindow->GetWindow( WINDOW_CLIENT );
+ if ( !(pNextWindow->GetStyle() & WB_TABSTOP) ||
+ (pNextWindow->GetType() == WINDOW_FIXEDTEXT) ||
+ (pNextWindow->GetType() == WINDOW_GROUPBOX) ||
+ (pNextWindow->GetType() == WINDOW_RADIOBUTTON) ||
+ (pNextWindow->GetType() == WINDOW_CHECKBOX) ||
+ (pNextWindow->GetType() == WINDOW_TRISTATEBOX) ||
+ (pNextWindow->GetType() == WINDOW_PUSHBUTTON) )
+ return FALSE;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplWindowAutoMnemonic( Window* pWindow )
+{
+ ImplMnemonicGenerator aMnemonicGenerator;
+ Window* pGetChild;
+ Window* pChild;
+
+ // Die schon vergebenen Mnemonics registieren
+ pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
+ while ( pGetChild )
+ {
+ pChild = pGetChild->ImplGetWindow();
+ aMnemonicGenerator.RegisterMnemonic( pChild->GetText() );
+ pGetChild = pGetChild->GetWindow( WINDOW_NEXT );
+ }
+
+ // Bei TabPages auch noch die Controls vom Dialog beruecksichtigen
+ if ( pWindow->GetType() == WINDOW_TABPAGE )
+ {
+ Window* pParent = pWindow->GetParent();
+ if ( pParent->GetType() == WINDOW_TABCONTROL )
+ pParent = pParent->GetParent();
+
+ if ( (pParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL )
+ {
+ pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
+ while ( pGetChild )
+ {
+ pChild = pGetChild->ImplGetWindow();
+ aMnemonicGenerator.RegisterMnemonic( pChild->GetText() );
+ pGetChild = pGetChild->GetWindow( WINDOW_NEXT );
+ }
+ }
+ }
+
+ // Die Mnemonics an die Controls vergeben, die noch keinen haben
+ pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
+ while ( pGetChild )
+ {
+ pChild = pGetChild->ImplGetWindow();
+ if ( ImplIsMnemonicCtrl( pChild ) )
+ {
+ XubString aText = pChild->GetText();
+ if ( aMnemonicGenerator.CreateMnemonic( aText ) )
+ pChild->SetText( aText );
+ }
+
+ pGetChild = pGetChild->GetWindow( WINDOW_NEXT );
+ }
+}
+
+// =======================================================================
+
+static PushButton* ImplGetDefaultButton( Dialog* pDialog )
+{
+ Window* pChild = pDialog->GetWindow( WINDOW_FIRSTCHILD );
+ while ( pChild )
+ {
+ if ( pChild->ImplIsPushButton() )
+ {
+ PushButton* pPushButton = (PushButton*)pChild;
+ if ( pPushButton->ImplIsDefButton() )
+ return pPushButton;
+ }
+
+ pChild = pChild->GetWindow( WINDOW_NEXT );
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static PushButton* ImplGetOKButton( Dialog* pDialog )
+{
+ Window* pChild = pDialog->GetWindow( WINDOW_FIRSTCHILD );
+ while ( pChild )
+ {
+ if ( pChild->GetType() == WINDOW_OKBUTTON )
+ return (PushButton*)pChild;
+
+ pChild = pChild->GetWindow( WINDOW_NEXT );
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static PushButton* ImplGetCancelButton( Dialog* pDialog )
+{
+ Window* pChild = pDialog->GetWindow( WINDOW_FIRSTCHILD );
+ while ( pChild )
+ {
+ if ( pChild->GetType() == WINDOW_CANCELBUTTON )
+ return (PushButton*)pChild;
+
+ pChild = pChild->GetWindow( WINDOW_NEXT );
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplMouseAutoPos( Dialog* pDialog )
+{
+ ULONG nMouseOptions = pDialog->GetSettings().GetMouseSettings().GetOptions();
+ if ( nMouseOptions & MOUSE_OPTION_AUTOCENTERPOS )
+ {
+ Size aSize = pDialog->GetOutputSizePixel();
+ pDialog->SetPointerPosPixel( Point( aSize.Width()/2, aSize.Height()/2 ) );
+ }
+ else if ( nMouseOptions & MOUSE_OPTION_AUTODEFBTNPOS )
+ {
+ Window* pWindow = ImplGetDefaultButton( pDialog );
+ if ( !pWindow )
+ pWindow = ImplGetOKButton( pDialog );
+ if ( !pWindow )
+ pWindow = ImplGetCancelButton( pDialog );
+ if ( !pWindow )
+ pWindow = pDialog;
+ Size aSize = pWindow->GetOutputSizePixel();
+ pWindow->SetPointerPosPixel( Point( aSize.Width()/2, aSize.Height()/2 ) );
+ }
+}
+
+// =======================================================================
+
+void Dialog::ImplInitData()
+{
+ mbDialog = TRUE;
+
+ mpDialogParent = NULL;
+ mpResult = NULL;
+ mpPrevExecuteDlg = NULL;
+ mbInExecute = FALSE;
+ mbOldSaveBack = FALSE;
+ mbInClose = FALSE;
+ mbModalMode = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Dialog::ImplInit( Window* pParent, WinBits nStyle )
+{
+ USHORT nSysWinMode = Application::GetSystemWindowMode();
+
+ if ( !(nStyle & WB_NODIALOGCONTROL) )
+ nStyle |= WB_DIALOGCONTROL;
+ nStyle |= WB_ROLLABLE;
+
+ if ( !pParent )
+ {
+ pParent = Application::GetDefDialogParent();
+ if ( !pParent && !(nStyle & WB_SYSTEMWINDOW) )
+ pParent = Application::GetAppWindow();
+
+ // If Parent is disabled, then we search for a modal dialog
+ // in this frame
+ if ( pParent && !pParent->IsInputEnabled() )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ Dialog* pExeDlg = pSVData->maWinData.mpLastExecuteDlg;
+ while ( pExeDlg )
+ {
+ // Nur wenn er sichtbar und enabled ist
+ if ( pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild( pExeDlg, TRUE ) &&
+ pExeDlg->IsReallyVisible() &&
+ pExeDlg->IsEnabled() && pExeDlg->IsInputEnabled() )
+ {
+ pParent = pExeDlg;
+ break;
+ }
+
+ pExeDlg = pExeDlg->mpPrevExecuteDlg;
+ }
+ }
+ }
+
+ if ( pParent && !(nSysWinMode & SYSTEMWINDOW_MODE_NOAUTOMODE) )
+ {
+ if ( !pParent->mpFrameWindow->IsVisible() )
+ pParent = NULL;
+ else
+ {
+ if ( pParent->mpFrameWindow->IsDialog() )
+ {
+ Size aOutSize = pParent->mpFrameWindow->GetOutputSizePixel();
+ if ( (aOutSize.Width() < 210) ||(aOutSize.Height() < 160) )
+ nStyle |= WB_SYSTEMWINDOW;
+ }
+ }
+ }
+
+ if ( !pParent || (nStyle & WB_SYSTEMWINDOW) ||
+ (pParent->mpFrameData->mbNeedSysWindow && !(nSysWinMode & SYSTEMWINDOW_MODE_NOAUTOMODE)) ||
+ (nSysWinMode & SYSTEMWINDOW_MODE_DIALOG) )
+ {
+ // Fenster mit einem schmallen Border anlegen?
+ if ( (nStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE)) == WB_BORDER )
+ {
+ ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle, BORDERWINDOW_STYLE_FRAME );
+ SystemWindow::ImplInit( pBorderWin, nStyle & ~WB_BORDER, NULL );
+ pBorderWin->mpClientWindow = this;
+ pBorderWin->GetBorder( mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder );
+ mpBorderWindow = pBorderWin;
+ mpRealParent = pParent;
+ }
+ else
+ {
+ mbFrame = TRUE;
+ mbOverlapWin = TRUE;
+ SystemWindow::ImplInit( pParent, nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_CLOSEABLE | WB_STANDALONE), NULL );
+ // Jetzt alle StyleBits setzen
+ mnStyle = nStyle;
+ }
+ }
+ else
+ {
+ ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle, BORDERWINDOW_STYLE_OVERLAP | BORDERWINDOW_STYLE_BORDER );
+ SystemWindow::ImplInit( pBorderWin, nStyle & ~WB_BORDER, NULL );
+ pBorderWin->mpClientWindow = this;
+ pBorderWin->GetBorder( mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder );
+ mpBorderWindow = pBorderWin;
+ mpRealParent = pParent;
+ }
+
+ SetActivateMode( ACTIVATE_MODE_GRABFOCUS );
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void Dialog::ImplInitSettings()
+{
+ // Wir haben graue Dialoge
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( GetSettings().GetStyleSettings().GetDialogColor() );
+}
+
+// -----------------------------------------------------------------------
+
+void Dialog::ImplCenterDialog()
+{
+ Rectangle aDeskRect = ImplGetFrameWindow()->GetDesktopRectPixel();
+ Point aDeskPos = aDeskRect.TopLeft();
+ Size aDeskSize = aDeskRect.GetSize();
+ Size aWinSize = GetSizePixel();
+ Point aWinPos( ((aDeskSize.Width() - aWinSize.Width()) / 2) + aDeskPos.X(),
+ ((aDeskSize.Height() - aWinSize.Height()) / 2) + aDeskPos.Y() );
+
+ // Pruefen, ob Dialogbox ausserhalb des Desks liegt
+ if ( (aWinPos.X() + aWinSize.Width()) > (aDeskPos.X()+aDeskSize.Width()) )
+ aWinPos.X() = aDeskPos.X()+aDeskSize.Width() - aWinSize.Width();
+ if ( (aWinPos.Y()+aWinSize.Height()) > (aDeskPos.Y()+aDeskSize.Height()) )
+ aWinPos.Y() = aDeskPos.Y()+aDeskSize.Height() - aWinSize.Height();
+ // Linke Ecke bevorzugen, da Titelbar oben ist
+ if ( aWinPos.X() < aDeskPos.X() )
+ aWinPos.X() = aDeskPos.X();
+ if ( aWinPos.Y() < aDeskPos.Y() )
+ aWinPos.Y() = aDeskPos.Y();
+
+ SetPosPixel( aWinPos );
+}
+
+// -----------------------------------------------------------------------
+
+Dialog::Dialog( WindowType nType ) :
+ SystemWindow( nType )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+Dialog::Dialog( Window* pParent, WinBits nStyle ) :
+ SystemWindow( WINDOW_DIALOG )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+Dialog::Dialog( Window* pParent, const ResId& rResId ) :
+ SystemWindow( WINDOW_DIALOG )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_DIALOG );
+ ImplInit( pParent, ImplInitRes( rResId ) );
+ ImplLoadRes( rResId );
+}
+
+// -----------------------------------------------------------------------
+
+long Dialog::Notify( NotifyEvent& rNEvt )
+{
+ // Zuerst Basisklasse rufen wegen TabSteuerung
+ long nRet = SystemWindow::Notify( rNEvt );
+ if ( !nRet )
+ {
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( (nKeyCode == KEY_ESCAPE) &&
+ ((GetStyle() & WB_CLOSEABLE) || ImplGetCancelButton( this ) || ImplGetOKButton( this )) )
+ {
+ Close();
+ return TRUE;
+ }
+ }
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+void Dialog::StateChanged( StateChangedType nType )
+{
+ SystemWindow::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if ( Application::IsAutoMnemonicEnabled() )
+ ImplWindowAutoMnemonic( this );
+
+ if ( IsDefaultPos() && !mbFrame )
+ ImplCenterDialog();
+ if ( !HasChildPathFocus() || HasFocus() )
+ GrabFocusToFirstControl();
+ if ( !(GetStyle() & WB_CLOSEABLE) )
+ {
+ if ( ImplGetCancelButton( this ) || ImplGetOKButton( this ) )
+ {
+ if ( ImplGetBorderWindow() )
+ ((ImplBorderWindow*)ImplGetBorderWindow())->SetCloser();
+ else
+ {
+ // ... missing implementation, if we are a frame window,
+ // because it is currently impossible to implement.
+ SetStyle( GetStyle() | WB_CLOSEABLE );
+ }
+ }
+ }
+
+ ImplMouseAutoPos( this );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Dialog::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SystemWindow::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Dialog::Close()
+{
+ if ( mxWindowPeer.is() )
+ {
+ Application::GetUnoWrapper()->WindowEvent_Close( this );
+ if ( IsCreatedWithToolkit() )
+ return FALSE;
+ }
+
+ mbInClose = TRUE;
+
+ if ( !(GetStyle() & WB_CLOSEABLE) )
+ {
+ ImplDelData aDelData;
+ ImplAddDel( &aDelData );
+ PushButton* pButton = ImplGetCancelButton( this );
+ if ( pButton )
+ pButton->Click();
+ else
+ {
+ pButton = ImplGetOKButton( this );
+ if ( pButton )
+ pButton->Click();
+ }
+ if ( aDelData.IsDelete() )
+ return TRUE;
+ ImplRemoveDel( &aDelData );
+ }
+
+ if ( IsInExecute() )
+ {
+ EndDialog( FALSE );
+ mbInClose = FALSE;
+ return TRUE;
+ }
+ else
+ {
+ mbInClose = FALSE;
+ return SystemWindow::Close();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+short Dialog::Execute()
+{
+ if ( mbInExecute )
+ {
+#ifdef DBG_UTIL
+ ByteString aErrorStr( "Dialog::Execute() is called in Dialoh::Execute(): " );
+ aErrorStr += ImplGetDialogText( this );
+ DBG_ERROR( aErrorStr.GetBuffer() );
+#endif
+ return 0;
+ }
+
+ if ( Application::IsDialogCancelEnabled() )
+ {
+#ifdef DBG_UTIL
+ ByteString aErrorStr( "Dialog::Execute() is called in a none UI application: " );
+ aErrorStr += ImplGetDialogText( this );
+ DBG_ERROR( aErrorStr.GetBuffer() );
+#endif
+ return 0;
+ }
+
+#ifdef DBG_UTIL
+ Window* pParent = GetParent();
+ if ( pParent )
+ {
+ pParent = pParent->ImplGetFirstOverlapWindow();
+ DBG_ASSERT( pParent->IsReallyVisible(),
+ "Dialog::Execute() - Parent not visible" );
+ }
+#endif
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Dialoge, die sich in Execute befinden, miteinander verketten
+ mpPrevExecuteDlg = pSVData->maWinData.mpLastExecuteDlg;
+ pSVData->maWinData.mpLastExecuteDlg = this;
+
+ // Capture beenden, damit der Dialog bedient werden kann
+ if ( pSVData->maWinData.mpTrackWin )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
+ if ( pSVData->maWinData.mpCaptureWin )
+ pSVData->maWinData.mpCaptureWin->ReleaseMouse();
+ EnableInput( TRUE, TRUE );
+
+ if ( GetParent() )
+ {
+ NotifyEvent aNEvt( EVENT_EXECUTEDIALOG, this );
+ GetParent()->Notify( aNEvt );
+ }
+ long nRet;
+ mpResult = &nRet;
+ mbInExecute = TRUE;
+ SetModalInputMode( TRUE );
+ mbOldSaveBack = IsSaveBackgroundEnabled();
+ EnableSaveBackground();
+ Show();
+
+ if ( Application::GetAccessHdlCount() )
+ {
+ Application::AccessNotify( AccessNotification( ACCESS_EVENT_MODALDIALOG_START, this ) );
+ Application::AccessNotify( AccessNotification( ACCESS_EVENT_DLGCONTROLS, this ) );
+ }
+
+ // Solange Yielden, bis EndDialog aufgerufen wird, oder der Dialog
+ // zerstoert wird (sollte nicht sein und ist nur vorsichtsmassnahme)
+ ImplDelData aDelData;
+ ImplAddDel( &aDelData );
+ pSVData->maAppData.mnModalMode++;
+ while ( !aDelData.IsDelete() && mbInExecute )
+ Application::Yield();
+ pSVData->maAppData.mnModalMode--;
+ if ( !aDelData.IsDelete() )
+ ImplRemoveDel( &aDelData );
+#ifdef DBG_UTIL
+ else
+ {
+ DBG_ERROR( "Dialog::Execute() - Dialog destroyed in Execute()" );
+ }
+#endif
+
+ return (short)nRet;
+}
+
+// -----------------------------------------------------------------------
+
+void Dialog::EndDialog( long nResult )
+{
+ if ( mbInExecute )
+ {
+ SetModalInputMode( FALSE );
+
+ // Dialog aus der Kette der Dialoge die in Execute stehen entfernen
+ ImplSVData* pSVData = ImplGetSVData();
+ Dialog* pPrevDlg = NULL;
+ Dialog* pExeDlg = pSVData->maWinData.mpLastExecuteDlg;
+ while ( pExeDlg )
+ {
+ if ( pExeDlg == this )
+ {
+ if ( pPrevDlg )
+ pPrevDlg->mpPrevExecuteDlg = mpPrevExecuteDlg;
+ else
+ pSVData->maWinData.mpLastExecuteDlg = mpPrevExecuteDlg;
+ break;
+ }
+ pExeDlg = pExeDlg->mpPrevExecuteDlg;
+ }
+ mpPrevExecuteDlg = NULL;
+
+ Hide();
+ EnableSaveBackground( mbOldSaveBack );
+ if ( GetParent() )
+ {
+ NotifyEvent aNEvt( EVENT_ENDEXECUTEDIALOG, this );
+ GetParent()->Notify( aNEvt );
+ }
+ if ( Application::GetAccessHdlCount() )
+ Application::AccessNotify( AccessNotification( ACCESS_EVENT_MODALDIALOG_END, this ) );
+ if ( mpResult )
+ *mpResult = nResult;
+ mpResult = NULL;
+ mbInExecute = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Dialog::SetModalInputMode( BOOL bModal )
+{
+ if ( bModal == mbModalMode )
+ return;
+
+ ImplSVData* pSVData = ImplGetSVData();
+ mbModalMode = bModal;
+ if ( bModal )
+ {
+ pSVData->maAppData.mnModalDialog++;
+
+ // Diable the prev Modal Dialog, because our dialog must close at first,
+ // before the other dialog can be closed (because the other dialog
+ // is on stack since our dialog returns)
+ if ( mpPrevExecuteDlg && !mpPrevExecuteDlg->IsWindowOrChild( this, TRUE ) )
+ mpPrevExecuteDlg->EnableInput( FALSE, TRUE, TRUE, this );
+
+ // determine next overlap dialog parent
+ Window* pParent = GetParent();
+ if ( pParent )
+ {
+ mpDialogParent = pParent->ImplGetFirstOverlapWindow();
+ if ( mpDialogParent )
+ mpDialogParent->EnableInput( FALSE, TRUE, TRUE, this );
+ }
+ }
+ else
+ {
+ pSVData->maAppData.mnModalDialog--;
+
+ if ( mpDialogParent )
+ mpDialogParent->EnableInput( TRUE, TRUE, TRUE, this );
+
+ // Enable the prev Modal Dialog
+ if ( mpPrevExecuteDlg && !mpPrevExecuteDlg->IsWindowOrChild( this, TRUE ) )
+ mpPrevExecuteDlg->EnableInput( TRUE, TRUE, TRUE, this );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Dialog::SetModalInputMode( BOOL bModal, BOOL bSubModalDialogs )
+{
+ if ( bSubModalDialogs )
+ {
+ Window* pOverlap = ImplGetFirstOverlapWindow();
+ pOverlap = pOverlap->mpFirstOverlap;
+ while ( pOverlap )
+ {
+ if ( pOverlap->IsDialog() )
+ ((Dialog*)pOverlap)->SetModalInputMode( bModal, TRUE );
+ pOverlap = pOverlap->mpNext;
+ }
+ }
+
+ SetModalInputMode( bModal );
+}
+
+// -----------------------------------------------------------------------
+
+void Dialog::GrabFocusToFirstControl()
+{
+ Window* pFocusControl;
+
+ // Wenn Dialog den Focus hat, versuchen wr trotzdem
+ // ein Focus-Control zu finden
+ if ( HasFocus() )
+ pFocusControl = NULL;
+ else
+ {
+ // Wenn schon ein Child-Fenster mal den Focus hatte,
+ // dann dieses bevorzugen
+ pFocusControl = ImplGetFirstOverlapWindow()->mpLastFocusWindow;
+ // Control aus der Dialog-Steuerung suchen
+ if ( pFocusControl )
+ pFocusControl = ImplFindDlgCtrlWindow( pFocusControl );
+ }
+ // Kein Control hatte vorher den Focus, oder das Control
+ // befindet sich nicht in der Tab-Steuerung, dann das erste
+ // Control in der TabSteuerung den Focus geben
+ if ( !pFocusControl ||
+ !(pFocusControl->GetStyle() & WB_TABSTOP) ||
+ !pFocusControl->IsVisible() ||
+ !pFocusControl->IsEnabled() || !pFocusControl->IsInputEnabled() )
+ {
+ USHORT n = 0;
+ pFocusControl = ImplGetDlgWindow( n, DLGWINDOW_FIRST );
+ }
+ if ( pFocusControl )
+ pFocusControl->ImplControlFocus( GETFOCUS_INIT );
+}
+
+// =======================================================================
+
+ModelessDialog::ModelessDialog( Window* pParent, WinBits nStyle ) :
+ Dialog( WINDOW_MODELESSDIALOG )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+ModelessDialog::ModelessDialog( Window* pParent, const ResId& rResId ) :
+ Dialog( WINDOW_MODELESSDIALOG )
+{
+ rResId.SetRT( RSC_MODELESSDIALOG );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// =======================================================================
+
+ModalDialog::ModalDialog( Window* pParent, WinBits nStyle ) :
+ Dialog( WINDOW_MODALDIALOG )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+ModalDialog::ModalDialog( Window* pParent, const ResId& rResId ) :
+ Dialog( WINDOW_MODALDIALOG )
+{
+ rResId.SetRT( RSC_MODALDIALOG );
+ ImplInit( pParent, ImplInitRes( rResId ) );
+ ImplLoadRes( rResId );
+}
diff --git a/vcl/source/window/dlgctrl.cxx b/vcl/source/window/dlgctrl.cxx
new file mode 100644
index 000000000000..a8c45e6d7f3b
--- /dev/null
+++ b/vcl/source/window/dlgctrl.cxx
@@ -0,0 +1,968 @@
+/*************************************************************************
+ *
+ * $RCSfile: dlgctrl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_DLGCTRL_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_TABPAGE_HXX
+#include <tabpage.hxx>
+#endif
+#ifndef _SV_TABCTRL_HXX
+#include <tabctrl.hxx>
+#endif
+#ifndef _SV_BUTTON_HXX
+#include <button.hxx>
+#endif
+
+#include <unohelp.hxx>
+
+#ifndef _COM_SUN_STAR_LANG_XCHARACTERCLASSIFICATION_HPP_
+#include <com/sun/star/lang/XCharacterClassification.hpp>
+#endif
+
+using namespace ::com::sun::star;
+
+
+#pragma hdrstop
+
+// =======================================================================
+
+static Window* ImplGetSubChildWindow( Window* pParent, USHORT n, USHORT& nIndex )
+{
+ Window* pTabPage = NULL;
+ Window* pFoundWindow = NULL;
+ Window* pWindow = pParent->GetWindow( WINDOW_FIRSTCHILD );
+ Window* pNextWindow = pWindow;
+ while ( pWindow )
+ {
+ pWindow = pWindow->ImplGetWindow();
+
+ // Unsichtbare und disablte Fenster werden uebersprungen
+ if ( pTabPage || pWindow->IsVisible() )
+ {
+ // Wenn das letzte Control ein TabControl war, wird von
+ // diesem die TabPage genommen
+ if ( pTabPage )
+ {
+ pFoundWindow = ImplGetSubChildWindow( pTabPage, n, nIndex );
+ pTabPage = NULL;
+ }
+ else
+ {
+ pFoundWindow = pWindow;
+
+ // Bei einem TabControl sich die aktuelle TabPage merken,
+ // damit diese dann genommen wird
+ if ( pWindow->GetType() == WINDOW_TABCONTROL )
+ {
+ TabControl* pTabControl = ((TabControl*)pWindow);
+ // Feststellen, ob TabPage Child vom TabControl ist
+ // und auch noch existiert (deshalb durch Vergleich,
+ // indem alle ChildFenster getestet werden). Denn es
+ // kann sein, das TabPages schon in einem Dialog-Dtor
+ // zerstoert wurden, obwohl das TabControl noch
+ // existiert.
+ TabPage* pTempTabPage = pTabControl->GetTabPage( pTabControl->GetCurPageId() );
+ if ( pTempTabPage )
+ {
+ Window* pTempWindow = pTabControl->GetWindow( WINDOW_FIRSTCHILD );
+ while ( pTempWindow )
+ {
+ if ( pTempWindow->ImplGetWindow() == pTempTabPage )
+ {
+ pTabPage = pTempTabPage;
+ break;
+ }
+ pTempWindow = pTempWindow->GetWindow( WINDOW_NEXT );
+ }
+ }
+ }
+ else if ( pWindow->GetStyle() & WB_DIALOGCONTROL )
+ pFoundWindow = ImplGetSubChildWindow( pWindow, n, nIndex );
+ }
+
+ if ( n == nIndex )
+ return pFoundWindow;
+ nIndex++;
+ }
+
+ if ( pTabPage )
+ pWindow = pTabPage;
+ else
+ {
+ pWindow = pNextWindow->GetWindow( WINDOW_NEXT );
+ pNextWindow = pWindow;
+ }
+ }
+
+ nIndex--;
+ return pFoundWindow;
+}
+
+// -----------------------------------------------------------------------
+
+static Window* ImplGetChildWindow( Window* pParent, USHORT n, USHORT& nIndex, BOOL bTestEnable )
+{
+ nIndex = 0;
+ Window* pWindow = ImplGetSubChildWindow( pParent, n, nIndex );
+ if ( bTestEnable )
+ {
+ USHORT n2 = nIndex;
+ while ( pWindow && (!pWindow->IsEnabled() || !pWindow->IsInputEnabled()) )
+ {
+ n2 = nIndex+1;
+ nIndex = 0;
+ pWindow = ImplGetSubChildWindow( pParent, n2, nIndex );
+ if ( nIndex < n2 )
+ break;
+ }
+
+ if ( (nIndex < n2) && n )
+ {
+ do
+ {
+ n--;
+ nIndex = 0;
+ pWindow = ImplGetSubChildWindow( pParent, n, nIndex );
+ }
+ while ( pWindow && n && (!pWindow->IsEnabled() || !pWindow->IsInputEnabled()) );
+ }
+ }
+ return pWindow;
+}
+
+// -----------------------------------------------------------------------
+
+static Window* ImplGetNextWindow( Window* pParent, USHORT n, USHORT& nIndex, BOOL bTestEnable )
+{
+ Window* pWindow = ImplGetChildWindow( pParent, n+1, nIndex, bTestEnable );
+ if ( n == nIndex )
+ {
+ n = 0;
+ pWindow = ImplGetChildWindow( pParent, n, nIndex, bTestEnable );
+ }
+ return pWindow;
+}
+
+// -----------------------------------------------------------------------
+
+Window* Window::ImplGetDlgWindow( USHORT nIndex, USHORT nType,
+ USHORT nFormStart, USHORT nFormEnd,
+ USHORT* pIndex )
+{
+ DBG_ASSERT( (nIndex >= nFormStart) && (nIndex <= nFormEnd),
+ "Window::ImplGetDlgWindow() - nIndex not in Form" );
+
+ Window* pWindow = NULL;
+ USHORT i;
+ USHORT nTemp;
+ USHORT nStartIndex;
+
+ if ( nType == DLGWINDOW_PREV )
+ {
+ i = nIndex;
+ do
+ {
+ if ( i > nFormStart )
+ i--;
+ else
+ i = nFormEnd;
+ pWindow = ImplGetChildWindow( this, i, nTemp, TRUE );
+ if ( !pWindow )
+ break;
+ if ( (i == nTemp) && (pWindow->GetStyle() & WB_TABSTOP) )
+ break;
+ }
+ while ( i != nIndex );
+ }
+ else
+ {
+ i = nIndex;
+ pWindow = ImplGetChildWindow( this, i, i, (nType == DLGWINDOW_FIRST) );
+ if ( pWindow )
+ {
+ nStartIndex = i;
+
+ if ( nType == DLGWINDOW_NEXT )
+ {
+ if ( i < nFormEnd )
+ {
+ pWindow = ImplGetNextWindow( this, i, i, TRUE );
+ if ( (i > nFormEnd) || (i < nFormStart) )
+ pWindow = ImplGetChildWindow( this, nFormStart, i, TRUE );
+ }
+ else
+ pWindow = ImplGetChildWindow( this, nFormStart, i, TRUE );
+ }
+
+ if ( i <= nFormEnd )
+ {
+ // 2ten Index mitfuehren, falls alle Controls disablte
+ USHORT nStartIndex2 = i;
+
+ do
+ {
+ if ( pWindow->GetStyle() & WB_TABSTOP )
+ break;
+ if ( (i >= nFormEnd) || (i < nFormStart) )
+ pWindow = ImplGetChildWindow( this, nFormStart, i, TRUE );
+ else
+ pWindow = ImplGetNextWindow( this, i, i, TRUE );
+ }
+ while ( (i != nStartIndex) && (i != nStartIndex2) );
+
+ if ( (i == nStartIndex2) &&
+ (!(pWindow->GetStyle() & WB_TABSTOP) || !pWindow->IsEnabled()) )
+ i = nStartIndex;
+ }
+ }
+
+ if ( nType == DLGWINDOW_FIRST )
+ {
+ if ( pWindow )
+ {
+ if ( pWindow->GetType() == WINDOW_TABCONTROL )
+ {
+ Window* pNextWindow = ImplGetDlgWindow( i, DLGWINDOW_NEXT );
+ if ( pNextWindow )
+ {
+ if ( pWindow->IsChild( pNextWindow ) )
+ pWindow = pNextWindow;
+ }
+ }
+
+ if ( !(pWindow->GetStyle() & WB_TABSTOP) )
+ pWindow = NULL;
+ }
+ }
+ }
+
+ if ( pIndex )
+ *pIndex = i;
+
+ return pWindow;
+}
+
+// -----------------------------------------------------------------------
+
+static Window* ImplFindAccelWindow( Window* pParent, USHORT& rIndex, xub_Unicode cCharCode,
+ USHORT nFormStart, USHORT nFormEnd )
+{
+ DBG_ASSERT( (rIndex >= nFormStart) && (rIndex <= nFormEnd),
+ "Window::ImplFindAccelWindow() - rIndex not in Form" );
+
+ xub_Unicode cCompareChar;
+ USHORT nStart = rIndex;
+ USHORT i = rIndex;
+ int bSearch = TRUE;
+ Window* pWindow;
+
+ // MT: Where can we keep the CharClass?!
+ static uno::Reference< lang::XCharacterClassification > xCharClass;
+ if ( !xCharClass.is() )
+ xCharClass = vcl::unohelper::CreateCharacterClassification();
+
+ const ::com::sun::star::lang::Locale& rLocale = Application::GetSettings().GetLocale();
+
+ cCharCode = xCharClass->toUpper( String(cCharCode), 0, 1, rLocale )[0];
+
+ if ( i < nFormEnd )
+ pWindow = ImplGetNextWindow( pParent, i, i, TRUE );
+ else
+ pWindow = ImplGetChildWindow( pParent, nFormStart, i, TRUE );
+ while ( bSearch )
+ {
+ const XubString aStr = pWindow->GetText();
+ USHORT nPos = aStr.Search( '~' );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ cCompareChar = aStr.GetChar( nPos+1 );
+ cCompareChar = xCharClass->toUpper( String(cCompareChar), 0, 1, rLocale )[0];
+ if ( cCompareChar == cCharCode )
+ {
+ // Bei Static-Controls auf das naechste Controlm weiterschalten
+ if ( (pWindow->GetType() == WINDOW_FIXEDTEXT) ||
+ (pWindow->GetType() == WINDOW_FIXEDLINE) ||
+ (pWindow->GetType() == WINDOW_GROUPBOX) )
+ pWindow = pParent->ImplGetDlgWindow( i, DLGWINDOW_NEXT );
+ rIndex = i;
+ return pWindow;
+ }
+ nPos = aStr.Search( '~', nPos+1 );
+ }
+
+ if ( i == nStart )
+ break;
+
+ if ( i < nFormEnd )
+ pWindow = ImplGetNextWindow( pParent, i, i, TRUE );
+ else
+ pWindow = ImplGetChildWindow( pParent, nFormStart, i, TRUE );
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static Window* ImplFindDlgCtrlWindow( Window* pParent, Window* pWindow, USHORT& rIndex,
+ USHORT& rFormStart, USHORT& rFormEnd )
+{
+ Window* pSWindow;
+ Window* pSecondWindow = NULL;
+ Window* pTempWindow = NULL;
+ USHORT i;
+ USHORT nSecond_i;
+ USHORT nFormStart = 0;
+ USHORT nSecondFormStart;
+ USHORT nFormEnd;
+
+ // Focus-Fenster in der Child-Liste suchen
+ pSWindow = ImplGetChildWindow( pParent, 0, i, FALSE );
+ while ( pSWindow )
+ {
+ if ( pSWindow->ImplGetWindow()->IsDialogControlStart() )
+ nFormStart = i;
+
+ // SecondWindow wegen zusammengesetzten Controls wie
+ // ComboBoxen und Feldern
+ if ( pSWindow->ImplIsWindowOrChild( pWindow ) )
+ {
+ pSecondWindow = pSWindow;
+ nSecond_i = i;
+ nSecondFormStart = nFormStart;
+ if ( pSWindow == pWindow )
+ break;
+ }
+
+ pSWindow = ImplGetNextWindow( pParent, i, i, FALSE );
+ if ( !i )
+ pSWindow = NULL;
+ }
+
+ if ( !pSWindow )
+ {
+ // Fenster nicht gefunden, dann koennen wir auch keine
+ // Steuerung uebernehmen
+ if ( !pSecondWindow )
+ return NULL;
+ else
+ {
+ pSWindow = pSecondWindow;
+ i = nSecond_i;
+ nFormStart = nSecondFormStart;
+ }
+ }
+
+ // Start-Daten setzen
+ rIndex = i;
+ rFormStart = nFormStart;
+
+ // Formularende suchen
+ nFormEnd = nFormStart;
+ pTempWindow = pSWindow;
+ do
+ {
+ nFormEnd = i;
+ pTempWindow = ImplGetNextWindow( pParent, i, i, FALSE );
+ if ( !i || (pTempWindow && pTempWindow->ImplGetWindow()->IsDialogControlStart()) )
+ break;
+ }
+ while ( pTempWindow );
+ rFormEnd = nFormEnd;
+
+ return pSWindow;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplControlFocus( USHORT nFlags )
+{
+ if ( nFlags & GETFOCUS_MNEMONIC )
+ {
+ if ( GetType() == WINDOW_RADIOBUTTON )
+ {
+ if ( !((RadioButton*)this)->IsChecked() )
+ ((RadioButton*)this)->ImplCallClick( TRUE, nFlags );
+ else
+ ImplGrabFocus( nFlags );
+ }
+ else
+ {
+ ImplGrabFocus( nFlags );
+ if ( nFlags & GETFOCUS_UNIQUEMNEMONIC )
+ {
+ if ( GetType() == WINDOW_CHECKBOX )
+ ((CheckBox*)this)->ImplCheck();
+ else if ( mbPushButton )
+ {
+ ((PushButton*)this)->SetPressed( TRUE );
+ ((PushButton*)this)->SetPressed( FALSE );
+ ((PushButton*)this)->Click();
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( GetType() == WINDOW_RADIOBUTTON )
+ {
+ if ( !((RadioButton*)this)->IsChecked() )
+ ((RadioButton*)this)->ImplCallClick( TRUE, nFlags );
+ else
+ ImplGrabFocus( nFlags );
+ }
+ else
+ ImplGrabFocus( nFlags );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplDlgCtrl( const KeyEvent& rKEvt, BOOL bKeyInput )
+{
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+ Window* pSWindow;
+ Window* pTempWindow;
+ Window* pButtonWindow;
+ USHORT i;
+ USHORT iButton;
+ USHORT iButtonStart;
+ USHORT iTemp;
+ USHORT nIndex;
+ USHORT nFormStart;
+ USHORT nFormEnd;
+ USHORT nDlgCtrlFlags;
+
+ // Ohne Focus-Window koennen wir auch keine Steuerung uebernehmen
+ Window* pFocusWindow = Application::GetFocusWindow();
+ if ( !pFocusWindow || !ImplIsWindowOrChild( pFocusWindow ) )
+ return FALSE;
+
+ // Focus-Fenster in der Child-Liste suchen
+ pSWindow = ::ImplFindDlgCtrlWindow( this, pFocusWindow,
+ nIndex, nFormStart, nFormEnd );
+ if ( !pSWindow )
+ return FALSE;
+ i = nIndex;
+
+ nDlgCtrlFlags = 0;
+ pTempWindow = pSWindow;
+ do
+ {
+ nDlgCtrlFlags |= pTempWindow->GetDialogControlFlags();
+ if ( pTempWindow == this )
+ break;
+ pTempWindow = pTempWindow->ImplGetParent();
+ }
+ while ( pTempWindow );
+
+ pButtonWindow = NULL;
+
+ if ( nKeyCode == KEY_RETURN )
+ {
+ // Wir suchen zuerst nach einem DefPushButton/CancelButton
+ pButtonWindow = ImplGetChildWindow( this, nFormStart, iButton, TRUE );
+ iButtonStart = iButton;
+ while ( pButtonWindow )
+ {
+ if ( (pButtonWindow->GetStyle() & WB_DEFBUTTON) &&
+ pButtonWindow->mbPushButton )
+ break;
+
+ pButtonWindow = ImplGetNextWindow( this, iButton, iButton, TRUE );
+ if ( (iButton <= iButtonStart) || (iButton > nFormEnd) )
+ pButtonWindow = NULL;
+ }
+
+ if ( bKeyInput && !pButtonWindow && (nDlgCtrlFlags & WINDOW_DLGCTRL_RETURN) )
+ {
+ USHORT nType;
+ USHORT nGetFocusFlags = GETFOCUS_TAB;
+ USHORT nNewIndex;
+ USHORT iStart;
+ if ( aKeyCode.IsShift() )
+ {
+ nType = DLGWINDOW_PREV;
+ nGetFocusFlags |= GETFOCUS_BACKWARD;
+ }
+ else
+ {
+ nType = DLGWINDOW_NEXT;
+ nGetFocusFlags |= GETFOCUS_FORWARD;
+ }
+ iStart = i;
+ pTempWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
+ while ( pTempWindow && (pTempWindow != pSWindow) )
+ {
+ if ( !pTempWindow->mbPushButton )
+ {
+ // Around-Flag ermitteln
+ if ( nType == DLGWINDOW_PREV )
+ {
+ if ( nNewIndex > iStart )
+ nGetFocusFlags |= GETFOCUS_AROUND;
+ }
+ else
+ {
+ if ( nNewIndex < iStart )
+ nGetFocusFlags |= GETFOCUS_AROUND;
+ }
+ pTempWindow->ImplControlFocus( nGetFocusFlags );
+ return TRUE;
+ }
+ else
+ {
+ i = nNewIndex;
+ pTempWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
+ }
+ if ( (i <= iStart) || (i > nFormEnd) )
+ pTempWindow = NULL;
+ }
+ // Wenn es das gleiche Fenster ist, ein Get/LoseFocus
+ // simulieren, falls AROUND ausgewertet wird
+ if ( pTempWindow && (pTempWindow == pSWindow) )
+ {
+ NotifyEvent aNEvt1( EVENT_LOSEFOCUS, pSWindow );
+ if ( !ImplCallPreNotify( aNEvt1 ) )
+ pSWindow->LoseFocus();
+ pSWindow->mnGetFocusFlags = nGetFocusFlags | GETFOCUS_AROUND;
+ NotifyEvent aNEvt2( EVENT_GETFOCUS, pSWindow );
+ if ( !ImplCallPreNotify( aNEvt2 ) )
+ pSWindow->GetFocus();
+ pSWindow->mnGetFocusFlags = 0;
+ return TRUE;
+ }
+ }
+ }
+ else if ( nKeyCode == KEY_ESCAPE )
+ {
+ // Wir suchen zuerst nach einem DefPushButton/CancelButton
+ pButtonWindow = ImplGetChildWindow( this, nFormStart, iButton, TRUE );
+ iButtonStart = iButton;
+ while ( pButtonWindow )
+ {
+ if ( pButtonWindow->GetType() == WINDOW_CANCELBUTTON )
+ break;
+
+ pButtonWindow = ImplGetNextWindow( this, iButton, iButton, TRUE );
+ if ( (iButton <= iButtonStart) || (iButton > nFormEnd) )
+ pButtonWindow = NULL;
+ }
+
+ if ( bKeyInput && mpDlgCtrlDownWindow )
+ {
+ if ( mpDlgCtrlDownWindow != pButtonWindow )
+ {
+ ((PushButton*)mpDlgCtrlDownWindow)->SetPressed( FALSE );
+ mpDlgCtrlDownWindow = NULL;
+ return TRUE;
+ }
+ }
+ }
+ else if ( bKeyInput )
+ {
+ if ( nKeyCode == KEY_TAB )
+ {
+ // keine Alt-Taste abfangen, wegen Windows
+ if ( !aKeyCode.IsMod2() )
+ {
+ USHORT nType;
+ USHORT nGetFocusFlags = GETFOCUS_TAB;
+ USHORT nNewIndex;
+ BOOL bFormular = FALSE;
+
+ // Bei Ctrl-Tab erstmal testen, ob zwischen Formularen
+ // gesprungen werden soll
+ if ( aKeyCode.IsMod1() )
+ {
+ // Gruppe suchen
+ Window* pFormularFirstWindow = NULL;
+ Window* pLastFormularFirstWindow = NULL;
+ pTempWindow = ImplGetChildWindow( this, 0, iTemp, FALSE );
+ Window* pPrevFirstFormularFirstWindow = NULL;
+ Window* pFirstFormularFirstWindow = pTempWindow;
+ while ( pTempWindow )
+ {
+ if ( pTempWindow->ImplGetWindow()->IsDialogControlStart() )
+ {
+ if ( iTemp != 0 )
+ bFormular = TRUE;
+ if ( aKeyCode.IsShift() )
+ {
+ if ( iTemp <= nIndex )
+ pFormularFirstWindow = pPrevFirstFormularFirstWindow;
+ pPrevFirstFormularFirstWindow = pTempWindow;
+ }
+ else
+ {
+ if ( (iTemp > nIndex) && !pFormularFirstWindow )
+ pFormularFirstWindow = pTempWindow;
+ }
+ pLastFormularFirstWindow = pTempWindow;
+ }
+
+ pTempWindow = ImplGetNextWindow( this, iTemp, iTemp, FALSE );
+ if ( !iTemp )
+ pTempWindow = NULL;
+ }
+
+ if ( bFormular )
+ {
+ if ( !pFormularFirstWindow )
+ {
+ if ( aKeyCode.IsShift() )
+ pFormularFirstWindow = pLastFormularFirstWindow;
+ else
+ pFormularFirstWindow = pFirstFormularFirstWindow;
+ }
+
+ USHORT nFoundFormStart = 0;
+ USHORT nFoundFormEnd = 0;
+ USHORT nTempIndex = 0;
+ if ( ::ImplFindDlgCtrlWindow( this, pFormularFirstWindow, nTempIndex,
+ nFoundFormStart, nFoundFormEnd ) )
+ {
+ nTempIndex = nFoundFormStart;
+ pFormularFirstWindow = ImplGetDlgWindow( nTempIndex, DLGWINDOW_FIRST, nFoundFormStart, nFoundFormEnd );
+ if ( pFormularFirstWindow )
+ {
+ pFormularFirstWindow->ImplControlFocus();
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ if ( !bFormular )
+ {
+ // Nur mit Ctrl+Tab zwischen Controls springen, wenn
+ // es erlaubt wurde
+ if ( !aKeyCode.IsMod1() || (nDlgCtrlFlags & WINDOW_DLGCTRL_MOD1TAB) )
+ {
+ if ( aKeyCode.IsShift() )
+ {
+ nType = DLGWINDOW_PREV;
+ nGetFocusFlags |= GETFOCUS_BACKWARD;
+ }
+ else
+ {
+ nType = DLGWINDOW_NEXT;
+ nGetFocusFlags |= GETFOCUS_FORWARD;
+ }
+ Window* pWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
+ // Wenn es das gleiche Fenster ist, ein Get/LoseFocus
+ // simulieren, falls AROUND ausgewertet wird
+ if ( pWindow == pSWindow )
+ {
+ NotifyEvent aNEvt1( EVENT_LOSEFOCUS, pSWindow );
+ if ( !ImplCallPreNotify( aNEvt1 ) )
+ pSWindow->LoseFocus();
+ pSWindow->mnGetFocusFlags = nGetFocusFlags | GETFOCUS_AROUND;
+ NotifyEvent aNEvt2( EVENT_GETFOCUS, pSWindow );
+ if ( !ImplCallPreNotify( aNEvt2 ) )
+ pSWindow->GetFocus();
+ pSWindow->mnGetFocusFlags = 0;
+ return TRUE;
+ }
+ else if ( pWindow )
+ {
+ // Around-Flag ermitteln
+ if ( nType == DLGWINDOW_PREV )
+ {
+ if ( nNewIndex > i )
+ nGetFocusFlags |= GETFOCUS_AROUND;
+ }
+ else
+ {
+ if ( nNewIndex < i )
+ nGetFocusFlags |= GETFOCUS_AROUND;
+ }
+ pWindow->ImplControlFocus( nGetFocusFlags );
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ else if ( (nKeyCode == KEY_LEFT) || (nKeyCode == KEY_UP) )
+ {
+ Window* pWindow = pSWindow;
+ WinBits nStyle = pSWindow->GetStyle();
+ if ( !(nStyle & WB_GROUP) )
+ {
+ pWindow = pWindow->GetWindow( WINDOW_PREV );
+ while ( pWindow )
+ {
+ pWindow = pWindow->ImplGetWindow();
+
+ nStyle = pWindow->GetStyle();
+
+ if ( pWindow->IsVisible() && pWindow->IsEnabled() && pWindow->IsInputEnabled() )
+ {
+ if ( pWindow != pSWindow )
+ pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
+ return TRUE;
+ }
+
+ if ( nStyle & WB_GROUP )
+ break;
+
+ pWindow = pWindow->GetWindow( WINDOW_PREV );
+ }
+ }
+ }
+ else if ( (nKeyCode == KEY_RIGHT) || (nKeyCode == KEY_DOWN) )
+ {
+ Window* pWindow;
+ WinBits nStyle;
+ pWindow = pSWindow->GetWindow( WINDOW_NEXT );
+ while ( pWindow )
+ {
+ pWindow = pWindow->ImplGetWindow();
+
+ nStyle = pWindow->GetStyle();
+
+ if ( nStyle & WB_GROUP )
+ break;
+
+ if ( pWindow->IsVisible() && pWindow->IsEnabled() && pWindow->IsInputEnabled() )
+ {
+ pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
+ return TRUE;
+ }
+
+ pWindow = pWindow->GetWindow( WINDOW_NEXT );
+ }
+ }
+ else
+ {
+ xub_Unicode c = rKEvt.GetCharCode();
+ if ( c )
+ {
+ pSWindow = ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd );
+ if ( pSWindow )
+ {
+ USHORT nGetFocusFlags = GETFOCUS_MNEMONIC;
+ if ( pSWindow == ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd ) )
+ nGetFocusFlags |= GETFOCUS_UNIQUEMNEMONIC;
+ pSWindow->ImplControlFocus( nGetFocusFlags );
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ if ( pButtonWindow && pButtonWindow->IsVisible() && pButtonWindow->IsEnabled() && pButtonWindow->IsInputEnabled() )
+ {
+ if ( bKeyInput )
+ {
+ if ( mpDlgCtrlDownWindow && (mpDlgCtrlDownWindow != pButtonWindow) )
+ {
+ ((PushButton*)mpDlgCtrlDownWindow)->SetPressed( FALSE );
+ mpDlgCtrlDownWindow = NULL;
+ }
+
+ ((PushButton*)pButtonWindow)->SetPressed( TRUE );
+ mpDlgCtrlDownWindow = pButtonWindow;
+ }
+ else if ( mpDlgCtrlDownWindow == pButtonWindow )
+ {
+ mpDlgCtrlDownWindow = NULL;
+ ((PushButton*)pButtonWindow)->SetPressed( FALSE );
+ ((PushButton*)pButtonWindow)->Click();
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplDlgCtrlNextWindow()
+{
+ Window* pDlgCtrlParent;
+ Window* pDlgCtrl;
+ Window* pSWindow;
+ USHORT nIndex;
+ USHORT nFormStart;
+ USHORT nFormEnd;
+
+ // Fenster fuer Dialog-Steuerung suchen
+ pDlgCtrl = this;
+ pDlgCtrlParent = ImplGetParent();
+ while ( pDlgCtrlParent &&
+ !pDlgCtrlParent->ImplIsOverlapWindow() &&
+ ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
+ pDlgCtrlParent = pDlgCtrlParent->ImplGetParent();
+
+ if ( !pDlgCtrlParent || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
+ return;
+
+ // Fenster in der Child-Liste suchen
+ pSWindow = ::ImplFindDlgCtrlWindow( pDlgCtrlParent, pDlgCtrl,
+ nIndex, nFormStart, nFormEnd );
+ if ( !pSWindow )
+ return;
+
+ Window* pWindow = pDlgCtrlParent->ImplGetDlgWindow( nIndex, DLGWINDOW_NEXT, nFormStart, nFormEnd );
+ if ( pWindow && (pWindow != pSWindow) )
+ pWindow->ImplControlFocus();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDlgCtrlUpdateDefButton( Window* pParent, Window* pFocusWindow,
+ BOOL bGetFocus )
+{
+ PushButton* pOldDefButton = NULL;
+ PushButton* pNewDefButton = NULL;
+ Window* pSWindow;
+ USHORT i;
+ USHORT nFormStart;
+ USHORT nFormEnd;
+
+ // Formular suchen
+ pSWindow = ::ImplFindDlgCtrlWindow( pParent, pFocusWindow, i, nFormStart, nFormEnd );
+ if ( !pSWindow )
+ {
+ nFormStart = 0;
+ nFormEnd = 0xFFFF;
+ }
+
+ pSWindow = ImplGetChildWindow( pParent, nFormStart, i, FALSE );
+ while ( pSWindow )
+ {
+ if ( pSWindow->ImplIsPushButton() )
+ {
+ PushButton* pPushButton = (PushButton*)pSWindow;
+ if ( pPushButton->ImplIsDefButton() )
+ pOldDefButton = pPushButton;
+ if ( pPushButton->HasChildPathFocus() )
+ pNewDefButton = pPushButton;
+ else if ( !pNewDefButton && (pPushButton->GetStyle() & WB_DEFBUTTON) )
+ pNewDefButton = pPushButton;
+ }
+
+ pSWindow = ImplGetNextWindow( pParent, i, i, FALSE );
+ if ( !i || (i > nFormEnd) )
+ pSWindow = NULL;
+ }
+
+ if ( !bGetFocus )
+ {
+ USHORT nDummy;
+ Window* pNewFocusWindow = Application::GetFocusWindow();
+ if ( !pNewFocusWindow || !pParent->ImplIsWindowOrChild( pNewFocusWindow ) )
+ pNewDefButton = NULL;
+ else if ( !::ImplFindDlgCtrlWindow( pParent, pNewFocusWindow, i, nDummy, nDummy ) ||
+ (i < nFormStart) || (i > nFormEnd) )
+ pNewDefButton = NULL;
+ }
+
+ if ( pOldDefButton != pNewDefButton )
+ {
+ if ( pOldDefButton )
+ pOldDefButton->ImplSetDefButton( FALSE );
+ if ( pNewDefButton )
+ pNewDefButton->ImplSetDefButton( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplDlgCtrlFocusChanged( Window* pWindow, BOOL bGetFocus )
+{
+ if ( mpDlgCtrlDownWindow && !bGetFocus )
+ {
+ ((PushButton*)mpDlgCtrlDownWindow)->SetPressed( FALSE );
+ mpDlgCtrlDownWindow = NULL;
+ }
+
+ ImplDlgCtrlUpdateDefButton( this, pWindow, bGetFocus );
+}
+
+// -----------------------------------------------------------------------
+
+Window* Window::ImplFindDlgCtrlWindow( Window* pWindow )
+{
+ USHORT nIndex;
+ USHORT nFormStart;
+ USHORT nFormEnd;
+
+ // Focus-Fenster in der Child-Liste suchen und zurueckgeben
+ return ::ImplFindDlgCtrlWindow( this, pWindow, nIndex, nFormStart, nFormEnd );
+}
diff --git a/vcl/source/window/dockwin.cxx b/vcl/source/window/dockwin.cxx
new file mode 100644
index 000000000000..5a27ed7e75ef
--- /dev/null
+++ b/vcl/source/window/dockwin.cxx
@@ -0,0 +1,857 @@
+/*************************************************************************
+ *
+ * $RCSfile: dockwin.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_DOCKWIN_CXX
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+#ifndef _SV_FLOATWIN_HXX
+#include <floatwin.hxx>
+#endif
+#ifndef _SV_DOCKWIN_HXX
+#include <dockwin.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+
+#include <unowrap.hxx>
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define DOCKWIN_FLOATSTYLES (WB_SIZEABLE | WB_MOVEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_PINABLE | WB_ROLLABLE)
+
+// =======================================================================
+
+class ImplDockFloatWin : public FloatingWindow
+{
+private:
+ DockingWindow* mpDockWin;
+
+public:
+ ImplDockFloatWin( Window* pParent, WinBits nWinBits,
+ DockingWindow* pDockingWin );
+
+ virtual void Move();
+ virtual void TitleButtonClick( USHORT nButton );
+ virtual void Pin();
+ virtual void Roll();
+ virtual void PopupModeEnd();
+ virtual void Resizing( Size& rSize );
+ virtual BOOL Close();
+};
+
+// -----------------------------------------------------------------------
+
+ImplDockFloatWin::ImplDockFloatWin( Window* pParent, WinBits nWinBits,
+ DockingWindow* pDockingWin ) :
+ FloatingWindow( pParent, nWinBits )
+{
+ mpDockWin = pDockingWin;
+
+ // Daten vom DockingWindow uebernehmen
+ if ( pDockingWin )
+ {
+ SetSettings( pDockingWin->GetSettings() );
+ Enable( pDockingWin->IsEnabled(), FALSE );
+ EnableInput( pDockingWin->IsInputEnabled(), FALSE );
+ AlwaysEnableInput( pDockingWin->IsAlwaysEnableInput(), FALSE );
+ EnableAlwaysOnTop( pDockingWin->IsAlwaysOnTopEnabled() );
+ EnableDrop( pDockingWin->IsDropEnabled() );
+ SetActivateMode( pDockingWin->GetActivateMode() );
+ }
+
+ SetBackground();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDockFloatWin::Move()
+{
+ FloatingWindow::Move();
+ mpDockWin->Move();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDockFloatWin::TitleButtonClick( USHORT nButton )
+{
+ FloatingWindow::TitleButtonClick( nButton );
+ mpDockWin->TitleButtonClick( nButton );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDockFloatWin::Pin()
+{
+ FloatingWindow::Pin();
+ mpDockWin->Pin();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDockFloatWin::Roll()
+{
+ FloatingWindow::Roll();
+ mpDockWin->Roll();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDockFloatWin::PopupModeEnd()
+{
+ FloatingWindow::PopupModeEnd();
+ mpDockWin->PopupModeEnd();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDockFloatWin::Resizing( Size& rSize )
+{
+ FloatingWindow::Resizing( rSize );
+ mpDockWin->Resizing( rSize );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplDockFloatWin::Close()
+{
+ return mpDockWin->Close();
+}
+
+// =======================================================================
+
+BOOL DockingWindow::ImplStartDocking( const Point& rPos )
+{
+ if ( !mbDockable )
+ return FALSE;
+
+ maMouseOff = rPos;
+ maMouseStart = maMouseOff;
+ mbDocking = TRUE;
+ mbLastFloatMode = IsFloatingMode();
+ mbStartFloat = mbLastFloatMode;
+
+ // FloatingBorder berechnen
+ FloatingWindow* pWin;
+ if ( mpFloatWin )
+ pWin = mpFloatWin;
+ else
+ pWin = new ImplDockFloatWin( mpParent, mnFloatBits, NULL );
+ pWin->GetBorder( mnDockLeft, mnDockTop, mnDockRight, mnDockBottom );
+ if ( !mpFloatWin )
+ delete pWin;
+
+ Point aPos = ImplOutputToFrame( Point() );
+ Size aSize = Window::GetOutputSizePixel();
+ mnTrackX = aPos.X();
+ mnTrackY = aPos.Y();
+ mnTrackWidth = aSize.Width();
+ mnTrackHeight = aSize.Height();
+
+ if ( mbLastFloatMode )
+ {
+ maMouseOff.X() += mnDockLeft;
+ maMouseOff.Y() += mnDockTop;
+ mnTrackX -= mnDockLeft;
+ mnTrackY -= mnDockTop;
+ mnTrackWidth += mnDockLeft+mnDockRight;
+ mnTrackHeight += mnDockTop+mnDockBottom;
+ }
+
+ if ( GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_DOCKING )
+ mbDragFull = TRUE;
+ else
+ {
+ StartDocking();
+ mbDragFull = FALSE;
+ ImplUpdateAll();
+ ImplGetFrameWindow()->ImplUpdateAll();
+ }
+
+ StartTracking( STARTTRACK_KEYMOD );
+ return TRUE;
+}
+
+// =======================================================================
+
+void DockingWindow::ImplInitData()
+{
+ mbDockWin = TRUE;
+
+ mpFloatWin = NULL;
+ mbDockCanceled = FALSE;
+ mbDockPrevented = FALSE;
+ mbFloatPrevented = FALSE;
+ mbDocking = FALSE;
+ mbPined = FALSE;
+ mbRollUp = FALSE;
+ mbDockBtn = FALSE;
+ mbHideBtn = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::ImplInit( Window* pParent, WinBits nStyle )
+{
+ if ( !(nStyle & WB_NODIALOGCONTROL) )
+ nStyle |= WB_DIALOGCONTROL;
+
+ mpParent = pParent;
+ mbDockable = (nStyle & WB_DOCKABLE) != 0;
+ mnFloatBits = WB_BORDER | (nStyle & DOCKWIN_FLOATSTYLES);
+ nStyle &= ~(DOCKWIN_FLOATSTYLES | WB_BORDER);
+ if ( nStyle & WB_DOCKBORDER )
+ nStyle |= WB_BORDER;
+
+ Window::ImplInit( pParent, nStyle, NULL );
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::ImplInitSettings()
+{
+ // Hack, damit man auch DockingWindows ohne Hintergrund bauen kann
+ // und noch nicht alles umgestellt ist
+ if ( IsBackground() )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else if ( Window::GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetFaceColor();
+ else
+ aColor = rStyleSettings.GetWindowColor();
+ SetBackground( aColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::ImplLoadRes( const ResId& rResId )
+{
+ Window::ImplLoadRes( rResId );
+
+ USHORT nMask = ReadShortRes();
+
+ if ( (RSC_DOCKINGWINDOW_XYMAPMODE | RSC_DOCKINGWINDOW_X |
+ RSC_DOCKINGWINDOW_Y) & nMask )
+ {
+ // Groessenangabe aus der Resource verwenden
+ Point aPos;
+ MapUnit ePosMap = MAP_PIXEL;
+
+ if ( RSC_DOCKINGWINDOW_XYMAPMODE & nMask )
+ ePosMap = (MapUnit)ReadShortRes();
+
+ if ( RSC_DOCKINGWINDOW_X & nMask )
+ {
+ aPos.X() = ReadShortRes();
+ aPos.X() = ImplLogicUnitToPixelX( aPos.X(), ePosMap );
+ }
+
+ if ( RSC_DOCKINGWINDOW_Y & nMask )
+ {
+ aPos.Y() = ReadShortRes();
+ aPos.Y() = ImplLogicUnitToPixelY( aPos.Y(), ePosMap );
+ }
+
+ SetFloatingPos( aPos );
+ }
+
+ if ( nMask & RSC_DOCKINGWINDOW_FLOATING )
+ {
+ if ( (BOOL)ReadShortRes() )
+ SetFloatingMode( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+DockingWindow::DockingWindow( WindowType nType ) :
+ Window( nType )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+DockingWindow::DockingWindow( Window* pParent, WinBits nStyle ) :
+ Window( WINDOW_DOCKINGWINDOW )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+DockingWindow::DockingWindow( Window* pParent, const ResId& rResId ) :
+ Window( WINDOW_DOCKINGWINDOW )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_DOCKINGWINDOW );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+DockingWindow::~DockingWindow()
+{
+ if ( IsFloatingMode() )
+ {
+ Show( FALSE, SHOW_NOFOCUSCHANGE );
+ SetFloatingMode( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( mbDocking )
+ {
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ mbDocking = FALSE;
+ if ( mbDragFull )
+ {
+ // Bei Abbruch alten Zustand wieder herstellen
+ if ( rTEvt.IsTrackingCanceled() )
+ {
+ StartDocking();
+ Rectangle aRect( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) );
+ EndDocking( aRect, mbStartFloat );
+ }
+ }
+ else
+ {
+ HideTracking();
+ if ( rTEvt.IsTrackingCanceled() )
+ {
+ mbDockCanceled = TRUE;
+ EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
+ mbDockCanceled = FALSE;
+ }
+ else
+ EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
+ }
+ }
+ // Docking nur bei nicht synthetischen MouseEvents
+ else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() )
+ {
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+ Point aFrameMousePos = ImplOutputToFrame( aMousePos );
+ Size aFrameSize = mpFrameWindow->GetOutputSizePixel();
+ if ( aFrameMousePos.X() < 0 )
+ aFrameMousePos.X() = 0;
+ if ( aFrameMousePos.Y() < 0 )
+ aFrameMousePos.Y() = 0;
+ if ( aFrameMousePos.X() > aFrameSize.Width()-1 )
+ aFrameMousePos.X() = aFrameSize.Width()-1;
+ if ( aFrameMousePos.Y() > aFrameSize.Height()-1 )
+ aFrameMousePos.Y() = aFrameSize.Height()-1;
+ aMousePos = ImplFrameToOutput( aFrameMousePos );
+ aMousePos.X() -= maMouseOff.X();
+ aMousePos.Y() -= maMouseOff.Y();
+ Point aPos = ImplOutputToFrame( aMousePos );
+ Rectangle aTrackRect( aPos, Size( mnTrackWidth, mnTrackHeight ) );
+ Rectangle aCompRect = aTrackRect;
+ aPos.X() += maMouseOff.X();
+ aPos.Y() += maMouseOff.Y();
+ if ( mbDragFull )
+ StartDocking();
+ if ( !rTEvt.GetMouseEvent().IsMod1() )
+ mbDockPrevented = TRUE;
+ BOOL bFloatMode = Docking( aPos, aTrackRect );
+ mbDockPrevented = FALSE;
+ mbFloatPrevented = FALSE;
+ if ( mbLastFloatMode != bFloatMode )
+ {
+ if ( bFloatMode )
+ {
+ aTrackRect.Left() -= mnDockLeft;
+ aTrackRect.Top() -= mnDockTop;
+ aTrackRect.Right() += mnDockRight;
+ aTrackRect.Bottom() += mnDockBottom;
+ }
+ else
+ {
+ if ( aCompRect == aTrackRect )
+ {
+ aTrackRect.Left() += mnDockLeft;
+ aTrackRect.Top() += mnDockTop;
+ aTrackRect.Right() -= mnDockRight;
+ aTrackRect.Bottom() -= mnDockBottom;
+ }
+ }
+ mbLastFloatMode = bFloatMode;
+ }
+ if ( mbDragFull )
+ {
+ Point aPos;
+ Point aOldPos = OutputToScreenPixel( aPos );
+ EndDocking( aTrackRect, mbLastFloatMode );
+ // Wenn der Status bzw. die Position sich
+ // geaendert hat, dann neu ausgeben
+ if ( aOldPos != OutputToScreenPixel( aPos ) )
+ {
+ ImplUpdateAll();
+ ImplGetFrameWindow()->ImplUpdateAll();
+ }
+// EndDocking( aTrackRect, mbLastFloatMode );
+ }
+ else
+ {
+ USHORT nTrackStyle;
+ if ( bFloatMode )
+ nTrackStyle = SHOWTRACK_BIG;
+ else
+ nTrackStyle = SHOWTRACK_SMALL;
+ Rectangle aShowTrackRect = aTrackRect;
+ aShowTrackRect.SetPos( ImplFrameToOutput( aShowTrackRect.TopLeft() ) );
+ ShowTracking( aShowTrackRect, nTrackStyle );
+
+ // Maus-Offset neu berechnen, da Rechteck veraendert werden
+ // konnte
+ maMouseOff.X() = aPos.X() - aTrackRect.Left();
+ maMouseOff.Y() = aPos.Y() - aTrackRect.Top();
+ }
+
+ mnTrackX = aTrackRect.Left();
+ mnTrackY = aTrackRect.Top();
+ mnTrackWidth = aTrackRect.GetWidth();
+ mnTrackHeight = aTrackRect.GetHeight();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long DockingWindow::Notify( NotifyEvent& rNEvt )
+{
+ if ( mbDockable )
+ {
+ if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
+ {
+ const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
+ if ( pMEvt->IsLeft() )
+ {
+ if ( pMEvt->GetClicks() == 2 )
+ {
+ if ( pMEvt->IsMod1() )
+ SetFloatingMode( !IsFloatingMode() );
+ return TRUE;
+ }
+ else if ( pMEvt->GetClicks() == 1 )
+ {
+ Point aPos = pMEvt->GetPosPixel();
+ Window* pWindow = rNEvt.GetWindow();
+ if ( pWindow != this )
+ {
+ aPos = pWindow->OutputToScreenPixel( aPos );
+ aPos = ScreenToOutputPixel( aPos );
+ }
+ if ( IsFloatingMode() || pMEvt->IsMod1() )
+ ImplStartDocking( aPos );
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return Window::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::StartDocking()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL DockingWindow::Docking( const Point&, Rectangle& )
+{
+ return IsFloatingMode();
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::EndDocking( const Rectangle& rRect, BOOL bFloatMode )
+{
+ if ( !IsDockingCanceled() )
+ {
+ BOOL bShow = FALSE;
+ if ( bFloatMode != IsFloatingMode() )
+ {
+ Show( FALSE, SHOW_NOFOCUSCHANGE );
+ SetFloatingMode( bFloatMode );
+ bShow = TRUE;
+ }
+ if ( bFloatMode )
+ mpFloatWin->SetPosSizePixel( rRect.TopLeft(), rRect.GetSize() );
+ else
+ {
+ Point aPos = rRect.TopLeft();
+ aPos = GetParent()->ScreenToOutputPixel( aPos );
+ Window::SetPosSizePixel( aPos, rRect.GetSize() );
+ }
+
+ if ( bShow )
+ Show();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL DockingWindow::PrepareToggleFloatingMode()
+{
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL DockingWindow::Close()
+{
+ if ( mxWindowPeer.is() )
+ {
+ Application::GetUnoWrapper()->WindowEvent_Close( this );
+ if ( IsCreatedWithToolkit() )
+ return FALSE;
+ }
+
+ Show( FALSE, SHOW_NOFOCUSCHANGE );
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::ToggleFloatingMode()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::TitleButtonClick( USHORT )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::Pin()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::Roll()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::PopupModeEnd()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::Resizing( Size& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+
+ Window::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+ else
+ Window::DataChanged( rDCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::ShowTitleButton( USHORT nButton, BOOL bVisible )
+{
+ if ( mpFloatWin )
+ mpFloatWin->ShowTitleButton( nButton, bVisible );
+ else
+ {
+ if ( nButton == TITLE_BUTTON_DOCKING )
+ mbDockBtn = bVisible;
+ else /* if ( nButton == TITLE_BUTTON_HIDE ) */
+ mbHideBtn = bVisible;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL DockingWindow::IsTitleButtonVisible( USHORT nButton ) const
+{
+ if ( mpFloatWin )
+ return mpFloatWin->IsTitleButtonVisible( nButton );
+ else
+ {
+ if ( nButton == TITLE_BUTTON_DOCKING )
+ return mbDockBtn;
+ else /* if ( nButton == TITLE_BUTTON_HIDE ) */
+ return mbHideBtn;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::SetFloatingMode( BOOL bFloatMode )
+{
+ if ( IsFloatingMode() != bFloatMode )
+ {
+ if ( PrepareToggleFloatingMode() )
+ {
+ BOOL bVisible = IsVisible();
+
+ if ( bFloatMode )
+ {
+ Show( FALSE, SHOW_NOFOCUSCHANGE );
+
+ maDockPos = Window::GetPosPixel();
+
+ Window* pRealParent = mpRealParent;
+ mpOldBorderWin = mpBorderWindow;
+ ImplDockFloatWin* pWin = new ImplDockFloatWin( mpParent, mnFloatBits, this );
+ mpFloatWin = pWin;
+ mpBorderWindow = NULL;
+ mnLeftBorder = 0;
+ mnTopBorder = 0;
+ mnRightBorder = 0;
+ mnBottomBorder = 0;
+ // Falls Parent zerstoert wird, muessen wir auch vom
+ // BorderWindow den Parent umsetzen
+ if ( mpOldBorderWin )
+ mpOldBorderWin->SetParent( pWin );
+ SetParent( pWin );
+ SetPosPixel( Point() );
+ mpBorderWindow = pWin;
+ pWin->mpClientWindow = this;
+ mpRealParent = pRealParent;
+ pWin->SetText( Window::GetText() );
+ pWin->SetOutputSizePixel( Window::GetSizePixel() );
+ pWin->SetPosPixel( maFloatPos );
+ // DockingDaten ans FloatingWindow weiterreichen
+ pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn );
+ pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn );
+ pWin->SetPin( mbPined );
+ if ( mbRollUp )
+ pWin->RollUp();
+ else
+ pWin->RollDown();
+ pWin->SetRollUpOutputSizePixel( maRollUpOutSize );
+ pWin->SetMinOutputSizePixel( maMinOutSize );
+
+ ToggleFloatingMode();
+
+ if ( bVisible )
+ Show();
+ }
+ else
+ {
+ Show( FALSE, SHOW_NOFOCUSCHANGE );
+
+ // FloatingDaten wird im FloatingWindow speichern
+ maFloatPos = mpFloatWin->GetPosPixel();
+ mbDockBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING );
+ mbHideBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE );
+ mbPined = mpFloatWin->IsPined();
+ mbRollUp = mpFloatWin->IsRollUp();
+ maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
+ maMinOutSize = mpFloatWin->GetMinOutputSizePixel();
+
+ Window* pRealParent = mpRealParent;
+ mpBorderWindow = NULL;
+ if ( mpOldBorderWin )
+ {
+ SetParent( mpOldBorderWin );
+ ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder );
+ mpOldBorderWin->Resize();
+ }
+ mpBorderWindow = mpOldBorderWin;
+ SetParent( pRealParent );
+ mpRealParent = pRealParent;
+ delete mpFloatWin;
+ mpFloatWin = NULL;
+ SetPosPixel( maDockPos );
+
+ ToggleFloatingMode();
+
+ if ( bVisible )
+ Show();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::SetFloatStyle( WinBits nStyle )
+{
+ mnFloatBits = nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+WinBits DockingWindow::GetFloatStyle() const
+{
+ return mnFloatBits;
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::SetTabStop()
+{
+ mnStyle |= WB_GROUP | WB_TABSTOP;
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::SetPosSizePixel( long nX, long nY,
+ long nWidth, long nHeight,
+ USHORT nFlags )
+{
+ if ( mpFloatWin )
+ mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
+ else
+ Window::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+Point DockingWindow::GetPosPixel() const
+{
+ if ( mpFloatWin )
+ return mpFloatWin->GetPosPixel();
+ else
+ return Window::GetPosPixel();
+}
+
+// -----------------------------------------------------------------------
+
+Size DockingWindow::GetSizePixel() const
+{
+ if ( mpFloatWin )
+ return mpFloatWin->GetSizePixel();
+ else
+ return Window::GetSizePixel();
+}
+
+// -----------------------------------------------------------------------
+
+void DockingWindow::SetOutputSizePixel( const Size& rNewSize )
+{
+ if ( mpFloatWin )
+ mpFloatWin->SetOutputSizePixel( rNewSize );
+ else
+ Window::SetOutputSizePixel( rNewSize );
+}
+
+// -----------------------------------------------------------------------
+
+Size DockingWindow::GetOutputSizePixel() const
+{
+ if ( mpFloatWin )
+ return mpFloatWin->GetOutputSizePixel();
+ else
+ return Window::GetOutputSizePixel();
+}
diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx
new file mode 100644
index 000000000000..800734aadf86
--- /dev/null
+++ b/vcl/source/window/floatwin.cxx
@@ -0,0 +1,748 @@
+/*************************************************************************
+ *
+ * $RCSfile: floatwin.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_FLOATWIN_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+#ifndef _SV_TOOLBOX_HXX
+#include <toolbox.hxx>
+#endif
+#ifndef _SV_FLOATWIN_HXX
+#include <floatwin.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+void FloatingWindow::ImplInit( Window* pParent, WinBits nStyle )
+{
+ mbFloatWin = TRUE;
+
+ if ( !pParent )
+ pParent = Application::GetAppWindow();
+
+ DBG_ASSERT( pParent, "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists" );
+
+ // no Border, then we dont need a border window
+ if ( !nStyle )
+ {
+ mbOverlapWin = TRUE;
+ if ( !(nStyle & WB_NODIALOGCONTROL) )
+ nStyle |= WB_DIALOGCONTROL;
+ SystemWindow::ImplInit( pParent, nStyle, NULL );
+ }
+ else
+ {
+ ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle, BORDERWINDOW_STYLE_OVERLAP | BORDERWINDOW_STYLE_BORDER | BORDERWINDOW_STYLE_FLOAT );
+ if ( !(nStyle & WB_NODIALOGCONTROL) )
+ nStyle |= WB_DIALOGCONTROL;
+ SystemWindow::ImplInit( pBorderWin, nStyle & ~WB_BORDER, NULL );
+ pBorderWin->mpClientWindow = this;
+ pBorderWin->GetBorder( mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder );
+ pBorderWin->SetDisplayActive( TRUE );
+ mpBorderWindow = pBorderWin;
+ mpRealParent = pParent;
+ }
+ SetActivateMode( 0 );
+
+ mpNextFloat = NULL;
+ mpFirstPopupModeWin = NULL;
+ mpBox = NULL;
+ mnPostId = 0;
+ mnTitle = (nStyle & WB_MOVEABLE) ? FLOATWIN_TITLE_NORMAL : FLOATWIN_TITLE_NONE;
+ mnOldTitle = mnTitle;
+ mnPopupModeFlags = 0;
+ mbInPopupMode = FALSE;
+ mbPopupMode = FALSE;
+ mbPopupModeCanceled = FALSE;
+ mbPopupModeTearOff = FALSE;
+ mbMouseDown = FALSE;
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::ImplInitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else if ( Window::GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetFaceColor();
+ else
+ aColor = rStyleSettings.GetWindowColor();
+ SetBackground( aColor );
+}
+
+// =======================================================================
+
+FloatingWindow::FloatingWindow( Window* pParent, WinBits nStyle ) :
+ SystemWindow( WINDOW_FLOATINGWINDOW )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+FloatingWindow::FloatingWindow( Window* pParent, const ResId& rResId ) :
+ SystemWindow( WINDOW_FLOATINGWINDOW )
+{
+ rResId.SetRT( RSC_FLOATINGWINDOW );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::ImplLoadRes( const ResId& rResId )
+{
+ SystemWindow::ImplLoadRes( rResId );
+
+ USHORT nObjMask = ReadShortRes();
+
+ if ( (RSC_FLOATINGWINDOW_WHMAPMODE | RSC_FLOATINGWINDOW_WIDTH |
+ RSC_FLOATINGWINDOW_HEIGHT) & nObjMask )
+ {
+ // Groessenangabe aus der Resource verwenden
+ Size aSize;
+ MapUnit eSizeMap = MAP_PIXEL;
+
+ if ( RSC_FLOATINGWINDOW_WHMAPMODE & nObjMask )
+ eSizeMap = (MapUnit) ReadShortRes();
+ if ( RSC_FLOATINGWINDOW_WIDTH & nObjMask )
+ aSize.Width() = ReadShortRes();
+ if ( RSC_FLOATINGWINDOW_HEIGHT & nObjMask )
+ aSize.Height() = ReadShortRes();
+
+ SetRollUpOutputSizePixel( LogicToPixel( aSize, eSizeMap ) );
+ }
+
+ if (nObjMask & RSC_FLOATINGWINDOW_ZOOMIN )
+ {
+ if ( ReadShortRes() )
+ RollUp();
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+FloatingWindow::~FloatingWindow()
+{
+ if ( IsInPopupMode() )
+ EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL | FLOATWIN_POPUPMODEEND_DONTCALLHDL );
+
+ if ( mnPostId )
+ Application::RemoveUserEvent( mnPostId );
+}
+
+// -----------------------------------------------------------------------
+
+Point FloatingWindow::ImplCalcPos( Window* pWindow,
+ const Rectangle& rRect, ULONG nFlags,
+ USHORT& rArrangeIndex )
+{
+ // Fenster-Position ermitteln
+ Point aPos;
+ Size aSize = pWindow->GetSizePixel();
+ Rectangle aScreenRect = pWindow->ImplGetFrameWindow()->GetDesktopRectPixel();
+ USHORT nArrangeAry[5];
+ USHORT nArrangeIndex;
+ BOOL bLeft;
+ BOOL bTop;
+ BOOL bBreak;
+ if ( nFlags & FLOATWIN_POPUPMODE_LEFT )
+ {
+ nArrangeAry[0] = FLOATWIN_POPUPMODE_LEFT;
+ nArrangeAry[1] = FLOATWIN_POPUPMODE_RIGHT;
+ nArrangeAry[2] = FLOATWIN_POPUPMODE_UP;
+ nArrangeAry[3] = FLOATWIN_POPUPMODE_DOWN;
+ nArrangeAry[4] = FLOATWIN_POPUPMODE_LEFT;
+ }
+ else if ( nFlags & FLOATWIN_POPUPMODE_RIGHT )
+ {
+ nArrangeAry[0] = FLOATWIN_POPUPMODE_RIGHT;
+ nArrangeAry[1] = FLOATWIN_POPUPMODE_LEFT;
+ nArrangeAry[2] = FLOATWIN_POPUPMODE_UP;
+ nArrangeAry[3] = FLOATWIN_POPUPMODE_DOWN;
+ nArrangeAry[4] = FLOATWIN_POPUPMODE_RIGHT;
+ }
+ else if ( nFlags & FLOATWIN_POPUPMODE_UP )
+ {
+ nArrangeAry[0] = FLOATWIN_POPUPMODE_UP;
+ nArrangeAry[1] = FLOATWIN_POPUPMODE_DOWN;
+ nArrangeAry[2] = FLOATWIN_POPUPMODE_RIGHT;
+ nArrangeAry[3] = FLOATWIN_POPUPMODE_LEFT;
+ nArrangeAry[4] = FLOATWIN_POPUPMODE_UP;
+ }
+ else
+ {
+ nArrangeAry[0] = FLOATWIN_POPUPMODE_DOWN;
+ nArrangeAry[1] = FLOATWIN_POPUPMODE_UP;
+ nArrangeAry[2] = FLOATWIN_POPUPMODE_RIGHT;
+ nArrangeAry[3] = FLOATWIN_POPUPMODE_LEFT;
+ nArrangeAry[4] = FLOATWIN_POPUPMODE_DOWN;
+ }
+ if ( nFlags & FLOATWIN_POPUPMODE_NOAUTOARRANGE )
+ nArrangeIndex = 4;
+ else
+ nArrangeIndex = 0;
+ for ( ; nArrangeIndex < 5; nArrangeIndex++ )
+ {
+ bLeft = FALSE;
+ bTop = FALSE;
+ bBreak = TRUE;
+ switch ( nArrangeAry[nArrangeIndex] )
+ {
+ case FLOATWIN_POPUPMODE_LEFT:
+ aPos.X() = rRect.Left()-aSize.Width();
+ aPos.Y() = rRect.Top();
+ aPos.Y() -= pWindow->mnTopBorder;
+ if ( aPos.X() < aScreenRect.Left() )
+ bBreak = FALSE;
+ break;
+ case FLOATWIN_POPUPMODE_RIGHT:
+ aPos = rRect.TopRight();
+ aPos.Y() -= pWindow->mnTopBorder;
+ if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
+ bBreak = FALSE;
+ break;
+ case FLOATWIN_POPUPMODE_UP:
+ aPos.X() = rRect.Left();
+ aPos.Y() = rRect.Top()-aSize.Height();
+ if ( aPos.Y() < aScreenRect.Top() )
+ bBreak = FALSE;
+ break;
+ case FLOATWIN_POPUPMODE_DOWN:
+ aPos = rRect.BottomLeft();
+ if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
+ bBreak = FALSE;
+ break;
+ }
+
+ // Evt. noch anpassen
+ if ( bBreak && !(nFlags & FLOATWIN_POPUPMODE_NOAUTOARRANGE) )
+ {
+ if ( (nArrangeAry[nArrangeIndex] == FLOATWIN_POPUPMODE_LEFT) ||
+ (nArrangeAry[nArrangeIndex] == FLOATWIN_POPUPMODE_RIGHT) )
+ {
+ if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
+ {
+ bTop = TRUE;
+ aPos.Y() = rRect.Bottom()-aSize.Height();
+ if ( aPos.Y() < aScreenRect.Top() )
+ aPos.Y() = aScreenRect.Top();
+ }
+ }
+ else
+ {
+ if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
+ {
+ bLeft = TRUE;
+ aPos.X() = rRect.Right()-aSize.Width();
+ if ( aPos.X() < aScreenRect.Left() )
+ aPos.X() = aScreenRect.Left();
+ }
+ }
+ }
+
+ if ( bBreak )
+ break;
+ }
+ if ( nArrangeIndex > 4 )
+ nArrangeIndex = 4;
+
+ // Ansonsten soweit wie moeglich in den Bildschirm einpassen
+ if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
+ aPos.X() = aScreenRect.Right()-aSize.Width();
+ if ( aPos.X() < aScreenRect.Left() )
+ aPos.X() = aScreenRect.Left();
+ if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
+ aPos.Y() = aScreenRect.Bottom()-aSize.Height();
+ if ( aPos.Y() < aScreenRect.Top() )
+ aPos.Y() = aScreenRect.Top();
+
+ rArrangeIndex = nArrangeIndex;
+ return aPos;
+}
+
+// -----------------------------------------------------------------------
+
+FloatingWindow* FloatingWindow::ImplFloatHitTest( const Point& rPos, USHORT& rHitTest )
+{
+ FloatingWindow* pWin = this;
+
+ do
+ {
+ Rectangle aRect( pWin->GetPosPixel(), pWin->GetSizePixel() );
+ if ( aRect.IsInside( rPos ) )
+ {
+ rHitTest = IMPL_FLOATWIN_HITTEST_WINDOW;
+ return pWin;
+ }
+
+ // Testen, ob Maus im Rechteck
+ if ( pWin->maFloatRect.IsInside( rPos ) )
+ {
+ rHitTest = IMPL_FLOATWIN_HITTEST_RECT;
+ return pWin;
+ }
+
+ pWin = pWin->mpNextFloat;
+ }
+ while ( pWin );
+
+ rHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+FloatingWindow* FloatingWindow::ImplFindLastLevelFloat()
+{
+ FloatingWindow* pWin = this;
+ FloatingWindow* pLastFoundWin = pWin;
+
+ do
+ {
+ if ( pWin->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NEWLEVEL )
+ pLastFoundWin = pWin;
+
+ pWin = pWin->mpNextFloat;
+ }
+ while ( pWin );
+
+ return pLastFoundWin;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FloatingWindow::ImplIsFloatPopupModeWindow( const Window* pWindow )
+{
+ FloatingWindow* pWin = this;
+
+ do
+ {
+ if ( pWin->mpFirstPopupModeWin == pWindow )
+ return TRUE;
+
+ pWin = pWin->mpNextFloat;
+ }
+ while ( pWin );
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FloatingWindow, ImplEndPopupModeHdl, void*, EMPTYARG )
+{
+ mnPostId = 0;
+ mnPopupModeFlags = 0;
+ mbPopupMode = FALSE;
+ PopupModeEnd();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long FloatingWindow::Notify( NotifyEvent& rNEvt )
+{
+ // Zuerst Basisklasse rufen wegen TabSteuerung
+ long nRet = SystemWindow::Notify( rNEvt );
+ if ( !nRet )
+ {
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( (nKeyCode == KEY_ESCAPE) && (GetStyle() & WB_CLOSEABLE) )
+ {
+ Close();
+ return TRUE;
+ }
+ }
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::StateChanged( StateChangedType nType )
+{
+ SystemWindow::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SystemWindow::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::ImplCallPopupModeEnd()
+{
+ // PopupMode wurde beendet
+ mbInPopupMode = FALSE;
+
+ // Handler asyncron rufen
+ if ( !mnPostId )
+ Application::PostUserEvent( mnPostId, LINK( this, FloatingWindow, ImplEndPopupModeHdl ) );
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::PopupModeEnd()
+{
+ maPopupModeEndHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::SetTitleType( USHORT nTitle )
+{
+ if ( (mnTitle != nTitle) && mpBorderWindow )
+ {
+ mnTitle = nTitle;
+ Size aOutSize = GetOutputSizePixel();
+ USHORT nTitleStyle;
+ if ( nTitle == FLOATWIN_TITLE_NORMAL )
+ nTitleStyle = BORDERWINDOW_TITLE_SMALL;
+ else if ( nTitle == FLOATWIN_TITLE_TEAROFF )
+ nTitleStyle = BORDERWINDOW_TITLE_TEAROFF;
+ else // nTitle == FLOATWIN_TITLE_NONE
+ nTitleStyle = BORDERWINDOW_TITLE_NONE;
+ ((ImplBorderWindow*)mpBorderWindow)->SetTitleType( nTitleStyle, aOutSize );
+ ((ImplBorderWindow*)mpBorderWindow)->GetBorder( mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::StartPopupMode( const Rectangle& rRect, ULONG nFlags )
+{
+ DBG_ASSERT( (GetStyle() & WB_MOVEABLE) || !(nFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF),
+ "TearOff only allowed, when FloatingWindow moveable" );
+
+ // Wenn Fenster sichtbar, dann vorher hiden, da es sonst flackert
+ if ( IsVisible() )
+ Show( FALSE, SHOW_NOFOCUSCHANGE );
+
+ // Wenn Fenster klein, dann vorher aufklappen
+ if ( IsRollUp() )
+ RollDown();
+
+ // Title wegnehmen
+ mnOldTitle = mnTitle;
+ if ( nFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF )
+ SetTitleType( FLOATWIN_TITLE_TEAROFF );
+ else
+ SetTitleType( FLOATWIN_TITLE_NONE );
+
+ // Fenster-Position ermitteln und setzen
+ USHORT nArrangeIndex;
+ SetPosPixel( ImplCalcPos( this, rRect, nFlags, nArrangeIndex ) );
+
+ // Daten seten und Fenster anzeigen
+ maFloatRect = rRect;
+ maFloatRect.Left() -= 2;
+ maFloatRect.Top() -= 2;
+ maFloatRect.Right() += 2;
+ maFloatRect.Bottom() += 2;
+ mnPopupModeFlags = nFlags;
+ mbInPopupMode = TRUE;
+ mbPopupMode = TRUE;
+ mbPopupModeCanceled = FALSE;
+ mbPopupModeTearOff = FALSE;
+ mbMouseDown = FALSE;
+
+ mbOldSaveBackMode = IsSaveBackgroundEnabled();
+ EnableSaveBackground();
+
+/*
+ // Abfragen, ob Animation eingeschaltet ist
+ if ( (Application::GetSettings().GetAnimationOptions() & ANIMATION_OPTION_POPUP) &&
+ !(nFlags & FLOATWIN_POPUPMODE_NOANIMATION) )
+ {
+ USHORT nAniFlags;
+ switch ( nArrangeAry[nArrangeIndex] )
+ {
+ case FLOATWIN_POPUPMODE_LEFT:
+ nAniFlags = STARTANIMATION_LEFT;
+ break;
+ case FLOATWIN_POPUPMODE_RIGHT:
+ nAniFlags = STARTANIMATION_RIGHT;
+ break;
+ case FLOATWIN_POPUPMODE_UP:
+ nAniFlags = STARTANIMATION_UP;
+ break;
+ case FLOATWIN_POPUPMODE_DOWN:
+ nAniFlags = STARTANIMATION_DOWN;
+ break;
+ }
+ if ( !(nFlags & FLOATWIN_POPUPMODE_ANIMATIONSLIDE) )
+ {
+ if ( bLeft )
+ nAniFlags |= STARTANIMATION_LEFT;
+ else
+ nAniFlags |= STARTANIMATION_RIGHT;
+ if ( bTop )
+ nAniFlags |= STARTANIMATION_UP;
+ else
+ nAniFlags |= STARTANIMATION_DOWN;
+ }
+
+ ImpStartAnimation( this, nAniFlags );
+ }
+ else
+*/
+ Show();
+
+ // FloatingWindow in Liste der Fenster aufnehmen, die sich im PopupModus
+ // befinden
+ ImplSVData* pSVData = ImplGetSVData();
+ mpNextFloat = pSVData->maWinData.mpFirstFloat;
+ pSVData->maWinData.mpFirstFloat = this;
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::StartPopupMode( ToolBox* pBox, ULONG nFlags )
+{
+ // Selektieten Button ermitteln
+ USHORT nItemId = pBox->GetDownItemId();
+ if ( !nItemId )
+ return;
+
+ mpBox = pBox;
+ pBox->ImplFloatControl( TRUE, this );
+
+ // Daten von der ToolBox holen
+ Rectangle aRect = pBox->GetItemRect( nItemId );
+ Point aPos = pBox->OutputToScreenPixel( aRect.TopLeft() );
+ aRect.SetPos( aPos );
+
+ // Flags fuer Positionierung bestimmen
+ if ( !(nFlags & (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_UP |
+ FLOATWIN_POPUPMODE_LEFT | FLOATWIN_POPUPMODE_RIGHT |
+ FLOATWIN_POPUPMODE_NOAUTOARRANGE)) )
+ {
+ WindowAlign eAlign = pBox->GetAlign();
+ if ( pBox->IsHorizontal() )
+ {
+ if ( pBox->IsFloatingMode() || (eAlign == WINDOWALIGN_TOP) )
+ nFlags |= FLOATWIN_POPUPMODE_DOWN;
+ else
+ nFlags |= FLOATWIN_POPUPMODE_UP;
+ }
+ else
+ {
+ if ( eAlign == WINDOWALIGN_LEFT )
+ nFlags |= FLOATWIN_POPUPMODE_RIGHT;
+ else
+ nFlags |= FLOATWIN_POPUPMODE_LEFT;
+ }
+ }
+
+ // FloatingModus starten
+ StartPopupMode( aRect, nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::ImplEndPopupMode( USHORT nFlags, ULONG nFocusId )
+{
+ if ( !mbInPopupMode )
+ return;
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Bei allen nachfolgenden PopupMode-Fenster den Modus auch beenden
+ while ( pSVData->maWinData.mpFirstFloat != this )
+ pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
+
+ // Fenster aus der Liste austragen
+ pSVData->maWinData.mpFirstFloat = mpNextFloat;
+ mpNextFloat = NULL;
+
+ ULONG nPopupModeFlags = mnPopupModeFlags;
+
+ // Wenn nicht abgerissen wurde, dann Fenster wieder Hiden
+ if ( !(nFlags & FLOATWIN_POPUPMODEEND_TEAROFF) ||
+ !(nPopupModeFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF) )
+ {
+ Show( FALSE, SHOW_NOFOCUSCHANGE );
+
+ // Focus evt. auf ein entsprechendes FloatingWindow weiterschalten
+ if ( nFocusId )
+ Window::EndSaveFocus( nFocusId );
+ else if ( pSVData->maWinData.mpFocusWin && pSVData->maWinData.mpFirstFloat &&
+ ImplIsWindowOrChild( pSVData->maWinData.mpFocusWin ) )
+ pSVData->maWinData.mpFirstFloat->GrabFocus();
+ mbPopupModeTearOff = FALSE;
+ }
+ else
+ {
+ mbPopupModeTearOff = TRUE;
+ if ( nFocusId )
+ Window::EndSaveFocus( nFocusId, FALSE );
+ }
+ EnableSaveBackground( mbOldSaveBackMode );
+
+ mbPopupModeCanceled = (nFlags & FLOATWIN_POPUPMODEEND_CANCEL) != 0;
+
+ // Gegebenenfalls den Title wieder herstellen
+ SetTitleType( mnOldTitle );
+
+ // ToolBox wieder auf normal schalten
+ if ( mpBox )
+ {
+ mpBox->ImplFloatControl( FALSE, this );
+ mpBox = NULL;
+ }
+
+ // Je nach Parameter den PopupModeEnd-Handler rufen
+ if ( !(nFlags & FLOATWIN_POPUPMODEEND_DONTCALLHDL) )
+ ImplCallPopupModeEnd();
+
+ // Je nach Parameter die restlichen Fenster auch noch schliessen
+ if ( nFlags & FLOATWIN_POPUPMODEEND_CLOSEALL )
+ {
+ if ( !(nPopupModeFlags & FLOATWIN_POPUPMODE_NEWLEVEL) )
+ {
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::EndPopupMode( USHORT nFlags )
+{
+ ImplEndPopupMode( nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::AddPopupModeWindow( Window* pWindow )
+{
+ // !!! bisher erst 1 Fenster und noch keine Liste
+ mpFirstPopupModeWin = pWindow;
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::RemovePopupModeWindow( Window* pWindow )
+{
+ // !!! bisher erst 1 Fenster und noch keine Liste
+ if ( mpFirstPopupModeWin == pWindow )
+ mpFirstPopupModeWin = NULL;
+}
+
diff --git a/vcl/source/window/keycod.cxx b/vcl/source/window/keycod.cxx
new file mode 100644
index 000000000000..34d5a997648e
--- /dev/null
+++ b/vcl/source/window/keycod.cxx
@@ -0,0 +1,276 @@
+/*************************************************************************
+ *
+ * $RCSfile: keycod.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_KEYCOD_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_KEYCOD_HXX
+#include <keycod.hxx>
+#endif
+
+#ifndef _RC_H
+#include <rc.h>
+#endif
+
+#ifdef REMOTE_APPSERVER
+#include <rmwindow.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+static USHORT aImplKeyFuncTab[(KEYFUNC_FRONT+1)*3] =
+{
+ 0, 0, 0, // KEYFUNC_DONTKNOW
+ KEY_N | KEY_MOD1, 0, 0, // KEYFUNC_NEW
+ KEY_O | KEY_MOD1, KEY_OPEN, 0, // KEYFUNC_OPEN
+ KEY_S | KEY_MOD1, 0, 0, // KEYFUNC_SAVE
+ 0, 0, 0, // KEYFUNC_SAVEAS
+ KEY_P | KEY_MOD1, 0, 0, // KEYFUNC_PRINT
+ KEY_W | KEY_MOD1, KEY_F4 | KEY_MOD1, 0, // KEYFUNC_CLOSE
+ KEY_Q | KEY_MOD1, KEY_F4 | KEY_MOD2, 0, // KEYFUNC_QUIT
+ KEY_X | KEY_MOD1, KEY_DELETE | KEY_SHIFT, KEY_CUT, // KEYFUNC_CUT
+ KEY_C | KEY_MOD1, KEY_INSERT | KEY_MOD1, KEY_COPY, // KEYFUNC_COPY
+ KEY_V | KEY_MOD1, KEY_INSERT | KEY_SHIFT, KEY_PASTE, // KEYFUNC_PASTE
+ KEY_Z | KEY_MOD1, KEY_BACKSPACE | KEY_MOD2, KEY_UNDO, // KEYFUNC_UNDO
+ 0, 0, 0, // KEYFUNC_REDO
+ KEY_DELETE, 0, 0, // KEYFUNC_DELETE
+ KEY_REPEAT, 0, 0, // KEYFUNC_REPEAT
+ KEY_F | KEY_MOD1, KEY_FIND, 0, // KEYFUNC_FIND
+ KEY_F | KEY_SHIFT | KEY_MOD1, KEY_SHIFT | KEY_FIND, 0, // KEYFUNC_FINDBACKWARD
+ KEY_RETURN | KEY_MOD2, 0, 0, // KEYFUNC_PROPERTIES
+ 0, 0, 0 // KEYFUNC_FRONT
+};
+
+// -----------------------------------------------------------------------
+
+void ImplGetKeyCode( KeyFuncType eFunc, USHORT& rCode1, USHORT& rCode2, USHORT& rCode3 )
+{
+ USHORT nIndex = (USHORT)eFunc;
+ nIndex *= 3;
+ rCode1 = aImplKeyFuncTab[nIndex];
+ rCode2 = aImplKeyFuncTab[nIndex+1];
+ rCode3 = aImplKeyFuncTab[nIndex+2];
+}
+
+// =======================================================================
+
+KeyCode::KeyCode( KeyFuncType eFunction )
+{
+ USHORT nDummy;
+ ImplGetKeyCode( eFunction, nCode, nDummy, nDummy );
+ eFunc = eFunction;
+}
+
+// -----------------------------------------------------------------------
+
+KeyCode::KeyCode( const ResId& rResId )
+{
+ rResId.SetRT( RSC_KEYCODE );
+
+ ResMgr* pResMgr = rResId.GetResMgr();
+ if ( !pResMgr )
+ pResMgr = Resource::GetResManager();
+
+ if ( pResMgr && pResMgr->GetResource( rResId ) )
+ {
+ pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
+
+ USHORT nKeyCode = pResMgr->ReadShort();
+ USHORT nModifier = pResMgr->ReadShort();
+ USHORT nKeyFunc = pResMgr->ReadShort();
+
+ eFunc = (KeyFuncType)nKeyFunc;
+ if ( eFunc != KEYFUNC_DONTKNOW )
+ {
+ USHORT nDummy;
+ ImplGetKeyCode( eFunc, nCode, nDummy, nDummy );
+ }
+ else
+ nCode = nKeyCode | nModifier;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString KeyCode::GetName( Window* pWindow ) const
+{
+ if ( !pWindow )
+ pWindow = ImplGetDefaultWindow();
+#ifndef REMOTE_APPSERVER
+ return pWindow->ImplGetFrame()->GetKeyName( GetFullCode() );
+#else
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->mpKeyNames )
+ {
+ pSVData->mpKeyNames = new KeyNames;
+ NMSP_CLIENT::KeyNameSequence aKeyNames;
+ pWindow->ImplGetFrame()->GetKeyNames( aKeyNames );
+ ULONG nNames = aKeyNames.getLength();
+ for ( USHORT n = 0; n < nNames; n++ )
+ {
+ const NMSP_CLIENT::IDLKeyNameInfo& rInfo = aKeyNames.getConstArray()[n];
+ pSVData->mpKeyNames->Insert( rInfo.nCode, new String( rInfo.aName ) );
+ }
+ }
+
+ String aName;
+ const int nMods = 3;
+ USHORT nKeyCode = GetFullCode();
+ USHORT aModifiers[nMods] = { KEY_MOD2, KEY_MOD1, KEY_SHIFT };
+ for ( USHORT n = 0; n < nMods; n++ )
+ {
+ USHORT nMod = aModifiers[n];
+ if ( nKeyCode & nMod )
+ {
+ String* pMod = pSVData->mpKeyNames->Get( nMod );
+ if ( pMod )
+ {
+ aName += *pMod;
+ aName += '+';
+ }
+ }
+ }
+
+ USHORT nCode = GetCode();
+ if ( (nCode >= KEY_0) && (nCode <= KEY_9) )
+ aName += (sal_Unicode)'0'+(nCode-KEY_0);
+ else if ( (nCode >= KEY_A) && (nCode <= KEY_Z) )
+ aName += (sal_Unicode)'A'+(nCode-KEY_A);
+ else if ( (nCode >= KEY_F1) && (nCode <= KEY_F9) )
+ {
+ aName += (sal_Unicode)'F';
+ aName += (sal_Unicode)'1' + (nCode-KEY_F1);
+ }
+ else if ( (nCode >= KEY_F10) && (nCode <= KEY_F19) )
+ {
+ aName += (sal_Unicode)'F';
+ aName += (sal_Unicode)'1';
+ aName += (sal_Unicode)'0' + (nCode-KEY_F10);
+ }
+ else if ( (nCode >= KEY_F20) && (nCode <= KEY_F26) )
+ {
+ aName += (sal_Unicode)'F';
+ aName += (sal_Unicode)'2';
+ aName += (sal_Unicode)'0' + (nCode-KEY_F20);
+ }
+ else
+ {
+ String* pName = pSVData->mpKeyNames->Get( GetFullCode() );
+ if ( pName )
+ aName += *pName;
+ }
+ return aName;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+XubString KeyCode::GetSymbolName( const XubString& rFontName, Window* pWindow ) const
+{
+#ifndef REMOTE_APPSERVER
+ if ( !pWindow )
+ pWindow = ImplGetDefaultWindow();
+ return pWindow->ImplGetFrame()->GetSymbolKeyName( rFontName, GetFullCode() );
+#else
+ return GetName( pWindow );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+KeyFuncType KeyCode::GetFunction() const
+{
+ if ( eFunc != KEYFUNC_DONTKNOW )
+ return eFunc;
+
+ USHORT nCompCode = GetModifier() | GetCode();
+ if ( nCompCode )
+ {
+ for ( USHORT i = (USHORT)KEYFUNC_NEW; i < (USHORT)KEYFUNC_FRONT; i++ )
+ {
+ USHORT nKeyCode1;
+ USHORT nKeyCode2;
+ USHORT nKeyCode3;
+ ImplGetKeyCode( (KeyFuncType)i, nKeyCode1, nKeyCode2, nKeyCode3 );
+ if ( (nCompCode == nKeyCode1) || (nCompCode == nKeyCode2) || (nCompCode == nKeyCode3) )
+ return (KeyFuncType)i;
+ }
+ }
+
+ return KEYFUNC_DONTKNOW;
+}
diff --git a/vcl/source/window/makefile.mk b/vcl/source/window/makefile.mk
new file mode 100644
index 000000000000..e65826da0a46
--- /dev/null
+++ b/vcl/source/window/makefile.mk
@@ -0,0 +1,139 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=vcl
+TARGET=win
+
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/accel.obj \
+ $(SLO)$/accmgr.obj \
+ $(SLO)$/brdwin.obj \
+ $(SLO)$/btndlg.obj \
+ $(SLO)$/cursor.obj \
+ $(SLO)$/dockwin.obj \
+ $(SLO)$/decoview.obj \
+ $(SLO)$/dialog.obj \
+ $(SLO)$/dlgctrl.obj \
+ $(SLO)$/filedlg.obj \
+ $(SLO)$/floatwin.obj \
+ $(SLO)$/keycod.obj \
+ $(SLO)$/menu.obj \
+ $(SLO)$/mnemonic.obj \
+ $(SLO)$/msgbox.obj \
+ $(SLO)$/seleng.obj \
+ $(SLO)$/split.obj \
+ $(SLO)$/splitwin.obj \
+ $(SLO)$/status.obj \
+ $(SLO)$/syschild.obj \
+ $(SLO)$/syswin.obj \
+ $(SLO)$/tabdlg.obj \
+ $(SLO)$/tabpage.obj \
+ $(SLO)$/toolbox.obj \
+ $(SLO)$/toolbox2.obj \
+ $(SLO)$/window.obj \
+ $(SLO)$/window2.obj \
+ $(SLO)$/winproc.obj \
+ $(SLO)$/wrkwin.obj \
+ $(SLO)$/scrwnd.obj
+
+.IF "$(remote)"!=""
+EXCEPTIONSFILES= \
+ $(SLO)$/brdwin.obj \
+ $(SLO)$/keycod.obj \
+ $(SLO)$/window.obj \
+ $(SLO)$/winproc.obj \
+ $(SLO)$/wrkwin.obj \
+ $(SLO)$/accel.obj \
+ $(SLO)$/cursor.obj \
+ $(SLO)$/dlgctrl.obj \
+ $(SLO)$/floatwin.obj \
+ $(SLO)$/menu.obj \
+ $(SLO)$/msgbox.obj \
+ $(SLO)$/split.obj \
+ $(SLO)$/status.obj \
+ $(SLO)$/syschild.obj \
+ $(SLO)$/syswin.obj \
+ $(SLO)$/tabpage.obj \
+ $(SLO)$/toolbox.obj \
+ $(SLO)$/toolbox2.obj \
+ $(SLO)$/dialog.obj
+.ELSE
+EXCEPTIONSFILES= \
+ $(SLO)$/window.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
new file mode 100644
index 000000000000..9df101095121
--- /dev/null
+++ b/vcl/source/window/menu.cxx
@@ -0,0 +1,3444 @@
+/*************************************************************************
+ *
+ * $RCSfile: menu.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_MENU_CXX
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_MNEMONIC_HXX
+#include <mnemonic.hxx>
+#endif
+#ifndef _SV_IMAGE_HXX
+#include <image.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+#ifndef _SV_FLOATWIN_HXX
+#include <floatwin.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_SOUND_HXX
+#include <sound.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_MENU_HXX
+#include <menu.hxx>
+#endif
+#ifndef _SV_BUTTON_HXX
+#include <button.hxx>
+#endif
+#ifndef _SV_GRADIENT_HXX
+#include <gradient.hxx>
+#endif
+#ifndef _SV_ACCESS_HXX
+#include <access.hxx>
+#endif
+
+#ifndef _ISOLANG_HXX
+#include <tools/isolang.hxx>
+#endif
+
+#pragma hdrstop
+
+#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
+#include <com/sun/star/uno/Reference.h>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_XCHARACTERCLASSIFICATION_HPP_
+#include <com/sun/star/lang/XCharacterClassification.hpp>
+#endif
+
+#include <unohelp.hxx>
+
+using namespace ::com::sun::star;
+
+DBG_NAME( Menu );
+
+#define ITEMPOS_INVALID 0xFFFF
+
+#define EXTRASPACEY 2
+#define EXTRAITEMHEIGHT 4
+
+DropEvent ImplTranslateDropEvent( const DropEvent& rE, Window* pSource, Window* pDest )
+{
+ Point aPos = pSource->OutputToScreenPixel( rE.GetPosPixel() );
+ aPos = pDest->ScreenToOutputPixel( aPos );
+ return DropEvent( aPos, rE.GetData(), rE.GetAction(), rE.GetSourceOptions(),
+ rE.GetWindowType(), rE.IsDefaultAction() );
+}
+
+inline BOOL ImplIsMouseFollow()
+{
+ return ( Application::GetSettings().GetMouseSettings().GetFollow() & MOUSE_FOLLOW_MENU ) ? TRUE : FALSE;
+}
+
+
+struct MenuItemData
+{
+ USHORT nId; // SV Id
+ MenuItemType eType; // MenuItem-Type
+ MenuItemBits nBits; // MenuItem-Bits
+ Menu* pSubMenu; // Pointer auf das SubMenu
+ Menu* pAutoSubMenu; // Pointer auf SubMenu aus Resource
+ XubString aText; // Menu-Text
+ XubString aHelpText; // Help-String
+ XubString aCommandStr; // CommandString
+ ULONG nHelpId; // Help-Id
+ Image aImage; // Image
+ KeyCode aAccelKey; // Accelerator-Key
+ BOOL bChecked; // Checked
+ BOOL bEnabled; // Enabled
+ BOOL bIsTemporary; // Temporary inserted ('No selection possible')
+
+ Size aSz; // nur temporaer gueltig
+
+ MenuItemData() {}
+ MenuItemData( const XubString& rStr, const Image& rImage ) :
+ aText( rStr ),
+ aImage( rImage )
+ {}
+ ~MenuItemData() { delete pAutoSubMenu; }
+};
+
+
+class MenuItemList : public List
+{
+ uno::Reference< lang::XCharacterClassification > xCharClass;
+public:
+ MenuItemList() : List( 16, 4 ) {}
+ ~MenuItemList();
+
+ MenuItemData* Insert( USHORT nId, MenuItemType eType, MenuItemBits nBits,
+ const XubString& rStr, const Image& rImage,
+ Menu* pMenu, USHORT nPos );
+ void InsertSeparator( USHORT nPos );
+ void Remove( USHORT nPos );
+
+
+ MenuItemData* GetData( USHORT nSVId, USHORT& rPos ) const;
+ MenuItemData* GetData( USHORT nSVId ) const
+ { USHORT nTemp; return GetData( nSVId, nTemp ); }
+ MenuItemData* GetDataFromPos( ULONG nPos ) const
+ { return (MenuItemData*)List::GetObject( nPos ); }
+
+ MenuItemData* SearchItem( xub_Unicode cSelectChar, USHORT& rPos ) const;
+ uno::Reference< lang::XCharacterClassification > GetCharClass() const;
+};
+
+
+
+MenuItemList::~MenuItemList()
+{
+ for ( ULONG n = Count(); n; )
+ {
+ MenuItemData* pData = GetDataFromPos( --n );
+ delete pData;
+ }
+}
+
+MenuItemData* MenuItemList::Insert( USHORT nId, MenuItemType eType,
+ MenuItemBits nBits,
+ const XubString& rStr, const Image& rImage,
+ Menu* pMenu, USHORT nPos )
+{
+ MenuItemData* pData = new MenuItemData( rStr, rImage );
+ pData->nId = nId;
+ pData->eType = eType;
+ pData->nBits = nBits;
+ pData->pSubMenu = NULL;
+ pData->pAutoSubMenu = NULL;
+ pData->nHelpId = 0;
+ pData->bChecked = FALSE;
+ pData->bEnabled = TRUE;
+ pData->bIsTemporary = FALSE;
+ List::Insert( (void*)pData, nPos );
+ return pData;
+}
+
+void MenuItemList::InsertSeparator( USHORT nPos )
+{
+ MenuItemData* pData = new MenuItemData;
+ pData->nId = 0;
+ pData->eType = MENUITEM_SEPARATOR;
+ pData->nBits = 0;
+ pData->pSubMenu = NULL;
+ pData->pAutoSubMenu = NULL;
+ pData->nHelpId = 0;
+ pData->bChecked = FALSE;
+ pData->bEnabled = TRUE;
+ pData->bIsTemporary = FALSE;
+ List::Insert( (void*)pData, nPos );
+}
+
+void MenuItemList::Remove( USHORT nPos )
+{
+ MenuItemData* pData = (MenuItemData*)List::Remove( (ULONG)nPos );
+ if ( pData )
+ delete pData;
+}
+
+MenuItemData* MenuItemList::GetData( USHORT nSVId, USHORT& rPos ) const
+{
+ rPos = 0;
+ MenuItemData* pData = (MenuItemData*)GetObject( rPos );
+ while ( pData )
+ {
+ if ( pData->nId == nSVId )
+ return pData;
+
+ rPos++;
+ pData = (MenuItemData*)GetObject( rPos );
+ }
+
+ return NULL;
+}
+
+MenuItemData* MenuItemList::SearchItem( xub_Unicode cSelectChar, USHORT& rPos ) const
+{
+ const ::com::sun::star::lang::Locale& rLocale = Application::GetSettings().GetLocale();
+ xub_Unicode cCharCode = GetCharClass()->toUpper( String(cSelectChar), 0, 1, rLocale )[0];
+ for ( rPos = (USHORT)Count(); rPos; )
+ {
+ MenuItemData* pData = GetDataFromPos( --rPos );
+ if ( pData->bEnabled )
+ {
+ USHORT n = pData->aText.Search( '~' );
+ if ( n != STRING_NOTFOUND )
+ {
+ xub_Unicode cCompareChar = pData->aText.GetChar( n+1 );
+ cCompareChar = GetCharClass()->toUpper( String(cCompareChar), 0, 1, rLocale )[0];
+ if ( cCompareChar == cCharCode )
+ return pData;
+ }
+ }
+ }
+
+ return 0;
+}
+
+uno::Reference< lang::XCharacterClassification > MenuItemList::GetCharClass() const
+{
+ if ( !xCharClass.is() )
+ ((MenuItemList*)this)->xCharClass = vcl::unohelper::CreateCharacterClassification();
+ return xCharClass;
+}
+
+
+
+class MenuFloatingWindow : public FloatingWindow
+{
+private:
+ Menu* pMenu;
+ PopupMenu* pActivePopup;
+ Timer aHighlightChangedTimer;
+ Timer aScrollTimer;
+ ULONG nSaveFocusId;
+ long nStartY;
+ USHORT nHighlightedItem; // gehighlightetes/selektiertes Item
+ USHORT nMBDownPos;
+ USHORT nScrollerHeight;
+ USHORT nFirstEntry;
+ USHORT nBorder;
+ BOOL bInExecute;
+
+ BOOL bScrollMenu;
+ BOOL bScrollUp;
+ BOOL bScrollDown;
+
+ DECL_LINK( PopupEnd, FloatingWindow* );
+ DECL_LINK( HighlightChanged, Timer* );
+ DECL_LINK( AutoScroll, Timer* );
+
+ void StateChanged( StateChangedType nType );
+ void DataChanged( const DataChangedEvent& rDCEvt );
+
+protected:
+ Region ImplCalcClipRegion( BOOL bIncludeLogo = TRUE ) const;
+ void ImplInitClipRegion();
+ void ImplDrawScroller( BOOL bUp );
+ void ImplScroll( const Point& rMousePos );
+ void ImplScroll( BOOL bUp );
+ void ImplCursorUpDown( BOOL bUp );
+ void ImplHighlightItem( const MouseEvent& rMEvt, BOOL bMBDown );
+
+public:
+ MenuFloatingWindow( Menu* pMenu, Window* pParent, WinBits nStyle );
+ ~MenuFloatingWindow();
+
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void KeyInput( const KeyEvent& rKEvent );
+ virtual void Command( const CommandEvent& rCEvt );
+ virtual void Paint( const Rectangle& rRect );
+ virtual void RequestHelp( const HelpEvent& rHEvt );
+ virtual void Resize();
+
+ void SetFocusId( ULONG nId ) { nSaveFocusId = nId; }
+ ULONG GetFocusId() const { return nSaveFocusId; }
+
+ void EnableScrollMenu( BOOL b );
+ BOOL IsScrollMenu() const { return bScrollMenu; }
+ USHORT GetScrollerHeight() const { return nScrollerHeight; }
+
+ void Execute();
+ void StopExecute( ULONG nFocusId = 0 );
+ void EndExecute();
+ void EndExecute( USHORT nSelectId );
+
+ PopupMenu* GetActivePopup() const { return pActivePopup; }
+ void KillActivePopup( PopupMenu* pThisOnly = NULL );
+
+ void HighlightItem( USHORT nPos, BOOL bHighlight );
+ void ChangeHighlightItem( USHORT n, BOOL bStartPopupTimer );
+};
+
+
+// Eine Basicklasse fuer beide (wegen pActivePopup, Timer, ...) waere nett,
+// aber dann musste eine 'Container'-Klasse gemacht werden, da von
+// unterschiedlichen Windows abgeleitet...
+// In den meisten Funktionen muessen dann sowieso Sonderbehandlungen fuer
+// MenuBar, PopupMenu gemacht werden, also doch zwei verschiedene Klassen.
+
+class MenuBarWindow : public Window
+{
+ friend class MenuBar;
+
+private:
+ Menu* pMenu;
+ PopupMenu* pActivePopup;
+ USHORT nHighlightedItem;
+ ULONG nSaveFocusId;
+ BOOL mbAutoPopup;
+
+ PushButton aCloser;
+ PushButton aFloatBtn;
+ PushButton aHideBtn;
+
+ void HighlightItem( USHORT nPos, BOOL bHighlight );
+ void ChangeHighlightItem( USHORT n, BOOL bSelectPopupEntry, BOOL bAllowRestoreFocus = TRUE );
+
+ USHORT ImplFindEntry( const Point& rMousePos ) const;
+ void ImplCreatePopup( BOOL bPreSelectFirst );
+ BOOL ImplHandleKeyEvent( const KeyEvent& rKEvent, BOOL bFromMenu = TRUE );
+
+ DECL_LINK( CloserHdl, PushButton* );
+ DECL_LINK( FloatHdl, PushButton* );
+ DECL_LINK( HideHdl, PushButton* );
+
+ void StateChanged( StateChangedType nType );
+ void DataChanged( const DataChangedEvent& rDCEvt );
+ void LoseFocus();
+
+public:
+ MenuBarWindow( Window* pParent );
+ ~MenuBarWindow();
+
+ void ShowButtons( BOOL bClose, BOOL bFloat, BOOL bHide );
+
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+ virtual void KeyInput( const KeyEvent& rKEvent );
+ virtual void Paint( const Rectangle& rRect );
+ virtual void Resize();
+ virtual void RequestHelp( const HelpEvent& rHEvt );
+ virtual BOOL QueryDrop( DropEvent& rDEvt );
+ virtual BOOL Drop( const DropEvent& rDEvt );
+
+ void SetFocusId( ULONG nId ) { nSaveFocusId = nId; }
+ ULONG GetFocusId() const { return nSaveFocusId; }
+
+ void SetMenu( MenuBar* pMenu );
+ void KillActivePopup();
+ PopupMenu* GetActivePopup() const { return pActivePopup; }
+ void PopupClosed( Menu* pMenu );
+};
+
+
+
+static void ImplSetMenuItemData( MenuItemData* pData, USHORT nPos )
+{
+ // Daten umsetzen
+ if ( !pData->aImage )
+ pData->eType = MENUITEM_STRING;
+ else if ( !pData->aText.Len() )
+ pData->eType = MENUITEM_IMAGE;
+ else
+ pData->eType = MENUITEM_STRINGIMAGE;
+}
+
+static BOOL ImplHandleHelpEvent( Window* pMenuWindow, Menu* pMenu, USHORT nHighlightedItem, const HelpEvent& rHEvt )
+{
+ BOOL bDone = FALSE;
+ USHORT nId = 0;
+ if ( nHighlightedItem != ITEMPOS_INVALID )
+ {
+ MenuItemData* pItemData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
+ if ( pItemData )
+ nId = pItemData->nId;
+ }
+
+ if ( ( rHEvt.GetMode() & HELPMODE_BALLOON ) && pMenuWindow )
+ {
+ Point aPos = rHEvt.GetMousePosPixel();
+ // Pos etwas nach unter-rechts korrigieren, wegen Pointer
+ aPos.X() += 15;
+// aPos.Y() += 20;
+ Help::ShowBalloon( pMenuWindow, aPos, pMenu->GetHelpText( nId ) );
+ bDone = TRUE;
+ }
+ else if ( rHEvt.GetMode() & (HELPMODE_CONTEXT | HELPMODE_EXTENDED) )
+ {
+ // Ist eine Hilfe in die Applikation selektiert
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ {
+ // Ist eine ID vorhanden, dann Hilfe mit der ID aufrufen, sonst
+ // den Hilfe-Index
+ ULONG nHelpId = pMenu->GetHelpId( nId );
+ if ( nHelpId )
+ pHelp->Start( nHelpId );
+ else
+ pHelp->Start( HELP_INDEX );
+ }
+ bDone = TRUE;
+ }
+ return bDone;
+}
+
+
+Menu::Menu()
+{
+ DBG_CTOR( Menu, NULL );
+ ImplInit();
+}
+
+Menu::~Menu()
+{
+ DBG_DTOR( Menu, NULL );
+
+ if ( nEventId )
+ Application::RemoveUserEvent( nEventId );
+
+ bKilled = TRUE;
+
+ delete pItemList;
+ delete pLogo;
+}
+
+void Menu::ImplInit()
+{
+ nMenuFlags = 0;
+ nDefaultItem = 0;
+ bIsMenuBar = FALSE;
+ nSelectedId = 0;
+ pItemList = new MenuItemList;
+ pLogo = NULL;
+ pStartedFrom = NULL;
+ pWindow = NULL;
+ nEventId = 0;
+ bCanceled = FALSE;
+ bInCallback = FALSE;
+ bKilled = FALSE;
+}
+
+void Menu::ImplLoadRes( const ResId& rResId )
+{
+ rResId.SetRT( RSC_MENU );
+ GetRes( rResId );
+
+ USHORT nObjMask = ReadShortRes();
+
+ if( nObjMask & RSC_MENU_ITEMS )
+ {
+ USHORT nObjFollows = ReadShortRes();
+ // MenuItems einfuegen
+ for( USHORT i = 0; i < nObjFollows; i++ )
+ {
+ InsertItem( ResId( (RSHEADER_TYPE*)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+ }
+
+ if( nObjMask & RSC_MENU_TEXT )
+ {
+ if( bIsMenuBar ) // Kein Titel im Menubar
+ ReadStringRes();
+ else
+ aTitleText = ReadStringRes();
+ }
+ if( nObjMask & RSC_MENU_DEFAULTITEMID )
+ SetDefaultItem( ReadShortRes() );
+}
+
+void Menu::Activate()
+{
+ bInCallback = TRUE;
+ if ( !aActivateHdl.Call( this ) )
+ {
+ Menu* pStartMenu = ImplGetStartMenu();
+ if ( pStartMenu && ( pStartMenu != this ) )
+ {
+ pStartMenu->bInCallback = TRUE;
+ pStartMenu->aActivateHdl.Call( this );
+ pStartMenu->bInCallback = FALSE;
+ }
+ }
+ bInCallback = FALSE;
+}
+
+void Menu::Deactivate()
+{
+ for ( USHORT n = pItemList->Count(); n; )
+ {
+ MenuItemData* pData = pItemList->GetDataFromPos( --n );
+ if ( pData->bIsTemporary )
+ pItemList->Remove( n );
+ }
+
+ bInCallback = TRUE;
+ Menu* pStartMenu = ImplGetStartMenu();
+ if ( !aDeactivateHdl.Call( this ) )
+ {
+ if ( pStartMenu && ( pStartMenu != this ) )
+ {
+ pStartMenu->bInCallback = TRUE;
+ pStartMenu->aDeactivateHdl.Call( this );
+ pStartMenu->bInCallback = FALSE;
+ }
+ }
+ bInCallback = FALSE;
+
+ if ( this == pStartMenu )
+ GetpApp()->HideHelpStatusText();
+}
+
+void Menu::Highlight()
+{
+ Menu* pStartMenu = ImplGetStartMenu();
+ if ( !aHighlightHdl.Call( this ) )
+ {
+ if ( pStartMenu && ( pStartMenu != this ) )
+ pStartMenu->aHighlightHdl.Call( this );
+ }
+
+ if ( GetCurItemId() )
+ GetpApp()->ShowHelpStatusText( GetHelpText( GetCurItemId() ) );
+}
+
+void Menu::ImplSelect()
+{
+ MenuItemData* pData = GetItemList()->GetData( nSelectedId );
+ if ( pData && (pData->nBits & MIB_AUTOCHECK) )
+ {
+ BOOL bChecked = IsItemChecked( nSelectedId );
+ if ( pData->nBits & MIB_RADIOCHECK )
+ {
+ if ( !bChecked )
+ CheckItem( nSelectedId, TRUE );
+ }
+ else
+ CheckItem( nSelectedId, !bChecked );
+ }
+
+ // Select rufen
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->maAppData.mpActivePopupMenu = NULL; // Falls neues Execute im Select()
+ Application::PostUserEvent( nEventId, LINK( this, Menu, ImplCallSelect ) );
+}
+
+void Menu::Select()
+{
+ if ( !aSelectHdl.Call( this ) )
+ {
+ Menu* pStartMenu = ImplGetStartMenu();
+ if ( pStartMenu && ( pStartMenu != this ) )
+ {
+ pStartMenu->nSelectedId = nSelectedId;
+ pStartMenu->aSelectHdl.Call( this );
+ }
+ }
+}
+
+void Menu::RequestHelp( const HelpEvent& rHEvt )
+{
+}
+
+void Menu::InsertItem( USHORT nItemId, const XubString& rStr, MenuItemBits nItemBits, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "Menu::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == MENU_ITEM_NOTFOUND,
+ "Menu::InsertItem(): ItemId already exists" );
+
+ // Falls Position > ItemCount, dann anheangen
+ if ( nPos >= (USHORT)pItemList->Count() )
+ nPos = MENU_APPEND;
+
+ // Item in die MenuItemListe aufnehmen
+ MenuItemData* pData = pItemList->Insert( nItemId, MENUITEM_STRING,
+ nItemBits, rStr, Image(), this, nPos );
+
+ Window* pWin = ImplGetWindow();
+ if ( pWin )
+ {
+ ImplCalcSize( pWin );
+ if ( pWin->IsVisible() )
+ pWin->Invalidate();
+ }
+}
+
+void Menu::InsertItem( USHORT nItemId, const Image& rImage,
+ MenuItemBits nItemBits, USHORT nPos )
+{
+ InsertItem( nItemId, ImplGetSVEmptyStr(), nItemBits, nPos );
+ SetItemImage( nItemId, rImage );
+}
+
+void Menu::InsertItem( USHORT nItemId,
+ const XubString& rStr, const Image& rImage,
+ MenuItemBits nItemBits, USHORT nPos )
+{
+ InsertItem( nItemId, rStr, nItemBits, nPos );
+ SetItemImage( nItemId, rImage );
+}
+
+void Menu::InsertItem( const ResId& rResId, USHORT nPos )
+{
+ USHORT nObjMask;
+
+ GetRes( rResId.SetRT( RSC_MENUITEM ) );
+ nObjMask = ReadShortRes();
+
+ BOOL bSep = FALSE;
+ if ( nObjMask & RSC_MENUITEM_SEPARATOR )
+ bSep = (BOOL)ReadShortRes();
+
+ USHORT nItemId = 1;
+ if ( nObjMask & RSC_MENUITEM_ID )
+ nItemId = ReadShortRes();
+
+ USHORT nStatus = 0;
+ if ( nObjMask & RSC_MENUITEM_STATUS )
+ nStatus = ReadShortRes();
+
+ String aText;
+ if ( nObjMask & RSC_MENUITEM_TEXT )
+ aText = ReadStringRes();
+
+ // Item erzeugen
+ if ( nObjMask & RSC_MENUITEM_BITMAP )
+ {
+ if ( !bSep )
+ {
+ Bitmap aBmp( ResId( (RSHEADER_TYPE*)GetClassRes() ) );
+ if ( aText.Len() )
+ InsertItem( nItemId, aText, aBmp, nStatus, nPos );
+ else
+ InsertItem( nItemId, aBmp, nStatus, nPos );
+ }
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+ else if ( !bSep )
+ InsertItem( nItemId, aText, nStatus, nPos );
+ if ( bSep )
+ InsertSeparator( nPos );
+
+ String aHelpText;
+ if ( nObjMask & RSC_MENUITEM_HELPTEXT )
+ {
+ aHelpText = ReadStringRes();
+ if( !bSep )
+ SetHelpText( nItemId, aHelpText );
+ }
+
+ ULONG nHelpId = 0;
+ if ( nObjMask & RSC_MENUITEM_HELPID )
+ {
+ nHelpId = ReadLongRes();
+ if ( !bSep )
+ SetHelpId( nItemId, nHelpId );
+ }
+
+ if( !bSep /* && SvHelpSettings::HelpText( aHelpText, nHelpId ) */ )
+ SetHelpText( nItemId, aHelpText );
+
+ if ( nObjMask & RSC_MENUITEM_KEYCODE )
+ {
+ if ( !bSep )
+ SetAccelKey( nItemId, KeyCode( ResId( (RSHEADER_TYPE*)GetClassRes() ) ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+ if( nObjMask & RSC_MENUITEM_CHECKED )
+ {
+ if ( !bSep )
+ CheckItem( nItemId, (BOOL)ReadShortRes() );
+ }
+ if ( nObjMask & RSC_MENUITEM_DISABLE )
+ {
+ if ( !bSep )
+ EnableItem( nItemId, !(BOOL)ReadShortRes() );
+ }
+ if ( nObjMask & RSC_MENUITEM_COMMAND )
+ {
+ String aCommandStr = ReadStringRes();
+ if ( !bSep )
+ SetItemCommand( nItemId, aCommandStr );
+ }
+ if ( nObjMask & RSC_MENUITEM_MENU )
+ {
+ if ( !bSep )
+ {
+ MenuItemData* pData = GetItemList()->GetData( nItemId );
+ if ( pData )
+ {
+ PopupMenu* pSubMenu = new PopupMenu( ResId( (RSHEADER_TYPE*)GetClassRes() ) );
+ pData->pAutoSubMenu = pSubMenu;
+ SetPopupMenu( nItemId, pSubMenu );
+ }
+ }
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+}
+
+void Menu::InsertSeparator( USHORT nPos )
+{
+ // Handelt es sich um einen MenuBar, dann mache nichts
+ if ( bIsMenuBar )
+ return;
+
+ // Falls Position > ItemCount, dann anheangen
+ if ( nPos >= (USHORT)pItemList->Count() )
+ nPos = MENU_APPEND;
+
+ // Separator in die Item-Liste einfuegen
+ pItemList->InsertSeparator( nPos );
+}
+
+void Menu::RemoveItem( USHORT nPos )
+{
+ if ( nPos < GetItemCount() )
+ pItemList->Remove( nPos );
+
+ Window* pWin = ImplGetWindow();
+ if ( pWin )
+ {
+ ImplCalcSize( pWin );
+ if ( pWin->IsVisible() )
+ pWin->Invalidate();
+ }
+}
+
+void ImplCopyItem( Menu* pThis, const Menu& rMenu, USHORT nPos, USHORT nNewPos,
+ USHORT nMode = 0 )
+{
+ MenuItemType eType = rMenu.GetItemType( nPos );
+
+ if ( eType == MENUITEM_DONTKNOW )
+ return;
+
+ if ( eType == MENUITEM_SEPARATOR )
+ pThis->InsertSeparator( nNewPos );
+ else
+ {
+ USHORT nId = rMenu.GetItemId( nPos );
+
+ DBG_ASSERT( pThis->GetItemPos( nId ) == MENU_ITEM_NOTFOUND,
+ "Menu::CopyItem(): ItemId already exists" );
+
+ MenuItemData* pData = rMenu.GetItemList()->GetData( nId );
+
+ if ( eType == MENUITEM_STRINGIMAGE )
+ pThis->InsertItem( nId, pData->aText, pData->aImage, pData->nBits, nNewPos );
+ else if ( eType == MENUITEM_STRING )
+ pThis->InsertItem( nId, pData->aText, pData->nBits, nNewPos );
+ else
+ pThis->InsertItem( nId, pData->aImage, pData->nBits, nNewPos );
+
+ if ( rMenu.IsItemChecked( nId ) )
+ pThis->CheckItem( nId, TRUE );
+ if ( !rMenu.IsItemEnabled( nId ) )
+ pThis->EnableItem( nId, FALSE );
+ pThis->SetHelpId( nId, pData->nHelpId );
+ pThis->SetHelpText( nId, pData->aHelpText );
+ pThis->SetAccelKey( nId, pData->aAccelKey );
+
+ PopupMenu* pSubMenu = rMenu.GetPopupMenu( nId );
+ if ( pSubMenu )
+ {
+ // AutoKopie anlegen
+ if ( nMode == 1 )
+ {
+ PopupMenu* pNewMenu = new PopupMenu( *pSubMenu );
+ pThis->SetPopupMenu( nId, pNewMenu );
+// SetAutoMenu( pThis, nId, pNewMenu );
+ }
+ else
+ pThis->SetPopupMenu( nId, pSubMenu );
+ }
+ }
+}
+
+void Menu::CopyItem( const Menu& rMenu, USHORT nPos, USHORT nNewPos )
+{
+ ImplCopyItem( this, rMenu, nPos, nNewPos );
+}
+
+void Menu::Clear()
+{
+ for ( USHORT i = GetItemCount(); i; i-- )
+ RemoveItem( 0 );
+}
+
+USHORT Menu::GetItemCount() const
+{
+ return (USHORT)pItemList->Count();
+}
+
+USHORT Menu::ImplGetVisibleItemCount() const
+{
+ USHORT nItems = 0;
+ for ( USHORT n = (USHORT)pItemList->Count(); n; )
+ {
+ if ( ImplIsVisible( --n ) )
+ nItems++;
+ }
+ return nItems;
+}
+
+USHORT Menu::GetItemId( USHORT nPos ) const
+{
+ MenuItemData* pData = pItemList->GetDataFromPos( nPos );
+
+ if ( pData )
+ return pData->nId;
+ else
+ return 0;
+}
+
+USHORT Menu::GetItemPos( USHORT nItemId ) const
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ if ( pData )
+ return nPos;
+ else
+ return MENU_ITEM_NOTFOUND;
+}
+
+MenuItemType Menu::GetItemType( USHORT nPos ) const
+{
+ MenuItemData* pData = pItemList->GetDataFromPos( nPos );
+
+ if ( pData )
+ return pData->eType;
+ else
+ return MENUITEM_DONTKNOW;
+}
+
+USHORT Menu::GetCurItemId() const
+{
+ return nSelectedId;
+}
+
+void Menu::SetItemBits( USHORT nItemId, MenuItemBits nBits )
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+ if ( pData )
+ pData->nBits = nBits;
+}
+
+MenuItemBits Menu::GetItemBits( USHORT nItemId ) const
+{
+ MenuItemBits nBits = 0;
+ MenuItemData* pData = pItemList->GetData( nItemId );
+ if ( pData )
+ nBits = pData->nBits;
+ return nBits;
+}
+
+void Menu::SetPopupMenu( USHORT nItemId, PopupMenu* pMenu )
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ // Item nicht vorhanden, dann NULL zurueckgeben
+ if ( !pData )
+ return;
+
+ // Gleiches Menu, danmn brauchen wir nichts machen
+ if ( (PopupMenu*)pData->pSubMenu == pMenu )
+ return;
+
+ // Daten austauschen
+ pData->pSubMenu = pMenu;
+}
+
+PopupMenu* Menu::GetPopupMenu( USHORT nItemId ) const
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+
+ if ( pData )
+ return (PopupMenu*)(pData->pSubMenu);
+ else
+ return NULL;
+}
+
+void Menu::SetAccelKey( USHORT nItemId, const KeyCode& rKeyCode )
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ if ( !pData )
+ return;
+
+ if ( pData->aAccelKey == rKeyCode )
+ return;
+
+ pData->aAccelKey = rKeyCode;
+}
+
+KeyCode Menu::GetAccelKey( USHORT nItemId ) const
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+
+ if ( pData )
+ return pData->aAccelKey;
+ else
+ return KeyCode();
+}
+
+void Menu::CheckItem( USHORT nItemId, BOOL bCheck )
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ if ( !pData )
+ return;
+
+ // Wenn RadioCheck, dann vorherigen unchecken
+ if ( bCheck && (pData->nBits & MIB_AUTOCHECK) &&
+ (pData->nBits & MIB_RADIOCHECK) )
+ {
+ MenuItemData* pGroupData;
+ USHORT nGroupPos;
+ USHORT nItemCount = GetItemCount();
+ BOOL bFound = FALSE;
+
+ nGroupPos = nPos;
+ while ( nGroupPos )
+ {
+ pGroupData = pItemList->GetDataFromPos( nGroupPos-1 );
+ if ( pGroupData->nBits & MIB_RADIOCHECK )
+ {
+ if ( IsItemChecked( pGroupData->nId ) )
+ {
+ CheckItem( pGroupData->nId, FALSE );
+ bFound = TRUE;
+ break;
+ }
+ }
+ else
+ break;
+ nGroupPos--;
+ }
+
+ if ( !bFound )
+ {
+ nGroupPos = nPos+1;
+ while ( nGroupPos < nItemCount )
+ {
+ pGroupData = pItemList->GetDataFromPos( nGroupPos );
+ if ( pGroupData->nBits & MIB_RADIOCHECK )
+ {
+ if ( IsItemChecked( pGroupData->nId ) )
+ {
+ CheckItem( pGroupData->nId, FALSE );
+ break;
+ }
+ }
+ else
+ break;
+ nGroupPos++;
+ }
+ }
+ }
+
+ pData->bChecked = bCheck;
+}
+
+BOOL Menu::IsItemChecked( USHORT nItemId ) const
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ if ( !pData )
+ return FALSE;
+
+ return pData->bChecked;
+}
+
+void Menu::EnableItem( USHORT nItemId, BOOL bEnable )
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ if ( pData && ( pData->bEnabled != bEnable ) )
+ {
+ pData->bEnabled = bEnable;
+
+ Window* pWin = ImplGetWindow();
+ if ( pWin && pWin->IsVisible() )
+ {
+ DBG_ASSERT( bIsMenuBar, "Menu::EnableItem - Popup visible!" );
+ long nX = 0;
+ ULONG nCount = pItemList->Count();
+ for ( ULONG n = 0; n < nCount; n++ )
+ {
+ MenuItemData* pData = pItemList->GetDataFromPos( n );
+ if ( n == nPos )
+ {
+ pWin->Invalidate( Rectangle( Point( nX, 0 ), Size( pData->aSz.Width(), pData->aSz.Height() ) ) );
+ break;
+ }
+ nX += pData->aSz.Width();
+ }
+ }
+ }
+}
+
+BOOL Menu::IsItemEnabled( USHORT nItemId ) const
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ if ( !pData )
+ return FALSE;
+
+ return pData->bEnabled;
+}
+
+void Menu::SetItemText( USHORT nItemId, const XubString& rStr )
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ if ( !pData )
+ return;
+
+ pData->aText = rStr;
+ ImplSetMenuItemData( pData, nPos );
+}
+
+XubString Menu::GetItemText( USHORT nItemId ) const
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ if ( pData )
+ return pData->aText;
+ else
+ return ImplGetSVEmptyStr();
+}
+
+void Menu::SetItemImage( USHORT nItemId, const Image& rImage )
+{
+ USHORT nPos;
+ MenuItemData* pData = pItemList->GetData( nItemId, nPos );
+
+ if ( !pData )
+ return;
+
+ pData->aImage = rImage;
+ ImplSetMenuItemData( pData, nPos );
+}
+
+Image Menu::GetItemImage( USHORT nItemId ) const
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+
+ if ( pData )
+ return pData->aImage;
+ else
+ return Image();
+}
+
+void Menu::SetItemCommand( USHORT nItemId, const String& rCommand )
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+
+ if ( pData )
+ pData->aCommandStr = rCommand;
+}
+
+const XubString& Menu::GetItemCommand( USHORT nItemId ) const
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+
+ if ( pData )
+ return pData->aCommandStr;
+ else
+ return ImplGetSVEmptyStr();
+}
+
+void Menu::SetHelpText( USHORT nItemId, const XubString& rStr )
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+
+ if ( pData )
+ pData->aHelpText = rStr;
+}
+
+const XubString& Menu::GetHelpText( USHORT nItemId ) const
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+
+ if ( pData )
+ {
+ if ( !pData->aHelpText.Len() && pData->nHelpId )
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pData->aHelpText = pHelp->GetHelpText( pData->nHelpId );
+ }
+
+ return pData->aHelpText;
+ }
+ else
+ return ImplGetSVEmptyStr();
+}
+
+void Menu::SetHelpId( USHORT nItemId, ULONG nHelpId )
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+
+ if ( pData )
+ pData->nHelpId = nHelpId;
+}
+
+ULONG Menu::GetHelpId( USHORT nItemId ) const
+{
+ MenuItemData* pData = pItemList->GetData( nItemId );
+
+ if ( pData )
+ return pData->nHelpId;
+ else
+ return 0;
+}
+
+Menu& Menu::operator=( const Menu& rMenu )
+{
+ // Aufraeumen
+ Clear();
+
+ // Items kopieren
+ USHORT nCount = rMenu.GetItemCount();
+ for ( USHORT i = 0; i < nCount; i++ )
+ ImplCopyItem( this, rMenu, i, MENU_APPEND, 1 );
+
+ nDefaultItem = rMenu.nDefaultItem;
+ aActivateHdl = rMenu.aActivateHdl;
+ aDeactivateHdl = rMenu.aDeactivateHdl;
+ aHighlightHdl = rMenu.aHighlightHdl;
+ aSelectHdl = rMenu.aSelectHdl;
+ aTitleText = rMenu.aTitleText;
+ bIsMenuBar = rMenu.bIsMenuBar;
+
+ return *this;
+}
+
+BOOL Menu::ImplIsVisible( USHORT nPos ) const
+{
+ BOOL bVisible = TRUE;
+
+ // Fuer den Menubar nicht erlaubt, weil ich nicht mitbekomme
+ // ob dadurch ein Eintrag verschwindet oder wieder da ist.
+ if ( !bIsMenuBar && ( nMenuFlags & MENU_FLAG_HIDEDISABLEDENTRIES ) )
+ {
+ MenuItemData* pData = pItemList->GetDataFromPos( nPos );
+ if ( pData->eType != MENUITEM_SEPARATOR )
+ {
+ // bVisible = pData->bEnabled && ( !pData->pSubMenu || pData->pSubMenu->HasValidEntries( TRUE ) );
+ bVisible = pData->bEnabled; // SubMenus nicht pruefen, weil sie ggf. erst im Activate() gefuellt werden.
+ }
+ else
+ {
+ // Ein Separator ist nur dann visible, wenn davor sichtbare Eintraege stehen.
+ USHORT nCount = (USHORT) pItemList->Count();
+ USHORT n;
+ BOOL bPrevVisible = FALSE;
+ BOOL bNextVisible = FALSE;
+ for ( n = nPos; !bPrevVisible && n; )
+ {
+ pData = pItemList->GetDataFromPos( --n );
+ if ( pData->eType != MENUITEM_SEPARATOR )
+ bPrevVisible = pData->bEnabled; // && ( !pData->pSubMenu || pData->pSubMenu->HasValidEntries( TRUE ) );
+ else
+ break;
+ }
+ if ( bPrevVisible )
+ {
+ for ( n = nPos+1; !bNextVisible && ( n < nCount ); n++ )
+ {
+ pData = pItemList->GetDataFromPos( n );
+ if ( pData->eType != MENUITEM_SEPARATOR )
+ bNextVisible = pData->bEnabled; // && ( !pData->pSubMenu || pData->pSubMenu->HasValidEntries( TRUE ) );
+ // nicht beim naechsten Separator abbrechen...
+ }
+ }
+ bVisible = bPrevVisible && bNextVisible;
+ }
+ }
+
+ return bVisible;
+}
+
+Size Menu::ImplCalcSize( Window* pWin )
+{
+ // | Checked| Image| Text| Accel/Popup|
+
+ // Fuer Symbole: nFontHeight x nFontHeight
+ long nFontHeight = pWin->GetTextHeight();
+ long nExtra = nFontHeight/4;
+
+ Size aSz;
+ Size aMaxImgSz;
+ long nMaxTextWidth = 0;
+ long nMaxAccWidth = 0;
+
+ for ( USHORT n = (USHORT)pItemList->Count(); n; )
+ {
+ MenuItemData* pData = pItemList->GetDataFromPos( --n );
+
+ pData->aSz.Height() = 0;
+ pData->aSz.Width() = 0;
+
+ if ( ImplIsVisible( n ) )
+ {
+
+ // Separator
+ if ( !bIsMenuBar && ( pData->eType == MENUITEM_SEPARATOR ) )
+ {
+ DBG_ASSERT( !bIsMenuBar, "Separator in MenuBar ?! " );
+ pData->aSz.Height() = 4;
+ }
+
+ // Image:
+ if ( !bIsMenuBar && ( ( pData->eType == MENUITEM_IMAGE ) || ( pData->eType == MENUITEM_STRINGIMAGE ) ) )
+ {
+ Size aImgSz = pData->aImage.GetSizePixel();
+ if ( aImgSz.Width() > aMaxImgSz.Width() )
+ aMaxImgSz.Width() = aImgSz.Width();
+ if ( aImgSz.Height() > aMaxImgSz.Height() )
+ aMaxImgSz.Height() = aImgSz.Height();
+ if ( aImgSz.Height() > pData->aSz.Height() )
+ pData->aSz.Height() = aImgSz.Height();
+ }
+
+ // Text:
+ if ( (pData->eType == MENUITEM_STRING) || (pData->eType == MENUITEM_STRINGIMAGE) )
+ {
+ long nTextWidth = pWin->GetCtrlTextWidth( pData->aText );
+ if ( nTextWidth > nMaxTextWidth )
+ nMaxTextWidth = nTextWidth;
+ long nTextHeight = pWin->GetTextHeight();
+ if ( nTextHeight > pData->aSz.Height() )
+ pData->aSz.Height() = nTextHeight;
+
+ if ( bIsMenuBar )
+ {
+ pData->aSz.Width() = nTextWidth + 4*nExtra;
+ aSz.Width() += pData->aSz.Width();
+ }
+ }
+
+ // Accel
+ if ( !bIsMenuBar && pData->aAccelKey.GetCode() )
+ {
+ String aName = pData->aAccelKey.GetName();
+ long nAccWidth = pWin->GetTextWidth( aName );
+ nAccWidth += nExtra;
+ if ( nAccWidth > nMaxAccWidth )
+ nMaxAccWidth = nAccWidth;
+ }
+
+ // SubMenu?
+ if ( !bIsMenuBar && pData->pSubMenu )
+ {
+ if ( nFontHeight > nMaxAccWidth )
+ nMaxAccWidth = nFontHeight;
+ if ( nFontHeight > pData->aSz.Height() )
+ pData->aSz.Height() = nFontHeight;
+ }
+
+ pData->aSz.Height() += EXTRAITEMHEIGHT; // Etwas mehr Abstand:
+
+ if ( !bIsMenuBar )
+ aSz.Height() += (long)pData->aSz.Height();
+ }
+ }
+
+ if ( !bIsMenuBar )
+ {
+ nCheckPos = (USHORT)nExtra;
+ nImagePos = (USHORT)(nCheckPos + nFontHeight/2 + nExtra );
+ nTextPos = (USHORT)(nImagePos+aMaxImgSz.Width());
+ if ( aMaxImgSz.Width() )
+ nTextPos += (USHORT)nExtra;
+
+ aSz.Width() = nTextPos + nMaxTextWidth + nExtra + nMaxAccWidth;
+ aSz.Width() += 10*nExtra; // etwas mehr...
+ }
+ else
+ {
+ nTextPos = (USHORT)(2*nExtra);
+ aSz.Height() = nFontHeight+6;
+ }
+
+ if ( pLogo )
+ aSz.Width() += pLogo->aBitmap.GetSizePixel().Width();
+
+ return aSz;
+}
+
+void Menu::ImplPaint( Window* pWin, USHORT nBorder, long nStartY, MenuItemData* pThisItemOnly, BOOL bHighlighted )
+{
+ // Fuer Symbole: nFontHeight x nFontHeight
+ long nFontHeight = pWin->GetTextHeight();
+ long nExtra = nFontHeight/4;
+
+ DecorationView aDecoView( pWin );
+ const StyleSettings& rSettings = pWin->GetSettings().GetStyleSettings();
+
+ Point aTopLeft, aTmpPos;
+
+ if ( pLogo )
+ aTopLeft.X() = pLogo->aBitmap.GetSizePixel().Width();
+
+ Size aOutSz = pWin->GetOutputSizePixel();
+ long nMaxY = aOutSz.Height() - nBorder;
+ USHORT nCount = (USHORT)pItemList->Count();
+ for ( USHORT n = 0; n < nCount; n++ )
+ {
+ MenuItemData* pData = pItemList->GetDataFromPos( n );
+ if ( ImplIsVisible( n ) && ( !pThisItemOnly || ( pData == pThisItemOnly ) ) )
+ {
+ if ( pThisItemOnly && bHighlighted )
+ pWin->SetTextColor( rSettings.GetMenuHighlightTextColor() );
+
+ Point aPos( aTopLeft );
+ aPos.Y() += nBorder;
+ aPos.Y() += nStartY;
+
+ if ( aPos.Y() >= 0 )
+ {
+ long nTextOffsetY = ((pData->aSz.Height()-nFontHeight)/2);
+ USHORT nTextStyle = 0;
+ USHORT nSymbolStyle = 0;
+ USHORT nImageStyle = 0;
+ // SubMenus ohne Items werden nicht mehr disablte dargestellt,
+ // wenn keine Items enthalten sind, da die Anwendung selber
+ // darauf achten muss. Ansonsten gibt es Faelle, wo beim
+ // asyncronen laden die Eintraege disablte dargestellt werden.
+ if ( !pData->bEnabled )
+ {
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ nSymbolStyle |= SYMBOL_DRAW_DISABLE;
+ nImageStyle |= IMAGE_DRAW_DISABLE;
+ }
+
+ // Separator
+ if ( !bIsMenuBar && ( pData->eType == MENUITEM_SEPARATOR ) )
+ {
+ aTmpPos.Y() = aPos.Y() + ((pData->aSz.Height()-2)/2);
+ aTmpPos.X() = aPos.X() + 1;
+ pWin->SetLineColor( rSettings.GetShadowColor() );
+ pWin->DrawLine( aTmpPos, Point( aOutSz.Width() - 1, aTmpPos.Y() ) );
+ aTmpPos.Y()++;
+ pWin->SetLineColor( rSettings.GetLightColor() );
+ pWin->DrawLine( aTmpPos, Point( aOutSz.Width() - 1, aTmpPos.Y() ) );
+ pWin->SetLineColor();
+ }
+
+ // Image:
+ if ( !bIsMenuBar && ( ( pData->eType == MENUITEM_IMAGE ) || ( pData->eType == MENUITEM_STRINGIMAGE ) ) )
+ {
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.X() = aPos.X() + nImagePos;
+ aTmpPos.Y() += (pData->aSz.Height()-pData->aImage.GetSizePixel().Height())/2;
+ pWin->DrawImage( aTmpPos, pData->aImage, nImageStyle );
+ }
+
+ // Text:
+ if ( ( pData->eType == MENUITEM_STRING ) || ( pData->eType == MENUITEM_STRINGIMAGE ) )
+ {
+ aTmpPos.X() = aPos.X() + nTextPos;
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nTextOffsetY;
+ USHORT nStyle = nTextStyle|TEXT_DRAW_MNEMONIC;
+ if ( pData->bIsTemporary )
+ nStyle |= TEXT_DRAW_DISABLE;
+ pWin->DrawCtrlText( aTmpPos, pData->aText, 0, pData->aText.Len(), nStyle );
+ }
+
+ // Accel
+ if ( !bIsMenuBar && pData->aAccelKey.GetCode() )
+ {
+ XubString aAccText = pData->aAccelKey.GetName();
+ aTmpPos.X() = aOutSz.Width() - pWin->GetTextWidth( aAccText );
+ aTmpPos.X() -= 3*nExtra;
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nTextOffsetY;
+ pWin->DrawCtrlText( aTmpPos, aAccText, 0, aAccText.Len(), nTextStyle );
+ }
+
+ // CheckMark
+ if ( !bIsMenuBar && pData->bChecked )
+ {
+ Rectangle aRect;
+ SymbolType eSymbol;
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nExtra/2;
+ aTmpPos.Y() += pData->aSz.Height() / 2;
+ if ( pData->nBits & MIB_RADIOCHECK )
+ {
+ aTmpPos.X() = aPos.X() + nCheckPos;
+ eSymbol = SYMBOL_RADIOCHECKMARK;
+ aTmpPos.Y() -= nFontHeight/4;
+ aRect = Rectangle( aTmpPos, Size( nFontHeight/2, nFontHeight/2 ) );
+ }
+ else
+ {
+ aTmpPos.X() = aPos.X() + nCheckPos;
+ eSymbol = SYMBOL_CHECKMARK;
+ aTmpPos.Y() -= nFontHeight/4;
+ aRect = Rectangle( aTmpPos, Size( (nFontHeight*25)/40, nFontHeight/2 ) );
+ }
+ aDecoView.DrawSymbol( aRect, eSymbol, pWin->GetTextColor(), nSymbolStyle );
+ }
+
+ // SubMenu?
+ if ( !bIsMenuBar && pData->pSubMenu )
+ {
+ aTmpPos.X() = aOutSz.Width() - nFontHeight + nExtra;
+ aTmpPos.Y() = aPos.Y();
+ aTmpPos.Y() += nExtra/2;
+ aTmpPos.Y() += ( pData->aSz.Height() / 2 ) - ( nFontHeight/4 );
+ if ( pData->nBits & MIB_POPUPSELECT )
+ {
+ pWin->SetTextColor( rSettings.GetMenuTextColor() );
+ Point aTmpPos2( aPos );
+ aTmpPos2.X() = aOutSz.Width() - nFontHeight - nFontHeight/4;
+ aDecoView.DrawFrame(
+ Rectangle( aTmpPos2, Size( nFontHeight+nFontHeight/4, pData->aSz.Height() ) ), FRAME_DRAW_GROUP );
+ }
+ aDecoView.DrawSymbol(
+ Rectangle( aTmpPos, Size( nFontHeight/2, nFontHeight/2 ) ),
+ SYMBOL_SPIN_RIGHT, pWin->GetTextColor(), nSymbolStyle );
+// if ( pData->nBits & MIB_POPUPSELECT )
+// {
+// aTmpPos.Y() += nFontHeight/2 ;
+// pWin->SetLineColor( rSettings.GetShadowColor() );
+// pWin->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) );
+// pWin->SetLineColor( rSettings.GetLightColor() );
+// aTmpPos.Y()++;
+// pWin->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) );
+// pWin->SetLineColor();
+// }
+ }
+
+ if ( pThisItemOnly && bHighlighted )
+ pWin->SetTextColor( rSettings.GetMenuTextColor() );
+ }
+ }
+
+ if ( !bIsMenuBar )
+ {
+ aTopLeft.Y() += pData->aSz.Height();
+ }
+ else
+ {
+ aTopLeft.X() += pData->aSz.Width();
+ }
+ }
+
+ if ( !pThisItemOnly && pLogo )
+ {
+ Size aLogoSz = pLogo->aBitmap.GetSizePixel();
+
+ Rectangle aRect( Point( 0, 0 ), Point( aLogoSz.Width()-1, aOutSz.Height() ) );
+ if ( pWin->GetColorCount() >= 256 )
+ {
+ Gradient aGrad( GRADIENT_LINEAR, pLogo->aStartColor, pLogo->aEndColor );
+ aGrad.SetAngle( 1800 );
+ aGrad.SetBorder( 15 );
+ pWin->DrawGradient( aRect, aGrad );
+ }
+ else
+ {
+ pWin->SetFillColor( pLogo->aStartColor );
+ pWin->DrawRect( aRect );
+ }
+
+ Point aLogoPos( 0, aOutSz.Height() - aLogoSz.Height() );
+ pLogo->aBitmap.Draw( pWin, aLogoPos );
+ }
+}
+
+Menu* Menu::ImplGetStartMenu()
+{
+ Menu* pStart = this;
+ while ( pStart && pStart->pStartedFrom && ( pStart->pStartedFrom != pStart ) )
+ pStart = pStart->pStartedFrom;
+ return pStart;
+}
+
+void Menu::ImplCallHighlight( USHORT nHighlightedItem )
+{
+ nSelectedId = 0;
+ MenuItemData* pData = pItemList->GetDataFromPos( nHighlightedItem );
+ if ( pData )
+ nSelectedId = pData->nId;
+ Highlight();
+ nSelectedId = 0;
+}
+
+IMPL_LINK( Menu, ImplCallSelect, Menu*, EMPTYARG )
+{
+ nEventId = 0;
+ Select();
+ return 0;
+}
+
+Menu* Menu::ImplFindSelectMenu()
+{
+ Menu* pSelMenu = nEventId ? this : NULL;
+
+ for ( ULONG n = GetItemList()->Count(); n && !pSelMenu; )
+ {
+ MenuItemData* pData = GetItemList()->GetDataFromPos( --n );
+
+ if ( pData->pSubMenu )
+ pSelMenu = pData->pSubMenu->ImplFindSelectMenu();
+ }
+
+ return pSelMenu;
+}
+
+void Menu::RemoveDisabledEntries( BOOL bCheckPopups, BOOL bRemoveEmptyPopups )
+{
+ for ( USHORT n = 0; n < GetItemCount(); n++ )
+ {
+ BOOL bRemove = FALSE;
+ MenuItemData* pItem = pItemList->GetDataFromPos( n );
+ if ( pItem->eType == MENUITEM_SEPARATOR )
+ {
+ if ( !n || ( GetItemType( n-1 ) == MENUITEM_SEPARATOR ) )
+ bRemove = TRUE;
+ }
+ else
+ bRemove = !pItem->bEnabled;
+
+ if ( bCheckPopups && pItem->pSubMenu )
+ {
+ pItem->pSubMenu->RemoveDisabledEntries( TRUE );
+ if ( bRemoveEmptyPopups && !pItem->pSubMenu->GetItemCount() )
+ bRemove = TRUE;
+ }
+
+ if ( bRemove )
+ RemoveItem( n-- );
+ }
+
+ if ( GetItemCount() )
+ {
+ USHORT nLast = GetItemCount() - 1;
+ MenuItemData* pItem = pItemList->GetDataFromPos( nLast );
+ if ( pItem->eType == MENUITEM_SEPARATOR )
+ RemoveItem( nLast );
+ }
+}
+
+BOOL Menu::HasValidEntries( BOOL bCheckPopups )
+{
+ BOOL bValidEntries = FALSE;
+ USHORT nCount = GetItemCount();
+ for ( USHORT n = 0; !bValidEntries && ( n < nCount ); n++ )
+ {
+ MenuItemData* pItem = pItemList->GetDataFromPos( n );
+ if ( pItem->bEnabled && ( pItem->eType != MENUITEM_SEPARATOR ) )
+ {
+ if ( bCheckPopups && pItem->pSubMenu )
+ bValidEntries = pItem->pSubMenu->HasValidEntries( TRUE );
+ else
+ bValidEntries = TRUE;
+ }
+ }
+ return bValidEntries;
+}
+
+void Menu::SetLogo( const MenuLogo& rLogo )
+{
+ delete pLogo;
+ pLogo = new MenuLogo( rLogo );
+}
+
+void Menu::SetLogo()
+{
+ delete pLogo;
+ pLogo = NULL;
+}
+
+MenuLogo Menu::GetLogo() const
+{
+ MenuLogo aLogo;
+ if ( pLogo )
+ aLogo = *pLogo;
+ return aLogo;
+}
+
+void Menu::GetAccessObject( AccessObjectRef& rAcc ) const
+{
+ rAcc = new AccessObject( (void*) this, bIsMenuBar? ACCESS_TYPE_MENUBAR : ACCESS_TYPE_MENU );
+}
+
+// -----------
+// - MenuBar -
+// -----------
+
+MenuBar::MenuBar()
+{
+ bIsMenuBar = TRUE;
+ mbCloserVisible = FALSE;
+ mbFloatBtnVisible = FALSE;
+ mbHideBtnVisible = FALSE;
+}
+
+MenuBar::MenuBar( const MenuBar& rMenu )
+{
+ bIsMenuBar = TRUE;
+ mbCloserVisible = FALSE;
+ mbFloatBtnVisible = FALSE;
+ mbHideBtnVisible = FALSE;
+ *this = rMenu;
+ bIsMenuBar = TRUE;
+}
+
+MenuBar::MenuBar( const ResId& rResId )
+{
+ bIsMenuBar = TRUE;
+ mbCloserVisible = FALSE;
+ mbFloatBtnVisible = FALSE;
+ mbHideBtnVisible = FALSE;
+ ImplLoadRes( rResId );
+}
+
+MenuBar::~MenuBar()
+{
+ ImplDestroy( this, TRUE );
+}
+
+void MenuBar::ShowCloser( BOOL bShow )
+{
+ ShowButtons( bShow, mbFloatBtnVisible, mbHideBtnVisible );
+}
+
+void MenuBar::ShowFloatButton( BOOL bShow )
+{
+ ShowButtons( mbCloserVisible, bShow, mbHideBtnVisible );
+}
+
+void MenuBar::ShowHideButton( BOOL bShow )
+{
+ ShowButtons( mbCloserVisible, mbFloatBtnVisible, bShow );
+}
+
+void MenuBar::ShowButtons( BOOL bClose, BOOL bFloat, BOOL bHide )
+{
+ if ( (bClose != mbCloserVisible) ||
+ (bFloat != mbFloatBtnVisible) ||
+ (bHide != mbHideBtnVisible) )
+ {
+ mbCloserVisible = bClose;
+ mbFloatBtnVisible = bFloat;
+ mbHideBtnVisible = bHide;
+ if ( ImplGetWindow() )
+ ((MenuBarWindow*)ImplGetWindow())->ShowButtons( bClose, bFloat, bHide );
+ }
+}
+
+Window* MenuBar::ImplCreate( Window* pParent, Window* pWindow, MenuBar* pMenu )
+{
+ if ( !pWindow )
+ pWindow = new MenuBarWindow( pParent );
+
+ pMenu->pStartedFrom = 0;
+ pMenu->pWindow = pWindow;
+ ((MenuBarWindow*)pWindow)->SetMenu( pMenu );
+ long nHeight = pMenu->ImplCalcSize( pWindow ).Height();
+ pWindow->SetPosSizePixel( 0, 0, 0, nHeight, WINDOW_POSSIZE_HEIGHT );
+ return pWindow;
+}
+
+void MenuBar::ImplDestroy( MenuBar* pMenu, BOOL bDelete )
+{
+ MenuBarWindow* pWindow = (MenuBarWindow*) pMenu->ImplGetWindow();
+ if ( pWindow && bDelete )
+ {
+ pWindow->KillActivePopup();
+ delete pWindow;
+ }
+ pMenu->pWindow = NULL;
+}
+
+BOOL MenuBar::ImplHandleKeyEvent( const KeyEvent& rKEvent, BOOL bFromMenu )
+{
+ BOOL bDone = FALSE;
+ // Enabled-Abfragen, falls diese Methode von einem anderen Fenster gerufen wurde...
+ Window* pWin = ImplGetWindow();
+ if ( pWin && pWin->IsEnabled() && pWin->IsInputEnabled() )
+ bDone = ((MenuBarWindow*)pWin)->ImplHandleKeyEvent( rKEvent, bFromMenu );
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+void MenuBar::SelectEntry( USHORT nId )
+{
+ if( ImplGetWindow() )
+ {
+ MenuBarWindow* pMenuWin = (MenuBarWindow*) ImplGetWindow();
+
+ pMenuWin->GrabFocus();
+ nId = GetItemPos( nId );
+
+ if( ITEMPOS_INVALID == pMenuWin->nHighlightedItem )
+ {
+ if( ( nId != ITEMPOS_INVALID ) && ( nId != pMenuWin->nHighlightedItem ) )
+ pMenuWin->ChangeHighlightItem( nId, FALSE );
+ }
+ else
+ {
+ pMenuWin->KillActivePopup();
+ pMenuWin->ChangeHighlightItem( ITEMPOS_INVALID, FALSE );
+ }
+ }
+}
+
+// BOOL PopupMenu::bAnyPopupInExecute = FALSE;
+
+PopupMenu::PopupMenu()
+{
+}
+
+PopupMenu::PopupMenu( const ResId& rResId )
+{
+ ImplLoadRes( rResId );
+}
+
+PopupMenu::PopupMenu( const PopupMenu& rMenu )
+{
+ *this = rMenu;
+}
+
+PopupMenu::~PopupMenu()
+{
+}
+
+BOOL PopupMenu::IsInExecute()
+{
+ return GetActivePopupMenu() ? TRUE : FALSE;
+}
+
+PopupMenu* PopupMenu::GetActivePopupMenu()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ return pSVData->maAppData.mpActivePopupMenu;
+}
+
+void PopupMenu::EndExecute( USHORT nSelectId )
+{
+ if ( ImplGetWindow() )
+ ImplGetFloatingWindow()->EndExecute( nSelectId );
+}
+
+void PopupMenu::SelectEntry( USHORT nId )
+{
+ if ( ImplGetWindow() )
+ {
+ USHORT nPos;
+ MenuItemData* pData = GetItemList()->GetData( nId, nPos );
+ if ( pData->pSubMenu )
+ ImplGetFloatingWindow()->ChangeHighlightItem( nPos, TRUE );
+ else
+ ImplGetFloatingWindow()->EndExecute( nId );
+ }
+}
+
+USHORT PopupMenu::Execute( Window* pWindow, const Point& rPopupPos )
+{
+ return Execute( pWindow, Rectangle( rPopupPos, rPopupPos ), POPUPMENU_EXECUTE_DOWN );
+}
+
+USHORT PopupMenu::Execute( Window* pWindow, const Rectangle& rRect, USHORT nFlags )
+{
+ ULONG nPopupModeFlags = 0;
+ if ( nFlags & POPUPMENU_EXECUTE_DOWN )
+ nPopupModeFlags = FLOATWIN_POPUPMODE_DOWN;
+ else if ( nFlags & POPUPMENU_EXECUTE_UP )
+ nPopupModeFlags = FLOATWIN_POPUPMODE_UP;
+ else if ( nFlags & POPUPMENU_EXECUTE_LEFT )
+ nPopupModeFlags = FLOATWIN_POPUPMODE_LEFT;
+ else if ( nFlags & POPUPMENU_EXECUTE_RIGHT )
+ nPopupModeFlags = FLOATWIN_POPUPMODE_RIGHT;
+ else
+ nPopupModeFlags = FLOATWIN_POPUPMODE_DOWN;
+ return ImplExecute( pWindow, rRect, nPopupModeFlags, 0, FALSE );
+}
+
+USHORT PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, ULONG nPopupModeFlags, Menu* pSFrom, BOOL bPreSelectFirst )
+{
+ // #59614# Mit TH abgesprochen dass die ASSERTION raus kommt,
+ // weil es evtl. legitim ist...
+// DBG_ASSERT( !PopupMenu::IsInExecute() || pSFrom, "PopupMenu::Execute() called in PopupMenu::Execute()" );
+
+ if ( !pSFrom && ( PopupMenu::IsInExecute() || !GetItemCount() ) )
+ return 0;
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ pStartedFrom = pSFrom;
+ nSelectedId = 0;
+ bCanceled = FALSE;
+
+ ULONG nFocusId = 0;
+ BOOL bRealExecute = FALSE;
+ if ( !pStartedFrom )
+ {
+ pSVData->maWinData.mbNoDeactivate = TRUE;
+ nFocusId = Window::SaveFocus();
+ bRealExecute = TRUE;
+ }
+
+ DBG_ASSERT( !ImplGetWindow(), "Win?!" );
+ Rectangle aRect( rRect );
+ aRect.SetPos( pW->OutputToScreenPixel( aRect.TopLeft() ) );
+
+ WinBits nStyle = WB_BORDER;
+ if ( bRealExecute )
+ nPopupModeFlags |= FLOATWIN_POPUPMODE_NEWLEVEL;
+ if ( !pStartedFrom || !pStartedFrom->bIsMenuBar )
+ nPopupModeFlags |= FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK | FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE;
+
+ // Kann beim Debuggen hilfreich sein.
+ // nPopupModeFlags |= FLOATWIN_POPUPMODE_NOFOCUSCLOSE;
+
+ ImplDelData aDelData;
+ pW->ImplAddDel( &aDelData );
+
+ bInCallback = TRUE; // hier schon setzen, falls Activate ueberladen
+ Activate();
+ bInCallback = FALSE;
+
+ if ( aDelData.IsDelete() )
+ return 0; // Error
+
+ pW->ImplRemoveDel( &aDelData );
+
+ if ( bCanceled || bKilled )
+ return 0;
+
+ if ( !GetItemCount() )
+ return 0;
+
+ // Das Flag MENU_FLAG_HIDEDISABLEDENTRIES wird vererbt.
+ if ( pSFrom )
+ {
+ if ( pSFrom->nMenuFlags & MENU_FLAG_HIDEDISABLEDENTRIES )
+ nMenuFlags |= MENU_FLAG_HIDEDISABLEDENTRIES;
+ else
+ nMenuFlags &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
+ }
+
+ USHORT nVisibleEntries = ImplGetVisibleItemCount();
+ if ( !nVisibleEntries )
+ {
+ String aTmpEntryText( ResId( SV_RESID_STRING_NOSELECTIONPOSSIBLE, ImplGetResMgr() ) );
+ MenuItemData* pData = pItemList->Insert(
+ 0xFFFF, MENUITEM_STRING, 0, aTmpEntryText, Image(), NULL, 0xFFFF );
+ pData->bIsTemporary = TRUE;
+ }
+ else if ( pSVData->maAppData.mbAutoMnemonics && !( nMenuFlags & MENU_FLAG_NOAUTOMNEMONICS ) )
+ {
+ ImplMnemonicGenerator aMnemonicGenerator;
+ ULONG n;
+ for ( n = 0; n < pItemList->Count(); n++ )
+ aMnemonicGenerator.RegisterMnemonic( pItemList->GetDataFromPos(n)->aText );
+ for ( n = 0; n < pItemList->Count(); n++ )
+ aMnemonicGenerator.CreateMnemonic( pItemList->GetDataFromPos(n)->aText );
+ }
+
+ MenuFloatingWindow* pWin = new MenuFloatingWindow( this, pW, nStyle );
+ pWindow = pWin;
+
+ Size aSz = ImplCalcSize( pWin );
+
+ long nMaxHeight = pWin->GetDesktopRectPixel().GetHeight();
+ if ( pStartedFrom && pStartedFrom->bIsMenuBar )
+ nMaxHeight -= pW->GetSizePixel().Height();
+ long nLeft, nTop, nRight, nBottom;
+ pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
+ nMaxHeight -= nTop+nBottom;
+ if ( aSz.Height() > nMaxHeight )
+ {
+ pWin->EnableScrollMenu( TRUE );
+ USHORT nEntries = ImplCalcVisEntries( nMaxHeight );
+ aSz.Height() = ImplCalcHeight( nEntries );
+ }
+
+ pWin->SetFocusId( nFocusId );
+ pWin->SetOutputSizePixel( aSz );
+ pWin->GrabFocus();
+ if ( GetItemCount() )
+ {
+ pWin->StartPopupMode( aRect, nPopupModeFlags );
+ }
+ if ( bPreSelectFirst )
+ {
+ USHORT nCount = (USHORT)pItemList->Count();
+ for ( USHORT n = 0; n < nCount; n++ )
+ {
+ MenuItemData* pData = pItemList->GetDataFromPos( n );
+ if ( ( pData->eType != MENUITEM_SEPARATOR ) && ImplIsVisible( n ) )
+ {
+ pWin->ChangeHighlightItem( n, FALSE );
+ break;
+ }
+ }
+ }
+ if ( bRealExecute )
+ {
+ pWin->Execute();
+
+ // Focus wieder herstellen (kann schon im Select wieder
+ // hergestellt wurden sein
+ nFocusId = pWin->GetFocusId();
+ if ( nFocusId )
+ {
+ pWin->SetFocusId( 0 );
+ pSVData->maWinData.mbNoDeactivate = FALSE;
+ }
+ pWin->ImplEndPopupMode( 0, nFocusId );
+
+ if ( nSelectedId ) // Dann abraeumen... ( sonst macht TH das )
+ {
+ PopupMenu* pSub = pWin->GetActivePopup();
+ while ( pSub )
+ {
+ pSub->ImplGetFloatingWindow()->EndPopupMode();
+ pSub = pSub->ImplGetFloatingWindow()->GetActivePopup();
+ }
+ }
+ delete pWindow;
+ pWindow = NULL;
+
+ // Steht noch ein Select aus?
+ Menu* pSelect = ImplFindSelectMenu();
+ if ( pSelect )
+ {
+ // Beim Popup-Menu muss das Select vor dem Verlassen von Execute gerufen werden!
+ Application::RemoveUserEvent( pSelect->nEventId );
+ pSelect->nEventId = 0;
+ pSelect->Select();
+ }
+ }
+
+ return bRealExecute ? nSelectedId : 0;
+}
+
+USHORT PopupMenu::ImplCalcVisEntries( long nMaxHeight, USHORT nStartEntry ) const
+{
+ nMaxHeight -= 2 * ImplGetFloatingWindow()->GetScrollerHeight();
+
+ long nHeight = 0;
+ USHORT nEntries = (USHORT) pItemList->Count();
+ USHORT nVisEntries = 0;
+ for ( USHORT n = nStartEntry; n < nEntries; n++ )
+ {
+ if ( ImplIsVisible( n ) )
+ {
+ MenuItemData* pData = pItemList->GetDataFromPos( n );
+ nHeight += pData->aSz.Height();
+ if ( nHeight > nMaxHeight )
+ break;
+ nVisEntries++;
+ }
+ }
+ return nVisEntries;
+}
+
+long PopupMenu::ImplCalcHeight( USHORT nEntries ) const
+{
+ long nHeight = 0;
+
+ if ( nEntries > pItemList->Count() )
+ nEntries = (USHORT) pItemList->Count();
+
+ for ( ULONG n = 0; n < nEntries; n++ )
+ {
+ MenuItemData* pData = pItemList->GetDataFromPos( n );
+ nHeight += pData->aSz.Height();
+ }
+
+ nHeight += 2*ImplGetFloatingWindow()->GetScrollerHeight();
+
+ return nHeight;
+}
+
+
+static void ImplInitMenuWindow( Window* pWin, BOOL bFont )
+{
+ const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ pWin->SetPointFont( rStyleSettings.GetMenuFont() );
+ pWin->SetBackground( Wallpaper( rStyleSettings.GetMenuColor() ) );
+ pWin->SetTextColor( rStyleSettings.GetMenuTextColor() );
+ pWin->SetTextFillColor();
+ pWin->SetLineColor();
+}
+
+MenuFloatingWindow::MenuFloatingWindow( Menu* pMen, Window* pParent, WinBits nStyle ) :
+ FloatingWindow( pParent, nStyle )
+{
+ pMenu = pMen;
+ pActivePopup = 0;
+ nSaveFocusId = 0;
+ bInExecute = FALSE;
+ bScrollMenu = FALSE;
+ nHighlightedItem = ITEMPOS_INVALID;
+ nMBDownPos = ITEMPOS_INVALID;
+ nScrollerHeight = 0;
+ nStartY = 0;
+ nBorder = EXTRASPACEY;
+ nFirstEntry = 0;
+ bScrollUp = FALSE;
+ bScrollDown = FALSE;
+
+ EnableSaveBackground();
+ ImplInitMenuWindow( this, TRUE );
+
+ SetPopupModeEndHdl( LINK( this, MenuFloatingWindow, PopupEnd ) );
+
+ aHighlightChangedTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, HighlightChanged ) );
+ aHighlightChangedTimer.SetTimeout( GetSettings().GetMouseSettings().GetMenuDelay() );
+ aScrollTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, AutoScroll ) );
+
+ if ( Application::GetAccessHdlCount() )
+ Application::AccessNotify( AccessNotification( ACCESS_EVENT_POPUPMENU_START, pMenu ) );
+}
+
+MenuFloatingWindow::~MenuFloatingWindow()
+{
+ if( Application::GetAccessHdlCount() )
+ Application::AccessNotify( AccessNotification( ACCESS_EVENT_POPUPMENU_END, pMenu ) );
+
+ aHighlightChangedTimer.Stop();
+}
+
+void MenuFloatingWindow::Resize()
+{
+ ImplInitClipRegion();
+}
+
+Region MenuFloatingWindow::ImplCalcClipRegion( BOOL bIncludeLogo ) const
+{
+ Size aOutSz = GetOutputSizePixel();
+ Point aPos;
+ Rectangle aRect( aPos, aOutSz );
+ long nBorder = nScrollerHeight;
+ aRect.Top() += nBorder;
+ aRect.Bottom() -= nBorder;
+
+ if ( pMenu->pLogo && !bIncludeLogo )
+ aRect.Left() += pMenu->pLogo->aBitmap.GetSizePixel().Width();
+
+ Region aRegion = aRect;
+ if ( pMenu->pLogo && bIncludeLogo && nScrollerHeight )
+ aRegion.Union( Rectangle( Point(), Size( pMenu->pLogo->aBitmap.GetSizePixel().Width(), aOutSz.Height() ) ) );
+
+ return aRegion;
+}
+
+void MenuFloatingWindow::ImplInitClipRegion()
+{
+ if ( IsScrollMenu() )
+ {
+ SetClipRegion( ImplCalcClipRegion() );
+ }
+ else
+ {
+ SetClipRegion();
+ }
+}
+
+void MenuFloatingWindow::ImplHighlightItem( const MouseEvent& rMEvt, BOOL bMBDown )
+{
+ long nY = nScrollerHeight;
+ long nMouseY = rMEvt.GetPosPixel().Y();
+ Size aOutSz = GetOutputSizePixel();
+ if ( ( nMouseY >= nY ) && ( nMouseY < ( aOutSz.Height() - nY ) ) )
+ {
+ BOOL bHighlighted = FALSE;
+ USHORT nCount = (USHORT)pMenu->pItemList->Count();
+ nY += nStartY; // ggf. gescrollt.
+ for ( USHORT n = 0; !bHighlighted && ( n < nCount ); n++ )
+ {
+ if ( pMenu->ImplIsVisible( n ) )
+ {
+ MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
+ long nOldY = nY;
+ nY += pData->aSz.Height();
+ if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) )
+ {
+ BOOL bPopupArea = TRUE;
+ if ( pData->nBits & MIB_POPUPSELECT )
+ {
+ // Nur wenn ueber dem Pfeil geklickt wurde...
+ Size aSz = GetOutputSizePixel();
+ long nFontHeight = GetTextHeight();
+ bPopupArea = ( rMEvt.GetPosPixel().X() >= ( aSz.Width() - nFontHeight - nFontHeight/4 ) );
+ }
+
+ if ( bMBDown )
+ {
+ if ( n != nHighlightedItem )
+ ChangeHighlightItem( (USHORT)n, FALSE );
+
+ if ( pActivePopup )
+ KillActivePopup();
+ else if ( bPopupArea )
+ HighlightChanged( NULL );
+ }
+ else
+ {
+ if ( n != nHighlightedItem )
+ {
+ ChangeHighlightItem( (USHORT)n, TRUE );
+ }
+ else if ( pData->nBits & MIB_POPUPSELECT )
+ {
+ if ( bPopupArea && ( pActivePopup != pData->pSubMenu ) )
+ HighlightChanged( NULL );
+ }
+ }
+ bHighlighted = TRUE;
+ }
+ }
+ }
+ if ( !bHighlighted )
+ ChangeHighlightItem( ITEMPOS_INVALID, TRUE );
+ }
+ else
+ {
+ ImplScroll( rMEvt.GetPosPixel() );
+ ChangeHighlightItem( ITEMPOS_INVALID, TRUE );
+ }
+}
+
+IMPL_LINK( MenuFloatingWindow, PopupEnd, FloatingWindow*, pPopup )
+{
+ if ( bInExecute )
+ {
+ if ( pActivePopup )
+ {
+ DBG_ASSERT( !pActivePopup->ImplGetWindow(), "PopupEnd, obwohl pActivePopup MIT Window!" );
+ pActivePopup->bCanceled = TRUE;
+ }
+ bInExecute = FALSE;
+ pMenu->bInCallback = TRUE;
+ pMenu->Deactivate();
+ pMenu->bInCallback = FALSE;
+ }
+ else
+ {
+ // Wenn dies Fenster von TH geschlossen wurde, hat noch ein anderes
+ // Menu dieses Fenster als pActivePopup.
+ if ( pMenu->pStartedFrom )
+ {
+ // Das pWin am 'Parent' kann aber schon 0 sein, falls die Kette von
+ // vorne abgeraeumt wurde und jetzt die EndPopup-Events eintrudeln
+ if ( pMenu->pStartedFrom->bIsMenuBar )
+ {
+ MenuBarWindow* p = (MenuBarWindow*) pMenu->pStartedFrom->ImplGetWindow();
+ if ( p )
+ p->PopupClosed( pMenu );
+ }
+ else
+ {
+ MenuFloatingWindow* p = (MenuFloatingWindow*) pMenu->pStartedFrom->ImplGetWindow();
+ if ( p )
+ p->KillActivePopup( (PopupMenu*)pMenu );
+ }
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK( MenuFloatingWindow, AutoScroll, Timer*, EMPTYARG )
+{
+ ImplScroll( GetPointerPosPixel() );
+ return 1;
+}
+
+IMPL_LINK( MenuFloatingWindow, HighlightChanged, Timer*, pTimer )
+{
+ MenuItemData* pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
+ if ( pData )
+ {
+ if ( pActivePopup && ( pActivePopup != pData->pSubMenu ) )
+ {
+ KillActivePopup();
+ }
+ if ( pData->bEnabled && pData->pSubMenu && pData->pSubMenu->GetItemCount() && ( pData->pSubMenu != pActivePopup ) )
+ {
+ pActivePopup = (PopupMenu*)pData->pSubMenu;
+ long nY = nScrollerHeight+nStartY;
+ MenuItemData* pData = 0;
+ for ( ULONG n = 0; n < nHighlightedItem; n++ )
+ {
+ pData = pMenu->pItemList->GetDataFromPos( n );
+ nY += pData->aSz.Height();
+ }
+ pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
+ Size MySize = GetOutputSizePixel();
+// Point MyPos = GetPosPixel();
+// Point aItemTopLeft( MyPos.X(), MyPos.Y()+nY );
+ Point aItemTopLeft( 0, nY );
+ Point aItemBottomRight( aItemTopLeft );
+ aItemBottomRight.X() += MySize.Width();
+ aItemBottomRight.Y() += pData->aSz.Height();
+
+ // Popups leicht versetzen:
+ aItemTopLeft.X() += 2;
+ aItemBottomRight.X() -= 2;
+ if ( nHighlightedItem )
+ aItemTopLeft.Y() -= 2;
+ else
+ {
+ long nL, nT, nR, nB;
+ GetBorder( nL, nT, nR, nB );
+ aItemTopLeft.Y() -= nT;
+ }
+
+ // pTest: Wegen Abstuerzen durch Reschedule() im Aufruf von Activate()
+ // Ausserdem wird damit auch verhindert, dass SubMenus angezeigt werden,
+ // die lange im Activate Rescheduled haben und jetzt schon nicht mehr
+ // angezeigt werden sollen.
+ Menu* pTest = pActivePopup;
+ USHORT nRet = pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_RIGHT, pMenu, pTimer ? FALSE : TRUE );
+
+ // nRet != 0, wenn es waerend Activate() abgeschossen wurde...
+ if ( !nRet && ( pActivePopup == pTest ) && pActivePopup->ImplGetWindow() )
+ pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this );
+ }
+ }
+
+ return 0;
+}
+
+void MenuFloatingWindow::EnableScrollMenu( BOOL b )
+{
+ bScrollMenu = b;
+ nScrollerHeight = b ? (USHORT) GetSettings().GetStyleSettings().GetScrollBarSize() /2 : 0;
+ bScrollDown = TRUE;
+ ImplInitClipRegion();
+}
+
+void MenuFloatingWindow::Execute()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ pSVData->maAppData.mpActivePopupMenu = (PopupMenu*)pMenu;
+
+ bInExecute = TRUE;
+// bCallingSelect = FALSE;
+
+ while ( bInExecute )
+ Application::Yield();
+
+ pSVData->maAppData.mpActivePopupMenu = NULL;
+
+// while ( bCallingSelect )
+// Application::Yield();
+}
+
+void MenuFloatingWindow::StopExecute( ULONG nFocusId )
+{
+ // Focus wieder herstellen
+ // (kann schon im Select wieder hergestellt wurden sein)
+ if ( nSaveFocusId )
+ {
+ Window::EndSaveFocus( nFocusId, FALSE );
+ nFocusId = nSaveFocusId;
+ if ( nFocusId )
+ {
+ nSaveFocusId = 0;
+ ImplGetSVData()->maWinData.mbNoDeactivate = FALSE;
+ }
+ }
+ ImplEndPopupMode( 0, nFocusId );
+
+ aHighlightChangedTimer.Stop();
+ bInExecute = FALSE;
+ if ( pActivePopup )
+ {
+ KillActivePopup();
+ }
+}
+
+void MenuFloatingWindow::KillActivePopup( PopupMenu* pThisOnly )
+{
+ if ( pActivePopup && ( !pThisOnly || ( pThisOnly == pActivePopup ) ) )
+ {
+ if ( pActivePopup->bInCallback )
+ pActivePopup->bCanceled = TRUE;
+
+ // Vor allen Aktionen schon pActivePopup = 0, falls z.B.
+ // PopupModeEndHdl des zu zerstoerenden Popups mal synchron gerufen wird.
+ PopupMenu* pPopup = pActivePopup;
+ pActivePopup = NULL;
+ pPopup->bInCallback = TRUE;
+ pPopup->Deactivate();
+ pPopup->bInCallback = FALSE;
+ if ( pPopup->ImplGetWindow() )
+ {
+ pPopup->ImplGetFloatingWindow()->StopExecute();
+ delete pPopup->pWindow;
+ pPopup->pWindow = NULL;
+ Update();
+ }
+ }
+}
+
+void MenuFloatingWindow::EndExecute()
+{
+ Menu* pStart = pMenu->ImplGetStartMenu();
+ ULONG nFocusId = 0;
+ if ( pStart && pStart->bIsMenuBar )
+ {
+ nFocusId = ((MenuBarWindow*)((MenuBar*)pStart)->ImplGetWindow())->GetFocusId();
+ if ( nFocusId )
+ {
+ ((MenuBarWindow*)((MenuBar*)pStart)->ImplGetWindow())->SetFocusId( 0 );
+ ImplGetSVData()->maWinData.mbNoDeactivate = FALSE;
+ }
+ }
+ // Wenn von woanders gestartet, dann ab dort aufraumen:
+ MenuFloatingWindow* pCleanUpFrom = this;
+ MenuFloatingWindow* pWin = this;
+ while ( pWin && !pWin->bInExecute &&
+ pWin->pMenu->pStartedFrom && !pWin->pMenu->pStartedFrom->bIsMenuBar )
+ {
+ pWin = ((PopupMenu*)pWin->pMenu->pStartedFrom)->ImplGetFloatingWindow();
+ }
+ if ( pWin )
+ pCleanUpFrom = pWin;
+
+ // Dies Fenster wird gleich zerstoert => Daten lokal merken...
+ Menu* pM = pMenu;
+ USHORT nItem = nHighlightedItem;
+
+ pCleanUpFrom->StopExecute( nFocusId );
+
+ if ( nItem != ITEMPOS_INVALID )
+ {
+ MenuItemData* pItemData = pM->GetItemList()->GetDataFromPos( nItem );
+ if ( pItemData && !pItemData->bIsTemporary )
+ {
+ pM->nSelectedId = pItemData->nId;
+ if ( pStart )
+ pStart->nSelectedId = pItemData->nId;
+
+ pM->ImplSelect();
+ }
+ }
+}
+
+void MenuFloatingWindow::EndExecute( USHORT nId )
+{
+ USHORT nPos;
+ if ( pMenu->GetItemList()->GetData( nId, nPos ) )
+ nHighlightedItem = nPos;
+ else
+ nHighlightedItem = ITEMPOS_INVALID;
+
+ EndExecute();
+}
+
+void MenuFloatingWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ // TH macht ein ToTop auf dieses Fenster, aber das aktive Popup
+ // soll oben bleiben...
+ if ( pActivePopup && pActivePopup->ImplGetWindow() && !pActivePopup->ImplGetFloatingWindow()->pActivePopup )
+ pActivePopup->ImplGetFloatingWindow()->ToTop();
+
+ if ( !ImplIsMouseFollow() )
+ {
+ ImplHighlightItem( rMEvt, TRUE );
+ }
+
+ nMBDownPos = nHighlightedItem;
+}
+
+void MenuFloatingWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
+ // nMBDownPos in lokaler Variable merken und gleich zuruecksetzen,
+ // weil nach EndExecute zu spaet
+ USHORT _nMBDownPos = nMBDownPos;
+ nMBDownPos = ITEMPOS_INVALID;
+ if ( pData && pData->bEnabled && ( pData->eType != MENUITEM_SEPARATOR ) )
+ {
+ if ( !pData->pSubMenu )
+ {
+ EndExecute();
+ }
+ else if ( ( pData->nBits & MIB_POPUPSELECT ) && ( nHighlightedItem == _nMBDownPos ) && ( rMEvt.GetClicks() == 2 ) )
+ {
+ // Nicht wenn ueber dem Pfeil geklickt wurde...
+ Size aSz = GetOutputSizePixel();
+ long nFontHeight = GetTextHeight();
+ if ( rMEvt.GetPosPixel().X() < ( aSz.Width() - nFontHeight - nFontHeight/4 ) )
+ EndExecute();
+ }
+ }
+
+}
+
+void MenuFloatingWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( !IsVisible() || rMEvt.IsSynthetic() )
+ return;
+
+ if ( rMEvt.IsLeaveWindow() )
+ {
+ if ( ImplIsMouseFollow() || ( rMEvt.GetButtons() == MOUSE_LEFT ) )
+ ChangeHighlightItem( ITEMPOS_INVALID, FALSE );
+ if ( IsScrollMenu() )
+ ImplScroll( rMEvt.GetPosPixel() );
+ }
+ else if ( ImplIsMouseFollow() || ( rMEvt.GetButtons() == MOUSE_LEFT ) )
+ {
+ ImplHighlightItem( rMEvt, FALSE );
+ }
+}
+
+void MenuFloatingWindow::ImplScroll( BOOL bUp )
+{
+ KillActivePopup();
+ Update();
+
+ HighlightItem( nHighlightedItem, FALSE );
+
+ if ( bScrollUp && bUp )
+ {
+ MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( --nFirstEntry );
+ long nEntryHeight = pData->aSz.Height();
+
+ nStartY += nEntryHeight;
+
+ if ( !bScrollDown )
+ {
+ bScrollDown = TRUE;
+ ImplDrawScroller( FALSE );
+ }
+
+ if ( nFirstEntry == 0 )
+ {
+ bScrollUp = FALSE;
+ ImplDrawScroller( TRUE );
+ }
+ Scroll( 0, nEntryHeight, ImplCalcClipRegion( FALSE ).GetBoundRect(), SCROLL_CLIP );
+ }
+ else if ( bScrollDown && !bUp )
+ {
+ MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nFirstEntry++ );
+ long nEntryHeight = pData->aSz.Height();
+
+ if ( !bScrollUp )
+ {
+ bScrollUp = TRUE;
+ ImplDrawScroller( TRUE );
+ }
+
+ Size aOutSz = GetOutputSizePixel();
+ USHORT nVisible = ((PopupMenu*)pMenu)->ImplCalcVisEntries( aOutSz.Height(), nFirstEntry );
+ if ( ( nFirstEntry + nVisible ) >= (USHORT) pMenu->GetItemList()->Count() )
+ {
+ bScrollDown = FALSE;
+ ImplDrawScroller( FALSE );
+ }
+
+ nStartY -= nEntryHeight;
+ Scroll( 0, -nEntryHeight, ImplCalcClipRegion( FALSE ).GetBoundRect(), SCROLL_CLIP );
+ }
+
+ HighlightItem( nHighlightedItem, TRUE );
+}
+
+void MenuFloatingWindow::ImplScroll( const Point& rMousePos )
+{
+ Size aOutSz = GetOutputSizePixel();
+
+ long nY = nScrollerHeight;
+ long nMouseY = rMousePos.Y();
+ long nDelta = 0;
+
+ if ( bScrollUp && ( nMouseY < nY ) )
+ {
+ ImplScroll( TRUE );
+ nDelta = nY - nMouseY;
+ }
+ else if ( bScrollDown && ( nMouseY > ( aOutSz.Height() - nY ) ) )
+ {
+ ImplScroll( FALSE );
+ nDelta = nMouseY - ( aOutSz.Height() - nY );
+ }
+
+ if ( nDelta )
+ {
+ aScrollTimer.Stop(); // Falls durch MouseMove gescrollt.
+ long nTimeout;
+ if ( nDelta < 3 )
+ nTimeout = 200;
+ else if ( nDelta < 5 )
+ nTimeout = 100;
+ else if ( nDelta < 8 )
+ nTimeout = 70;
+ else if ( nDelta < 12 )
+ nTimeout = 40;
+ else
+ nTimeout = 20;
+ aScrollTimer.SetTimeout( nTimeout );
+ aScrollTimer.Start();
+ }
+}
+void MenuFloatingWindow::ChangeHighlightItem( USHORT n, BOOL bStartPopupTimer )
+{
+ // #57934# ggf. das aktive Popup sofort schliessen, damit TH's Hintergrundsicherung funktioniert.
+ // #65750# Dann verzichten wir lieber auf den schmalen Streifen Hintergrundsicherung.
+ // Sonst lassen sich die Menus schlecht bedienen.
+// MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
+// if ( pActivePopup && pNextData && ( pActivePopup != pNextData->pSubMenu ) )
+// KillActivePopup();
+
+ if ( nHighlightedItem != ITEMPOS_INVALID )
+ HighlightItem( nHighlightedItem, FALSE );
+
+ nHighlightedItem = (USHORT)n;
+ DBG_ASSERT( ( nHighlightedItem == ITEMPOS_INVALID ) || pMenu->ImplIsVisible( nHighlightedItem ), "ChangeHighlightItem: Not visible!" );
+ HighlightItem( nHighlightedItem, TRUE );
+ pMenu->ImplCallHighlight( nHighlightedItem );
+
+ if ( bStartPopupTimer )
+ aHighlightChangedTimer.Start();
+}
+
+void MenuFloatingWindow::HighlightItem( USHORT nPos, BOOL bHighlight )
+{
+ Size aSz = GetOutputSizePixel();
+ USHORT nBorder = nScrollerHeight;
+ long nY = nBorder+nStartY;
+ long nX = 0;
+
+ if ( pMenu->pLogo )
+ nX = pMenu->pLogo->aBitmap.GetSizePixel().Width();
+
+ USHORT nCount = (USHORT)pMenu->pItemList->Count();
+ for ( USHORT n = 0; n < nCount; n++ )
+ {
+ MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
+ if ( n == nPos )
+ {
+ DBG_ASSERT( pMenu->ImplIsVisible( n ), "Highlight: Item not visible!" );
+ if ( pData->eType != MENUITEM_SEPARATOR )
+ {
+ if ( bHighlight )
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
+ else
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
+
+ Rectangle aRect( Point( nX, nY ), Size( aSz.Width(), pData->aSz.Height() ) );
+ if ( pData->nBits & MIB_POPUPSELECT )
+ {
+ long nFontHeight = GetTextHeight();
+ aRect.Right() -= nFontHeight + nFontHeight/4;
+ }
+ DrawRect( aRect );
+ pMenu->ImplPaint( this, nBorder, nStartY, pData, bHighlight );
+ }
+ return;
+ }
+
+ nY += pData->aSz.Height();
+ }
+}
+
+void MenuFloatingWindow::ImplCursorUpDown( BOOL bUp )
+{
+ USHORT n = nHighlightedItem;
+ if ( n == ITEMPOS_INVALID )
+ {
+ if ( bUp )
+ n = 0;
+ else
+ n = pMenu->GetItemCount()-1;
+ }
+
+ USHORT nLoop = n;
+ do
+ {
+ if ( bUp )
+ {
+ if ( n )
+ n--;
+ else
+ if ( !IsScrollMenu() || ( nHighlightedItem == ITEMPOS_INVALID ) )
+ n = pMenu->GetItemCount()-1;
+ else
+ break;
+ }
+ else
+ {
+ n++;
+ if ( n >= pMenu->GetItemCount() )
+ if ( !IsScrollMenu() || ( nHighlightedItem == ITEMPOS_INVALID ) )
+ n = 0;
+ else
+ break;
+ }
+
+ MenuItemData* pData = (MenuItemData*)pMenu->GetItemList()->GetDataFromPos( n );
+ if ( ( pData->eType != MENUITEM_SEPARATOR ) && pMenu->ImplIsVisible( n ) )
+ {
+ // Selektion noch im sichtbaren Bereich?
+ if ( IsScrollMenu() )
+ {
+ ChangeHighlightItem( ITEMPOS_INVALID, FALSE );
+
+ while ( n < nFirstEntry )
+ ImplScroll( TRUE );
+
+ Size aOutSz = GetOutputSizePixel();
+ while ( n >= ( nFirstEntry + ((PopupMenu*)pMenu)->ImplCalcVisEntries( aOutSz.Height(), nFirstEntry ) ) )
+ ImplScroll( FALSE );
+ }
+ ChangeHighlightItem( n, FALSE );
+ break;
+ }
+ } while ( n != nLoop );
+}
+
+void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent )
+{
+ USHORT nCode = rKEvent.GetKeyCode().GetCode();
+ switch ( nCode )
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ {
+ ImplCursorUpDown( nCode == KEY_UP );
+ }
+ break;
+ case KEY_LEFT:
+ {
+ if ( pMenu->pStartedFrom )
+ {
+ StopExecute();
+ if ( pMenu->pStartedFrom->bIsMenuBar )
+ {
+ // Weiterkeiten...
+ ((MenuBarWindow*)((MenuBar*)pMenu->pStartedFrom)->ImplGetWindow())->KeyInput( rKEvent );
+ }
+ else
+ {
+ MenuFloatingWindow* pFloat = ((PopupMenu*)pMenu->pStartedFrom)->ImplGetFloatingWindow();
+ pFloat->GrabFocus();
+ pFloat->KillActivePopup();
+ }
+ }
+ }
+ break;
+ case KEY_RIGHT:
+ {
+ BOOL bDone = FALSE;
+ if ( nHighlightedItem != ITEMPOS_INVALID )
+ {
+ MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
+ if ( pData && pData->pSubMenu )
+ {
+ HighlightChanged( 0 );
+ bDone = TRUE;
+ }
+ }
+ if ( !bDone )
+ {
+ Menu* pStart = pMenu->ImplGetStartMenu();
+ if ( pStart && pStart->bIsMenuBar )
+ {
+ // Weiterkeiten...
+ pStart->ImplGetWindow()->KeyInput( rKEvent );
+ }
+ }
+ }
+ break;
+ case KEY_RETURN:
+ {
+ MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
+ if ( pData && pData->bEnabled )
+ {
+ if ( pData->pSubMenu )
+ HighlightChanged( 0 );
+ else
+ EndExecute();
+ }
+ else
+ StopExecute();
+ }
+ break;
+ case KEY_MENU:
+ {
+ Menu* pStart = pMenu->ImplGetStartMenu();
+ if ( pStart && pStart->bIsMenuBar )
+ {
+ // Weiterkeiten...
+ pStart->ImplGetWindow()->KeyInput( rKEvent );
+ }
+ }
+ break;
+ default:
+ {
+ xub_Unicode nCharCode = rKEvent.GetCharCode();
+ USHORT nPos;
+ MenuItemData* pData = pMenu->GetItemList()->SearchItem( nCharCode, nPos );
+ if ( pData )
+ {
+ if ( pData->pSubMenu )
+ {
+ ChangeHighlightItem( nPos, FALSE );
+ HighlightChanged( 0 );
+ }
+ else
+ {
+ nHighlightedItem = nPos;
+ EndExecute();
+ }
+ }
+ else
+ {
+ // Bei ungueltigen Tasten Beepen, aber nicht bei HELP und F-Tasten
+ if ( !rKEvent.GetKeyCode().IsControlMod() && ( nCode != KEY_HELP ) && ( rKEvent.GetKeyCode().GetGroup() != KEYGROUP_FKEYS ) )
+ Sound::Beep();
+ FloatingWindow::KeyInput( rKEvent );
+ }
+ }
+ }
+}
+
+void MenuFloatingWindow::Paint( const Rectangle& rRect )
+{
+ if ( IsScrollMenu() )
+ {
+ ImplDrawScroller( TRUE );
+ ImplDrawScroller( FALSE );
+ }
+ pMenu->ImplPaint( this, nScrollerHeight, nStartY );
+ if ( nHighlightedItem != ITEMPOS_INVALID )
+ HighlightItem( nHighlightedItem, TRUE );
+}
+
+void MenuFloatingWindow::ImplDrawScroller( BOOL bUp )
+{
+ SetClipRegion();
+
+ Size aOutSz = GetOutputSizePixel();
+ long nY = bUp ? 0 : ( aOutSz.Height() - nScrollerHeight );
+ long nX = pMenu->pLogo ? pMenu->pLogo->aBitmap.GetSizePixel().Width() : 0;
+ Rectangle aRect( Point( nX, nY ), Size( aOutSz.Width()-nX, nScrollerHeight ) );
+
+ DecorationView aDecoView( this );
+ SymbolType eSymbol = bUp ? SYMBOL_SPIN_UP : SYMBOL_SPIN_DOWN;
+
+ USHORT nStyle = 0;
+ if ( ( bUp && !bScrollUp ) || ( !bUp && !bScrollDown ) )
+ nStyle |= SYMBOL_DRAW_DISABLE;
+
+ aDecoView.DrawSymbol( aRect, eSymbol, GetSettings().GetStyleSettings().GetButtonTextColor(), nStyle );
+
+ ImplInitClipRegion();
+}
+
+void MenuFloatingWindow::RequestHelp( const HelpEvent& rHEvt )
+{
+ USHORT nId = nHighlightedItem;
+ Menu* pM = pMenu;
+ Window* pW = this;
+ if ( rHEvt.GetMode() & (HELPMODE_CONTEXT | HELPMODE_EXTENDED) )
+ {
+ nHighlightedItem = ITEMPOS_INVALID;
+ EndExecute();
+ pW = NULL;
+ }
+ if( !ImplHandleHelpEvent( pW, pM, nId, rHEvt ) )
+ Window::RequestHelp( rHEvt );
+}
+
+void MenuFloatingWindow::StateChanged( StateChangedType nType )
+{
+ FloatingWindow::StateChanged( nType );
+
+ if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) || ( nType == STATE_CHANGE_CONTROLBACKGROUND ) )
+ {
+ ImplInitMenuWindow( this, FALSE );
+ Invalidate();
+ }
+}
+
+void MenuFloatingWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ FloatingWindow::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitMenuWindow( this, FALSE );
+ Invalidate();
+ }
+}
+
+void MenuFloatingWindow::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
+ {
+// ImplCursorUpDown( pData->GetDelta() > 0L );
+ ImplScroll( pData->GetDelta() > 0L );
+ MouseMove( MouseEvent( GetPointerPosPixel(), 0 ) );
+ }
+ }
+}
+
+
+
+MenuBarWindow::MenuBarWindow( Window* pParent ) :
+ Window( pParent, 0 ),
+ aCloser( this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE ),
+ aFloatBtn( this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE ),
+ aHideBtn( this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE )
+{
+ pMenu = NULL;
+ pActivePopup = NULL;
+ nSaveFocusId = 0;
+ nHighlightedItem = ITEMPOS_INVALID;
+ mbAutoPopup = TRUE;
+ nSaveFocusId = 0;
+
+ ResMgr* pResMgr = ImplGetResMgr();
+ aCloser.SetClickHdl( LINK( this, MenuBarWindow, CloserHdl ) );
+ aCloser.SetSymbol( SYMBOL_CLOSE );
+ aCloser.SetQuickHelpText( XubString( ResId( SV_HELPTEXT_CLOSE, pResMgr ) ) );
+ aFloatBtn.SetClickHdl( LINK( this, MenuBarWindow, FloatHdl ) );
+ aFloatBtn.SetSymbol( SYMBOL_FLOAT );
+ aFloatBtn.SetQuickHelpText( XubString( ResId( SV_HELPTEXT_RESTORE, pResMgr ) ) );
+ aHideBtn.SetClickHdl( LINK( this, MenuBarWindow, HideHdl ) );
+ aHideBtn.SetSymbol( SYMBOL_HIDE );
+ aHideBtn.SetQuickHelpText( XubString( ResId( SV_HELPTEXT_MINIMIZE, pResMgr ) ) );
+}
+
+MenuBarWindow::~MenuBarWindow()
+{
+}
+
+void MenuBarWindow::SetMenu( MenuBar* pMen )
+{
+ pMenu = pMen;
+ KillActivePopup();
+ nHighlightedItem = ITEMPOS_INVALID;
+ ImplInitMenuWindow( this, TRUE );
+ if ( pMen )
+ {
+ aCloser.Show( pMen->HasCloser() );
+ aFloatBtn.Show( pMen->HasFloatButton() );
+ aHideBtn.Show( pMen->HasHideButton() );
+ }
+ Invalidate();
+}
+
+void MenuBarWindow::ShowButtons( BOOL bClose, BOOL bFloat, BOOL bHide )
+{
+ aCloser.Show( bClose );
+ aFloatBtn.Show( bFloat );
+ aHideBtn.Show( bHide );
+ Resize();
+}
+
+IMPL_LINK( MenuBarWindow, CloserHdl, PushButton*, EMPTYARG )
+{
+ return ((MenuBar*)pMenu)->GetCloserHdl().Call( pMenu );
+}
+
+IMPL_LINK( MenuBarWindow, FloatHdl, PushButton*, EMPTYARG )
+{
+ return ((MenuBar*)pMenu)->GetFloatButtonClickHdl().Call( pMenu );
+}
+
+IMPL_LINK( MenuBarWindow, HideHdl, PushButton*, EMPTYARG )
+{
+ return ((MenuBar*)pMenu)->GetHideButtonClickHdl().Call( pMenu );
+}
+
+void MenuBarWindow::ImplCreatePopup( BOOL bPreSelectFirst )
+{
+ MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
+ if ( pData )
+ {
+ if ( pActivePopup && ( pActivePopup != pData->pSubMenu ) )
+ {
+ KillActivePopup();
+ }
+ if ( pData->bEnabled && pData->pSubMenu && ( nHighlightedItem != ITEMPOS_INVALID ) && ( pData->pSubMenu != pActivePopup ) )
+ {
+ pActivePopup = (PopupMenu*)pData->pSubMenu;
+ long nX = 0;
+ MenuItemData* pData = 0;
+ for ( ULONG n = 0; n < nHighlightedItem; n++ )
+ {
+ pData = pMenu->GetItemList()->GetDataFromPos( n );
+ nX += pData->aSz.Width();
+ }
+ pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
+// Point MyPos = GetPosPixel();
+ Point aItemTopLeft( nX, 0 );
+ Point aItemBottomRight( aItemTopLeft );
+ aItemBottomRight.X() += pData->aSz.Width();
+
+ // Im Vollbild-Modus hat die MenuBar ggf. die Hoehe 0:
+ // Nicht immer einfach die Window-Hoehe nehmen, weil ItemHeight < WindowHeight.
+ if ( GetSizePixel().Height() )
+ aItemBottomRight.Y() += pData->aSz.Height();
+
+ // ImplExecute ist doch nicht modal...
+ GrabFocus();
+ pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_DOWN, pMenu, bPreSelectFirst );
+ if ( pActivePopup )
+ {
+ // Hat kein Window, wenn vorher abgebrochen oder keine Eintraege
+ if ( pActivePopup->ImplGetFloatingWindow() )
+ pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this );
+ else
+ pActivePopup = NULL;
+ }
+ }
+ }
+}
+
+
+void MenuBarWindow::KillActivePopup()
+{
+ if ( pActivePopup )
+ {
+ if ( pActivePopup->bInCallback )
+ pActivePopup->bCanceled = TRUE;
+
+ pActivePopup->bInCallback = TRUE;
+ pActivePopup->Deactivate();
+ pActivePopup->bInCallback = FALSE;
+ // Abfrage auf pActivePopup, falls im Deactivate abgeschossen...
+ if ( pActivePopup && pActivePopup->ImplGetWindow() )
+ {
+ pActivePopup->ImplGetFloatingWindow()->StopExecute();
+ delete pActivePopup->pWindow;
+ pActivePopup->pWindow = NULL;
+ }
+ pActivePopup = 0;
+ }
+}
+
+void MenuBarWindow::PopupClosed( Menu* pPopup )
+{
+ if ( pPopup == pActivePopup )
+ {
+ KillActivePopup();
+ ChangeHighlightItem( ITEMPOS_INVALID, FALSE );
+ }
+}
+
+void MenuBarWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ mbAutoPopup = TRUE;
+ USHORT nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
+ if ( ( nEntry != ITEMPOS_INVALID ) && ( nEntry != nHighlightedItem ) )
+ {
+ ChangeHighlightItem( nEntry, ImplIsMouseFollow() ? FALSE : TRUE );
+ }
+ else
+ {
+ KillActivePopup();
+ ChangeHighlightItem( ITEMPOS_INVALID, FALSE );
+ }
+}
+
+void MenuBarWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+}
+
+void MenuBarWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ // Im Move nur Highlighten, wenn schon eins gehighlightet.
+ if ( rMEvt.IsSynthetic() || rMEvt.IsLeaveWindow() || ( nHighlightedItem == ITEMPOS_INVALID ) )
+ return;
+
+ USHORT nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
+ if ( ( nEntry != ITEMPOS_INVALID ) && ( nEntry != nHighlightedItem )
+ && ( ImplIsMouseFollow() || ( rMEvt.GetButtons() == MOUSE_LEFT ) ) )
+ ChangeHighlightItem( nEntry, FALSE );
+}
+
+void MenuBarWindow::ChangeHighlightItem( USHORT n, BOOL bSelectEntry, BOOL bAllowRestoreFocus )
+{
+ // #57934# ggf. das aktive Popup sofort schliessen, damit TH's Hintergrundsicherung funktioniert.
+ MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
+ if ( pActivePopup && pActivePopup->ImplGetWindow() && ( !pNextData || ( pActivePopup != pNextData->pSubMenu ) ) )
+ KillActivePopup(); // pActivePopup ggf. ohne pWin, wenn in Activate() Rescheduled wurde
+
+ // Activate am MenuBar immer nur einmal pro Vorgang...
+ BOOL bJustActivated = FALSE;
+ if ( ( nHighlightedItem == ITEMPOS_INVALID ) && ( n != ITEMPOS_INVALID ) )
+ {
+ ImplGetSVData()->maWinData.mbNoDeactivate = TRUE;
+ nSaveFocusId = Window::SaveFocus();
+ pMenu->bInCallback = TRUE; // hier schon setzen, falls Activate ueberladen
+ pMenu->Activate();
+ pMenu->bInCallback = FALSE;
+ bJustActivated = TRUE;
+ }
+ else if ( ( nHighlightedItem != ITEMPOS_INVALID ) && ( n == ITEMPOS_INVALID ) )
+ {
+ pMenu->bInCallback = TRUE;
+ pMenu->Deactivate();
+ pMenu->bInCallback = FALSE;
+ ULONG nTempFocusId = nSaveFocusId;
+ nSaveFocusId = 0;
+ ImplGetSVData()->maWinData.mbNoDeactivate = FALSE;
+ Window::EndSaveFocus( nTempFocusId, bAllowRestoreFocus );
+ }
+
+ if ( nHighlightedItem != ITEMPOS_INVALID )
+ HighlightItem( nHighlightedItem, FALSE );
+
+ nHighlightedItem = (USHORT)n;
+ DBG_ASSERT( ( nHighlightedItem == ITEMPOS_INVALID ) || pMenu->ImplIsVisible( nHighlightedItem ), "ChangeHighlightItem: Not visible!" );
+ HighlightItem( nHighlightedItem, TRUE );
+ pMenu->ImplCallHighlight( nHighlightedItem );
+
+ if ( mbAutoPopup )
+ ImplCreatePopup( bSelectEntry );
+
+ // #58935# #73659# Focus, wenn kein Popup drunter haengt...
+ if ( bJustActivated && !pActivePopup )
+ GrabFocus();
+}
+
+void MenuBarWindow::HighlightItem( USHORT nPos, BOOL bHighlight )
+{
+ long nX = 0;
+ ULONG nCount = pMenu->pItemList->Count();
+ for ( ULONG n = 0; n < nCount; n++ )
+ {
+ MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
+ if ( n == nPos )
+ {
+ if ( pData->eType != MENUITEM_SEPARATOR )
+ {
+ if ( bHighlight )
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
+ else
+ SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
+
+ DrawRect( Rectangle( Point( nX, 1 ), Size( pData->aSz.Width(), pData->aSz.Height()-2 ) ) );
+ pMenu->ImplPaint( this, 0, 0, pData, bHighlight );
+ }
+ return;
+ }
+
+ nX += pData->aSz.Width();
+ }
+}
+
+void MenuBarWindow::KeyInput( const KeyEvent& rKEvent )
+{
+ if ( !ImplHandleKeyEvent( rKEvent ) )
+ Window::KeyInput( rKEvent );
+}
+
+BOOL MenuBarWindow::ImplHandleKeyEvent( const KeyEvent& rKEvent, BOOL bFromMenu )
+{
+ if ( pMenu->bInCallback )
+ return TRUE; // schlucken
+
+ BOOL bDone = FALSE;
+ USHORT nCode = rKEvent.GetKeyCode().GetCode();
+ if ( nCode == KEY_MENU )
+ {
+ mbAutoPopup = FALSE;
+ if ( nHighlightedItem == ITEMPOS_INVALID )
+ {
+ ChangeHighlightItem( 0, FALSE );
+ GrabFocus();
+ }
+ else
+ {
+ ChangeHighlightItem( ITEMPOS_INVALID, FALSE );
+ nSaveFocusId = 0;
+ }
+ bDone = TRUE;
+ }
+ else if ( bFromMenu )
+ {
+ if ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) )
+ {
+ USHORT n = nHighlightedItem;
+ if ( n == ITEMPOS_INVALID )
+ {
+ if ( nCode == KEY_LEFT)
+ n = 0;
+ else
+ n = pMenu->GetItemCount()-1;
+ }
+
+ USHORT nLoop = n;
+ do
+ {
+ if ( nCode == KEY_LEFT )
+ {
+ if ( n )
+ n--;
+ else
+ n = pMenu->GetItemCount()-1;
+ }
+ else
+ {
+ n++;
+ if ( n >= pMenu->GetItemCount() )
+ n = 0;
+ }
+
+ MenuItemData* pData = (MenuItemData*)pMenu->GetItemList()->GetDataFromPos( n );
+ if ( ( pData->eType != MENUITEM_SEPARATOR ) && pMenu->ImplIsVisible( n ) )
+ {
+ ChangeHighlightItem( n, TRUE );
+ break;
+ }
+ } while ( n != nLoop );
+ bDone = TRUE;
+ }
+ else if ( nCode == KEY_RETURN )
+ {
+ KillActivePopup();
+ bDone = TRUE;
+ }
+ else if ( ( nCode == KEY_UP ) || ( nCode == KEY_DOWN ) )
+ {
+ if ( !mbAutoPopup )
+ {
+ ImplCreatePopup( TRUE );
+ mbAutoPopup = TRUE;
+ }
+ bDone = TRUE;
+ }
+ else if ( nCode == KEY_ESCAPE)
+ {
+ ChangeHighlightItem( ITEMPOS_INVALID, FALSE );
+ bDone = TRUE;
+ }
+ }
+
+ if ( !bDone && ( bFromMenu || rKEvent.GetKeyCode().IsControlMod() ) )
+ {
+ xub_Unicode nCharCode = rKEvent.GetCharCode();
+ if ( nCharCode )
+ {
+ USHORT nEntry;
+ MenuItemData* pData = pMenu->GetItemList()->SearchItem( nCharCode, nEntry );
+ if ( pData && (nEntry != ITEMPOS_INVALID) )
+ {
+ mbAutoPopup = TRUE;
+ ChangeHighlightItem( nEntry, TRUE );
+ bDone = TRUE;
+ }
+ else
+ {
+ // Wegen Systemmenu und anderen System-HotKeys, nur
+ // eigenstaendige Character-Kombinationen auswerten
+ USHORT nKeyCode = rKEvent.GetKeyCode().GetCode();
+ if ( !nKeyCode ||
+ ((nKeyCode >= KEY_A) && (nKeyCode <= KEY_Z)) )
+ Sound::Beep();
+ }
+ }
+ }
+ return bDone;
+}
+
+void MenuBarWindow::Paint( const Rectangle& rRect )
+{
+ pMenu->ImplPaint( this, 0 );
+ if ( nHighlightedItem != ITEMPOS_INVALID )
+ HighlightItem( nHighlightedItem, TRUE );
+}
+
+void MenuBarWindow::Resize()
+{
+ Size aOutSz = GetOutputSizePixel();
+ long n = aOutSz.Height()-4;
+ long nX = aOutSz.Width()-3;
+ long nY = 2;
+
+ ULONG nStyle = GetSettings().GetStyleSettings().GetOptions();
+ if ( nStyle & (STYLE_OPTION_OS2STYLE | STYLE_OPTION_UNIXSTYLE | STYLE_OPTION_MACSTYLE) )
+ {
+ if ( nStyle & STYLE_OPTION_OS2STYLE )
+ {
+ nX += 3;
+ nY -= 2;
+ n += 4;
+ }
+
+ if ( aFloatBtn.IsVisible() )
+ {
+ nX -= n;
+ aFloatBtn.SetPosSizePixel( nX, nY, n, n );
+ }
+ if ( aHideBtn.IsVisible() )
+ {
+ nX -= n;
+ aHideBtn.SetPosSizePixel( nX, nY, n, n );
+ }
+ if ( nStyle & (STYLE_OPTION_MACSTYLE | STYLE_OPTION_UNIXSTYLE) )
+ {
+ if ( aFloatBtn.IsVisible() || aHideBtn.IsVisible() )
+ nX -= 3;
+ }
+ if ( aCloser.IsVisible() )
+ {
+ nX -= n;
+ aCloser.SetPosSizePixel( nX, nY, n, n );
+ }
+ }
+ else
+ {
+ if ( aCloser.IsVisible() )
+ {
+ nX -= n;
+ aCloser.SetPosSizePixel( nX, nY, n, n );
+ nX -= 3;
+ }
+ if ( aFloatBtn.IsVisible() )
+ {
+ nX -= n;
+ aFloatBtn.SetPosSizePixel( nX, nY, n, n );
+ }
+ if ( aHideBtn.IsVisible() )
+ {
+ nX -= n;
+ aHideBtn.SetPosSizePixel( nX, nY, n, n );
+ }
+ }
+
+ if ( nStyle & STYLE_OPTION_OS2STYLE )
+ aFloatBtn.SetSymbol( SYMBOL_OS2FLOAT );
+ else
+ aFloatBtn.SetSymbol( SYMBOL_FLOAT );
+ if ( nStyle & STYLE_OPTION_OS2STYLE )
+ aHideBtn.SetSymbol( SYMBOL_OS2HIDE );
+ else
+ aHideBtn.SetSymbol( SYMBOL_HIDE );
+ if ( nStyle & STYLE_OPTION_OS2STYLE )
+ aCloser.SetSymbol( SYMBOL_OS2CLOSE );
+ else
+ aCloser.SetSymbol( SYMBOL_CLOSE );
+}
+
+USHORT MenuBarWindow::ImplFindEntry( const Point& rMousePos ) const
+{
+ long nX = 0;
+ USHORT nCount = (USHORT)pMenu->pItemList->Count();
+ for ( USHORT n = 0; n < nCount; n++ )
+ {
+ MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
+ if ( pMenu->ImplIsVisible( n ) )
+ {
+ nX += pData->aSz.Width();
+ if ( nX > rMousePos.X() )
+ return (USHORT)n;
+ }
+ }
+ return ITEMPOS_INVALID;
+}
+
+void MenuBarWindow::RequestHelp( const HelpEvent& rHEvt )
+{
+ USHORT nId = nHighlightedItem;
+ if ( rHEvt.GetMode() & (HELPMODE_CONTEXT | HELPMODE_EXTENDED) )
+ ChangeHighlightItem( ITEMPOS_INVALID, TRUE );
+ if( !ImplHandleHelpEvent( this, pMenu, nId, rHEvt ) )
+ Window::RequestHelp( rHEvt );
+}
+
+BOOL MenuBarWindow::QueryDrop( DropEvent& rDEvt )
+{
+ Window* pW = GetParent()->ImplGetWindow();
+ DropEvent aEvent( ImplTranslateDropEvent( rDEvt, this, pW ) );
+ BOOL bRet = pW->QueryDrop( aEvent );
+ rDEvt = aEvent;
+ return bRet;
+}
+
+BOOL MenuBarWindow::Drop( const DropEvent& rDEvt )
+{
+ Window* pW = GetParent()->ImplGetWindow();
+ return pW->Drop( ImplTranslateDropEvent( rDEvt, this, pW ) );
+}
+
+
+void MenuBarWindow::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) ||
+ ( nType == STATE_CHANGE_CONTROLBACKGROUND ) )
+ {
+ ImplInitMenuWindow( this, FALSE );
+ Invalidate();
+ }
+}
+
+void MenuBarWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitMenuWindow( this, TRUE );
+ // Falls sich der Font geaendert hat.
+ long nHeight = pMenu->ImplCalcSize( this ).Height();
+ SetPosSizePixel( 0, 0, 0, nHeight, WINDOW_POSSIZE_HEIGHT );
+ GetParent()->Resize();
+ Invalidate();
+ Resize();
+ }
+}
+
+void MenuBarWindow::LoseFocus()
+{
+ if ( !HasChildPathFocus( TRUE ) )
+ ChangeHighlightItem( ITEMPOS_INVALID, FALSE, FALSE );
+}
diff --git a/vcl/source/window/mnemonic.cxx b/vcl/source/window/mnemonic.cxx
new file mode 100644
index 000000000000..ea1b7b0cea29
--- /dev/null
+++ b/vcl/source/window/mnemonic.cxx
@@ -0,0 +1,260 @@
+/*************************************************************************
+ *
+ * $RCSfile: mnemonic.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_MNEMONIC_CXX
+
+#include <string.h>
+#include <svapp.hxx>
+#include <settings.hxx>
+#include <mnemonic.hxx>
+
+#include <unohelp.hxx>
+
+#ifndef _COM_SUN_STAR_LANG_XCHARACTERCLASSIFICATION_HPP_
+#include <com/sun/star/lang/XCharacterClassification.hpp>
+#endif
+
+using namespace ::com::sun::star;
+
+
+// =======================================================================
+
+ImplMnemonicGenerator::ImplMnemonicGenerator()
+{
+ memset( maMnemonics, 1, sizeof( maMnemonics ) );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ImplMnemonicGenerator::ImplGetMnemonicIndex( sal_Unicode c )
+{
+ static USHORT const aImplMnemonicRangeTab[MNEMONIC_RANGES*2] =
+ {
+ MNEMONIC_RANGE_1_START, MNEMONIC_RANGE_1_END,
+ MNEMONIC_RANGE_2_START, MNEMONIC_RANGE_2_END,
+ MNEMONIC_RANGE_3_START, MNEMONIC_RANGE_3_END,
+ MNEMONIC_RANGE_4_START, MNEMONIC_RANGE_4_END
+ };
+
+ USHORT nMnemonicIndex = 0;
+ for ( USHORT i = 0; i < MNEMONIC_RANGES; i++ )
+ {
+ if ( (c >= aImplMnemonicRangeTab[i*2]) &&
+ (c <= aImplMnemonicRangeTab[i*2+1]) )
+ return nMnemonicIndex+c-aImplMnemonicRangeTab[i*2];
+
+ nMnemonicIndex += aImplMnemonicRangeTab[i*2+1]-aImplMnemonicRangeTab[i*2];
+ }
+
+ return MNEMONIC_INDEX_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Unicode ImplMnemonicGenerator::ImplFindMnemonic( const XubString& rKey )
+{
+ xub_StrLen nIndex = 0;
+ while ( (nIndex = rKey.Search( MNEMONIC_CHAR, nIndex )) != STRING_NOTFOUND )
+ {
+ sal_Unicode cMnemonic = rKey.GetChar( nIndex+1 );
+ if ( cMnemonic != MNEMONIC_CHAR )
+ return cMnemonic;
+ nIndex += 2;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplMnemonicGenerator::RegisterMnemonic( const XubString& rKey )
+{
+ const ::com::sun::star::lang::Locale& rLocale = Application::GetSettings().GetLocale();
+ uno::Reference < lang::XCharacterClassification > xCharClass = GetCharClass();
+
+ XubString aKey = xCharClass->toUpper( rKey, 0, rKey.Len(), rLocale );
+
+ // If we find a Mnemonic, set the flag. In other case count the
+ // characters, because we need this to set most as possible
+ // Mnemonics
+ sal_Unicode cMnemonic = ImplFindMnemonic( aKey );
+ if ( cMnemonic )
+ {
+ USHORT nMnemonicIndex = ImplGetMnemonicIndex( cMnemonic );
+ if ( nMnemonicIndex != MNEMONIC_INDEX_NOTFOUND )
+ maMnemonics[nMnemonicIndex] = 0;
+ }
+ else
+ {
+ xub_StrLen nIndex = 0;
+ xub_StrLen nLen = aKey.Len();
+ while ( nIndex < nLen )
+ {
+ sal_Unicode c = aKey.GetChar( nIndex );
+
+ USHORT nMnemonicIndex = ImplGetMnemonicIndex( c );
+ if ( nMnemonicIndex != MNEMONIC_INDEX_NOTFOUND )
+ {
+ if ( maMnemonics[nMnemonicIndex] && (maMnemonics[nMnemonicIndex] < 0xFF) )
+ maMnemonics[nMnemonicIndex]++;
+ }
+
+ nIndex++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplMnemonicGenerator::CreateMnemonic( XubString& rKey )
+{
+ if ( !rKey.Len() || ImplFindMnemonic( rKey ) )
+ return FALSE;
+
+ const ::com::sun::star::lang::Locale& rLocale = Application::GetSettings().GetLocale();
+ uno::Reference < lang::XCharacterClassification > xCharClass = GetCharClass();
+
+ XubString aKey = xCharClass->toUpper( rKey, 0, rKey.Len(), rLocale );
+
+ BOOL bChanged = FALSE;
+ xub_StrLen nLen = aKey.Len();
+
+ // 1) Anfangsbuchstaben werden bevorzugt
+ USHORT nMnemonicIndex;
+ sal_Unicode c;
+ xub_StrLen nIndex = 0;
+ do
+ {
+ c = aKey.GetChar( nIndex );
+ nMnemonicIndex = ImplGetMnemonicIndex( c );
+ if ( nMnemonicIndex != MNEMONIC_INDEX_NOTFOUND )
+ {
+ if ( maMnemonics[nMnemonicIndex] )
+ {
+ maMnemonics[nMnemonicIndex] = 0;
+ rKey.Insert( MNEMONIC_CHAR, nIndex );
+ bChanged = TRUE;
+ break;
+ }
+ }
+
+ // Search for next word
+ do
+ {
+ nIndex++;
+ c = aKey.GetChar( nIndex );
+ if ( c == ' ' )
+ break;
+ }
+ while ( nIndex < nLen );
+ nIndex++;
+ }
+ while ( nIndex < nLen );
+
+ // 2) Eindeutiger/seltender Buchstabe enthalten?
+ if ( !bChanged )
+ {
+ USHORT nBestCount = 0xFFFF;
+ USHORT nBestMnemonicIndex;
+ xub_StrLen nBestIndex;
+ nIndex = 0;
+ do
+ {
+ c = aKey.GetChar( nIndex );
+ nMnemonicIndex = ImplGetMnemonicIndex( c );
+ if ( nMnemonicIndex != MNEMONIC_INDEX_NOTFOUND )
+ {
+ if ( maMnemonics[nMnemonicIndex] )
+ {
+ if ( maMnemonics[nMnemonicIndex] < nBestCount )
+ {
+ nBestCount = maMnemonics[nMnemonicIndex];
+ nBestIndex = nIndex;
+ nBestMnemonicIndex = nMnemonicIndex;
+ if ( nBestCount == 2 )
+ break;
+ }
+ }
+ }
+
+ nIndex++;
+ }
+ while ( nIndex < nLen );
+
+ if ( nBestCount != 0xFFFF )
+ {
+ maMnemonics[nBestMnemonicIndex] = 0;
+ rKey.Insert( MNEMONIC_CHAR, nBestIndex );
+ bChanged = TRUE;
+ }
+ }
+
+ return bChanged;
+}
+
+uno::Reference< lang::XCharacterClassification > ImplMnemonicGenerator::GetCharClass()
+{
+ if ( !xCharClass.is() )
+ xCharClass = vcl::unohelper::CreateCharacterClassification();
+ return xCharClass;
+}
+
+
diff --git a/vcl/source/window/msgbox.cxx b/vcl/source/window/msgbox.cxx
new file mode 100644
index 000000000000..ce045114c1ae
--- /dev/null
+++ b/vcl/source/window/msgbox.cxx
@@ -0,0 +1,548 @@
+/*************************************************************************
+ *
+ * $RCSfile: msgbox.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_MSGBOX_CXX
+
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_METRIC_HXX
+#include <metric.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_FIXED_HXX
+#include <fixed.hxx>
+#endif
+#ifndef _SV_SOUND_HXX
+#include <sound.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+#ifndef _SV_MSGBOX_HXX
+#include <msgbox.hxx>
+#endif
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+static void ImplInitMsgBoxImageList()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->maWinData.mpMsgBoxImgList )
+ {
+ Bitmap aBmp( ResId( SV_RESID_BITMAP_MSGBOX, ImplGetResMgr() ) );
+ pSVData->maWinData.mpMsgBoxImgList = new ImageList( aBmp, Color( 0xC0, 0xC0, 0xC0 ), 4 );
+ }
+}
+
+// =======================================================================
+
+void MessBox::ImplInitData()
+{
+ mpFixedText = NULL;
+ mpFixedImage = NULL;
+ mnSoundType = 0;
+ mbHelpBtn = FALSE;
+ mbSound = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void MessBox::ImplInitButtons()
+{
+ WinBits nStyle = GetStyle();
+ USHORT nOKFlags = 0;
+ USHORT nCancelFlags = BUTTONDIALOG_CANCELBUTTON;
+ USHORT nRetryFlags = 0;
+ USHORT nYesFlags = 0;
+ USHORT nNoFlags = 0;
+
+ if ( nStyle & WB_OK_CANCEL )
+ {
+ if ( nStyle & WB_DEF_CANCEL )
+ nCancelFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+ else // WB_DEF_OK
+ nOKFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+
+ AddButton( BUTTON_OK, BUTTONID_OK, nOKFlags );
+ AddButton( BUTTON_CANCEL, BUTTONID_CANCEL, nCancelFlags );
+ }
+ else if ( nStyle & WB_YES_NO )
+ {
+ if ( nStyle & WB_DEF_YES )
+ nYesFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+ else // WB_DEF_NO
+ nNoFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+ nNoFlags |= BUTTONDIALOG_CANCELBUTTON;
+
+ AddButton( BUTTON_YES, BUTTONID_YES, nYesFlags );
+ AddButton( BUTTON_NO, BUTTONID_NO, nNoFlags );
+ }
+ else if ( nStyle & WB_YES_NO_CANCEL )
+ {
+ if ( nStyle & WB_DEF_YES )
+ nYesFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+ else if ( nStyle & WB_DEF_NO )
+ nNoFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+ else
+ nCancelFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+
+ AddButton( BUTTON_YES, BUTTONID_YES, nYesFlags );
+ AddButton( BUTTON_NO, BUTTONID_NO, nNoFlags );
+ AddButton( BUTTON_CANCEL, BUTTONID_CANCEL, nCancelFlags );
+ }
+ else if ( nStyle & WB_RETRY_CANCEL )
+ {
+ if ( nStyle & WB_DEF_CANCEL )
+ nCancelFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+ else // WB_DEF_RETRY
+ nRetryFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+
+ AddButton( BUTTON_RETRY, BUTTONID_RETRY, nRetryFlags );
+ AddButton( BUTTON_CANCEL, BUTTONID_CANCEL, nCancelFlags );
+
+ }
+ else if ( nStyle & WB_OK )
+ {
+ nOKFlags |= BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_CANCELBUTTON | BUTTONDIALOG_FOCUSBUTTON;
+
+ AddButton( BUTTON_OK, BUTTONID_OK, nOKFlags );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+MessBox::MessBox( WindowType nType ) :
+ ButtonDialog( WINDOW_MESSBOX )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+MessBox::MessBox( Window* pParent, WinBits nStyle,
+ const XubString& rTitle, const XubString& rMessage ) :
+ ButtonDialog( WINDOW_MESSBOX ),
+ maMessText( rMessage )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle | WB_MOVEABLE | WB_HORZ | WB_CENTER );
+ ImplInitButtons();
+
+ if ( rTitle.Len() )
+ SetText( rTitle );
+}
+
+// -----------------------------------------------------------------------
+
+MessBox::MessBox( Window* pParent, const ResId& rResId ) :
+ ButtonDialog( WINDOW_MESSBOX )
+{
+ ImplInitData();
+
+ GetRes( rResId.SetRT( RSC_MESSBOX ) );
+ USHORT nHiButtons = ReadShortRes();
+ USHORT nLoButtons = ReadShortRes();
+ USHORT nHiDefButton = ReadShortRes();
+ USHORT nLoDefButton = ReadShortRes();
+ USHORT nHiHelpId = ReadShortRes();
+ USHORT nLoHelpId = ReadShortRes();
+ USHORT bSysModal = ReadShortRes();
+ SetHelpId( ((ULONG)nHiHelpId << 16) + nLoHelpId );
+ WinBits nBits = (((ULONG)nHiButtons << 16) + nLoButtons) |
+ (((ULONG)nHiDefButton << 16) + nLoDefButton);
+ ImplInit( pParent, nBits | WB_MOVEABLE | WB_HORZ | WB_CENTER );
+
+ ImplLoadRes( rResId );
+ ImplInitButtons();
+}
+
+// -----------------------------------------------------------------------
+
+void MessBox::ImplLoadRes( const ResId& rResId )
+{
+ SetText( ReadStringRes() );
+ SetMessText( ReadStringRes() );
+ SetHelpText( ReadStringRes() );
+}
+
+// -----------------------------------------------------------------------
+
+MessBox::~MessBox()
+{
+ if ( mpFixedText )
+ delete mpFixedText;
+ if ( mpFixedImage )
+ delete mpFixedImage;
+}
+
+// -----------------------------------------------------------------------
+
+void MessBox::ImplPosControls()
+{
+ if ( GetHelpId() )
+ {
+ if ( !mbHelpBtn )
+ {
+ AddButton( BUTTON_HELP, BUTTONID_HELP, BUTTONDIALOG_HELPBUTTON, 3 );
+ mbHelpBtn = TRUE;
+ }
+ }
+ else
+ {
+ if ( mbHelpBtn )
+ {
+ RemoveButton( BUTTONID_HELP );
+ mbHelpBtn = FALSE;
+ }
+ }
+
+ XubString aMessText( maMessText );
+ TextRectInfo aTextInfo;
+ Rectangle aRect( 0, 0, 30000, 30000 );
+ Rectangle aFormatRect;
+ Point aTextPos( IMPL_DIALOG_OFFSET, IMPL_DIALOG_OFFSET+IMPL_MSGBOX_OFFSET_EXTRA_Y );
+ Size aImageSize;
+ Size aPageSize;
+ Size aFixedSize;
+ long nTitleWidth;
+ long nButtonSize = ImplGetButtonSize();
+ long nMaxWidth = GetDesktopRectPixel().GetWidth()-8;
+ long nMaxLineWidth;
+ long nWidth;
+ WinBits nWinStyle = WB_LEFT | WB_WORDBREAK | WB_NOLABEL | WB_INFO;
+ USHORT nTextStyle = TEXT_DRAW_MULTILINE | TEXT_DRAW_TOP | TEXT_DRAW_LEFT;
+
+ if ( mpFixedText )
+ delete mpFixedText;
+ if ( mpFixedImage )
+ {
+ delete mpFixedImage;
+ mpFixedImage = NULL;
+ }
+
+ // Message-Text um Tabs bereinigen
+ XubString aTabStr( RTL_CONSTASCII_USTRINGPARAM( " " ) );
+ USHORT nIndex = 0;
+ while ( nIndex != STRING_NOTFOUND )
+ nIndex = aMessText.SearchAndReplace( '\t', aTabStr, nIndex );
+
+ // Wenn Fenster zu schmall, machen wir Dialog auch breiter
+ if ( mbFrame )
+ nMaxWidth = 630;
+ else if ( nMaxWidth < 120 )
+ nMaxWidth = 120;
+
+ nMaxWidth -= mnLeftBorder+mnRightBorder+4;
+
+ // MessageBox sollte min. so breit sein, das auch Title sichtbar ist
+ // Extra-Width for Closer, because Closer is set after this call
+ nTitleWidth = CalcTitleWidth();
+ nTitleWidth += mnTopBorder;
+
+ nMaxWidth -= (IMPL_DIALOG_OFFSET*2)+(IMPL_MSGBOX_OFFSET_EXTRA_X*2);
+
+ // Wenn wir ein Image haben, dann deren Groesse ermitteln und das
+ // entsprechende Control anlegen und positionieren
+ aImageSize = maImage.GetSizePixel();
+ if ( aImageSize.Width() )
+ {
+ aImageSize.Width() += 4;
+ aImageSize.Height() += 4;
+ aTextPos.X() += aImageSize.Width()+IMPL_SEP_MSGBOX_IMAGE;
+ mpFixedImage = new FixedImage( this );
+ mpFixedImage->SetPosSizePixel( Point( IMPL_DIALOG_OFFSET-2+IMPL_MSGBOX_OFFSET_EXTRA_X,
+ IMPL_DIALOG_OFFSET-2+IMPL_MSGBOX_OFFSET_EXTRA_Y ),
+ aImageSize );
+ mpFixedImage->SetImage( maImage );
+ mpFixedImage->Show();
+ nMaxWidth -= aImageSize.Width()+IMPL_SEP_MSGBOX_IMAGE;
+ }
+ else
+ aTextPos.X() += IMPL_MSGBOX_OFFSET_EXTRA_X;
+
+ // Maximale Zeilenlaenge ohne Wordbreak ermitteln
+ aFormatRect = GetTextRect( aRect, aMessText, nTextStyle, &aTextInfo );
+ nMaxLineWidth = aFormatRect.GetWidth();
+ nTextStyle |= TEXT_DRAW_WORDBREAK;
+
+ // Breite fuer Textformatierung ermitteln
+ if ( nMaxLineWidth > 450 )
+ nWidth = 450;
+ else if ( nMaxLineWidth > 300 )
+ nWidth = nMaxLineWidth+5;
+ else
+ nWidth = 300;
+ if ( nButtonSize > nWidth )
+ nWidth = nButtonSize-(aTextPos.X()-IMPL_DIALOG_OFFSET);
+ if ( nWidth > nMaxWidth )
+ nWidth = nMaxWidth;
+
+ aRect.Right() = nWidth;
+ aFormatRect = GetTextRect( aRect, aMessText, nTextStyle, &aTextInfo );
+ if ( aTextInfo.GetMaxLineWidth() > nWidth )
+ {
+ nWidth = aTextInfo.GetMaxLineWidth()+8;
+ aRect.Right() = nWidth;
+ aFormatRect = GetTextRect( aRect, aMessText, nTextStyle, &aTextInfo );
+ }
+
+ // Style fuer FixedText ermitteln
+ aPageSize.Width() = aImageSize.Width();
+ aFixedSize.Width() = aTextInfo.GetMaxLineWidth()+1;
+ aFixedSize.Height() = aFormatRect.GetHeight();
+ if ( aFixedSize.Height() < aImageSize.Height() )
+ {
+ nWinStyle |= WB_VCENTER;
+ aPageSize.Height() = aImageSize.Height();
+ aFixedSize.Height() = aImageSize.Height();
+ }
+ else
+ {
+ nWinStyle |= WB_TOP;
+ aPageSize.Height() = aFixedSize.Height();
+ }
+ if ( aImageSize.Width() )
+ aPageSize.Width() += IMPL_SEP_MSGBOX_IMAGE;
+ aPageSize.Width() += (IMPL_DIALOG_OFFSET*2)+(IMPL_MSGBOX_OFFSET_EXTRA_X*2);
+ aPageSize.Width() += aFixedSize.Width()+1;
+ aPageSize.Height() += (IMPL_DIALOG_OFFSET*2)+(IMPL_MSGBOX_OFFSET_EXTRA_Y*2);
+ if ( aPageSize.Width() < IMPL_MINSIZE_MSGBOX_WIDTH )
+ aPageSize.Width() = IMPL_MINSIZE_MSGBOX_WIDTH;
+ if ( aPageSize.Width() < nTitleWidth )
+ aPageSize.Width() = nTitleWidth;
+ mpFixedText = new FixedText( this, nWinStyle );
+ mpFixedText->SetPosSizePixel( aTextPos, aFixedSize );
+ mpFixedText->SetText( aMessText );
+ mpFixedText->Show();
+ SetPageSizePixel( aPageSize );
+}
+
+// -----------------------------------------------------------------------
+
+void MessBox::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ ImplPosControls();
+ if ( mbSound && mnSoundType )
+ Sound::Beep( (SoundType)(mnSoundType-1), this );
+ }
+ ButtonDialog::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void InfoBox::ImplInitData()
+{
+ // Default Text is the display title from the application
+ if ( !GetText().Len() )
+ SetText( Application::GetDisplayName() );
+
+ SetImage( InfoBox::GetStandardImage() );
+}
+
+// -----------------------------------------------------------------------
+
+InfoBox::InfoBox( Window* pParent, const XubString& rMessage ) :
+ MessBox( pParent, WB_OK | WB_DEF_OK, ImplGetSVEmptyStr(), rMessage )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+InfoBox::InfoBox( Window* pParent, const ResId & rResId ) :
+ MessBox( pParent, rResId.SetRT( RSC_INFOBOX ) )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+Image InfoBox::GetStandardImage()
+{
+ ImplInitMsgBoxImageList();
+ return ImplGetSVData()->maWinData.mpMsgBoxImgList->GetImage( 4 );
+}
+
+// -----------------------------------------------------------------------
+
+void WarningBox::ImplInitData()
+{
+ // Default Text is the display title from the application
+ if ( !GetText().Len() )
+ SetText( Application::GetDisplayName() );
+
+ SetImage( WarningBox::GetStandardImage() );
+ mnSoundType = ((USHORT)SOUND_WARNING)+1;
+}
+
+// -----------------------------------------------------------------------
+
+WarningBox::WarningBox( Window* pParent, WinBits nStyle,
+ const XubString& rMessage ) :
+ MessBox( pParent, nStyle, ImplGetSVEmptyStr(), rMessage )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+WarningBox::WarningBox( Window* pParent, const ResId& rResId ) :
+ MessBox( pParent, rResId.SetRT( RSC_WARNINGBOX ) )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+Image WarningBox::GetStandardImage()
+{
+ ImplInitMsgBoxImageList();
+ return ImplGetSVData()->maWinData.mpMsgBoxImgList->GetImage( 3 );
+}
+
+// -----------------------------------------------------------------------
+
+void ErrorBox::ImplInitData()
+{
+ // Default Text is the display title from the application
+ if ( !GetText().Len() )
+ SetText( Application::GetDisplayName() );
+
+ SetImage( ErrorBox::GetStandardImage() );
+ mnSoundType = ((USHORT)SOUND_ERROR)+1;
+}
+
+// -----------------------------------------------------------------------
+
+ErrorBox::ErrorBox( Window* pParent, WinBits nStyle,
+ const XubString& rMessage ) :
+ MessBox( pParent, nStyle, ImplGetSVEmptyStr(), rMessage )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+ErrorBox::ErrorBox( Window* pParent, const ResId& rResId ) :
+ MessBox( pParent, rResId.SetRT( RSC_ERRORBOX ) )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+Image ErrorBox::GetStandardImage()
+{
+ ImplInitMsgBoxImageList();
+ return ImplGetSVData()->maWinData.mpMsgBoxImgList->GetImage( 1 );
+}
+
+// -----------------------------------------------------------------------
+
+void QueryBox::ImplInitData()
+{
+ // Default Text is the display title from the application
+ if ( !GetText().Len() )
+ SetText( Application::GetDisplayName() );
+
+ SetImage( QueryBox::GetStandardImage() );
+ mnSoundType = ((USHORT)SOUND_QUERY)+1;
+}
+
+// -----------------------------------------------------------------------
+
+QueryBox::QueryBox( Window* pParent, WinBits nStyle, const XubString& rMessage ) :
+ MessBox( pParent, nStyle, ImplGetSVEmptyStr(), rMessage )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+QueryBox::QueryBox( Window* pParent, const ResId& rResId ) :
+ MessBox( pParent, rResId.SetRT( RSC_QUERYBOX ) )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+Image QueryBox::GetStandardImage()
+{
+ ImplInitMsgBoxImageList();
+ return ImplGetSVData()->maWinData.mpMsgBoxImgList->GetImage( 2 );
+}
diff --git a/vcl/source/window/scrwnd.cxx b/vcl/source/window/scrwnd.cxx
new file mode 100644
index 000000000000..13b6a1075e91
--- /dev/null
+++ b/vcl/source/window/scrwnd.cxx
@@ -0,0 +1,420 @@
+/*************************************************************************
+ *
+ * $RCSfile: scrwnd.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <math.h>
+#include <limits.h>
+#include <tools/debug.hxx>
+#include "svids.hrc"
+#include "svdata.hxx"
+#include "timer.hxx"
+#include "scrwnd.hxx"
+
+// -----------
+// - Defines -
+// -----------
+
+#define WHEEL_WIDTH 25
+#define WHEEL_RADIUS ((WHEEL_WIDTH) >> 1 )
+#define MAX_TIME 300
+#define MIN_TIME 20
+#define DEF_TIMEOUT 50
+
+// -------------------
+// - ImplWheelWindow -
+// -------------------
+
+ImplWheelWindow::ImplWheelWindow( Window* pParent ) :
+ FloatingWindow ( pParent, 0 ),
+ mnRepaintTime ( 1UL ),
+ mnActDist ( 0UL ),
+ mnWheelMode ( WHEELMODE_NONE ),
+ mnActDeltaX ( 0L ),
+ mnActDeltaY ( 0L ),
+ mnTimeout ( DEF_TIMEOUT )
+{
+ // we need a parent
+ DBG_ASSERT( pParent, "ImplWheelWindow::ImplWheelWindow(): Parent not set!" );
+
+ const Size aSize( pParent->GetOutputSizePixel() );
+ const USHORT nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
+ const BOOL bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
+ const BOOL bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
+
+ // calculate maximum speed distance
+ mnMaxWidth = (ULONG) ( 0.4 * hypot( (double) aSize.Width(), aSize.Height() ) );
+
+ // create wheel window
+ SetTitleType( FLOATWIN_TITLE_NONE );
+ ImplCreateImageList();
+ ImplSetRegion( Bitmap( ResId( SV_RESID_BITMAP_SCROLLMSK, ImplGetResMgr() ) ) );
+
+ // set wheel mode
+ if( bHorz && bVert )
+ ImplSetWheelMode( WHEELMODE_VH );
+ else if( bHorz )
+ ImplSetWheelMode( WHEELMODE_H );
+ else
+ ImplSetWheelMode( WHEELMODE_V );
+
+ // init timer
+ mpTimer = new Timer;
+ mpTimer->SetTimeoutHdl( LINK( this, ImplWheelWindow, ImplScrollHdl ) );
+ mpTimer->SetTimeout( mnTimeout );
+ mpTimer->Start();
+
+ CaptureMouse();
+}
+
+// ------------------------------------------------------------------------
+
+ImplWheelWindow::~ImplWheelWindow()
+{
+ ReleaseMouse();
+ mpTimer->Stop();
+ delete mpTimer;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWheelWindow::ImplSetRegion( const Bitmap& rRegionBmp )
+{
+ Point aPos( GetPointerPosPixel() );
+ const Size aSize( rRegionBmp.GetSizePixel() );
+ Point aPoint;
+ const Rectangle aRect( aPoint, aSize );
+
+ maCenter = maLastMousePos = aPos;
+ aPos.X() -= aSize.Width() >> 1;
+ aPos.Y() -= aSize.Height() >> 1;
+
+ SetPosSizePixel( aPos, aSize );
+ SetWindowRegionPixel( rRegionBmp.CreateRegion( COL_BLACK, aRect ) );
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWheelWindow::ImplCreateImageList()
+{
+ Bitmap aImgBmp( ResId( SV_RESID_BITMAP_SCROLLBMP, ImplGetResMgr() ) );
+ maImgList = ImageList( aImgBmp, 6 );
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWheelWindow::ImplSetWheelMode( ULONG nWheelMode )
+{
+ if( nWheelMode != mnWheelMode )
+ {
+ mnWheelMode = nWheelMode;
+
+ if( WHEELMODE_NONE == mnWheelMode )
+ {
+ if( IsVisible() )
+ Hide();
+ }
+ else
+ {
+ if( !IsVisible() )
+ Show();
+
+ ImplDrawWheel();
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWheelWindow::ImplDrawWheel()
+{
+ USHORT nId;
+
+ switch( mnWheelMode )
+ {
+ case( WHEELMODE_VH ): nId = 1; break;
+ case( WHEELMODE_V ): nId = 2; break;
+ case( WHEELMODE_H ): nId = 3; break;
+ case( WHEELMODE_SCROLL_VH ):nId = 4; break;
+ case( WHEELMODE_SCROLL_V ): nId = 5; break;
+ case( WHEELMODE_SCROLL_H ): nId = 6; break;
+ default: nId = 0; break;
+ }
+
+ if( nId )
+ DrawImage( Point(), maImgList.GetImage( nId ) );
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWheelWindow::ImplRecalcScrollValues()
+{
+ if( mnActDist < WHEEL_RADIUS )
+ {
+ mnActDeltaX = mnActDeltaY = 0L;
+ mnTimeout = DEF_TIMEOUT;
+ }
+ else
+ {
+ ULONG nCurTime;
+
+ // calc current time
+ if( mnMaxWidth )
+ {
+ const double fExp = ( (double) mnActDist / mnMaxWidth ) * log10( (double) MAX_TIME / MIN_TIME );
+ nCurTime = (ULONG) ( MAX_TIME / pow( 10., fExp ) );
+ }
+ else
+ nCurTime = MAX_TIME;
+
+ if( !nCurTime )
+ nCurTime = 1UL;
+
+ if( mnRepaintTime <= nCurTime )
+ mnTimeout = nCurTime - mnRepaintTime;
+ else
+ {
+ long nMult = mnRepaintTime / nCurTime;
+
+ if( !( mnRepaintTime % nCurTime ) )
+ mnTimeout = 0UL;
+ else
+ mnTimeout = ++nMult * nCurTime - mnRepaintTime;
+
+ double fValX = (double) mnActDeltaX * nMult;
+ double fValY = (double) mnActDeltaY * nMult;
+
+ if( fValX > LONG_MAX )
+ mnActDeltaX = LONG_MAX;
+ else if( fValX < LONG_MIN )
+ mnActDeltaX = LONG_MIN;
+ else
+ mnActDeltaX = (long) fValX;
+
+ if( fValY > LONG_MAX )
+ mnActDeltaY = LONG_MAX;
+ else if( fValY < LONG_MIN )
+ mnActDeltaY = LONG_MIN;
+ else
+ mnActDeltaY = (long) fValY;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+PointerStyle ImplWheelWindow::ImplGetMousePointer( long nDistX, long nDistY )
+{
+ PointerStyle eStyle;
+ const USHORT nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
+ const BOOL bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
+ const BOOL bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
+
+ if( bHorz || bVert )
+ {
+ if( mnActDist < WHEEL_RADIUS )
+ {
+ if( bHorz && bVert )
+ eStyle = POINTER_AUTOSCROLL_NSWE;
+ else if( bHorz )
+ eStyle = POINTER_AUTOSCROLL_WE;
+ else
+ eStyle = POINTER_AUTOSCROLL_NS;
+ }
+ else
+ {
+ double fAngle = atan2( (double) -nDistY, nDistX ) / F_PI180;
+
+ if( fAngle < 0.0 )
+ fAngle += 360.;
+
+ if( bHorz && bVert )
+ {
+ if( fAngle >= 22.5 && fAngle <= 67.5 )
+ eStyle = POINTER_AUTOSCROLL_NE;
+ else if( fAngle >= 67.5 && fAngle <= 112.5 )
+ eStyle = POINTER_AUTOSCROLL_N;
+ else if( fAngle >= 112.5 && fAngle <= 157.5 )
+ eStyle = POINTER_AUTOSCROLL_NW;
+ else if( fAngle >= 157.5 && fAngle <= 202.5 )
+ eStyle = POINTER_AUTOSCROLL_W;
+ else if( fAngle >= 202.5 && fAngle <= 247.5 )
+ eStyle = POINTER_AUTOSCROLL_SW;
+ else if( fAngle >= 247.5 && fAngle <= 292.5 )
+ eStyle = POINTER_AUTOSCROLL_S;
+ else if( fAngle >= 292.5 && fAngle <= 337.5 )
+ eStyle = POINTER_AUTOSCROLL_SE;
+ else
+ eStyle = POINTER_AUTOSCROLL_E;
+ }
+ else if( bHorz )
+ {
+ if( fAngle >= 270. || fAngle <= 90. )
+ eStyle = POINTER_AUTOSCROLL_E;
+ else
+ eStyle = POINTER_AUTOSCROLL_W;
+ }
+ else
+ {
+ if( fAngle >= 0. && fAngle <= 180. )
+ eStyle = POINTER_AUTOSCROLL_N;
+ else
+ eStyle = POINTER_AUTOSCROLL_S;
+ }
+ }
+ }
+ else
+ eStyle = POINTER_ARROW;
+
+ return eStyle;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWheelWindow::Paint( const Rectangle& rRect )
+{
+ ImplDrawWheel();
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWheelWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ FloatingWindow::MouseMove( rMEvt );
+
+ const Point aMousePos( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
+ const long nDistX = aMousePos.X() - maCenter.X();
+ const long nDistY = aMousePos.Y() - maCenter.Y();
+
+ mnActDist = (ULONG) hypot( (double) nDistX, nDistY );
+
+ const PointerStyle eActStyle = ImplGetMousePointer( nDistX, nDistY );
+ const USHORT nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
+ const BOOL bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
+ const BOOL bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
+ const BOOL bOuter = mnActDist > WHEEL_RADIUS;
+
+ if( bOuter && ( maLastMousePos != aMousePos ) )
+ {
+ switch( eActStyle )
+ {
+ case( POINTER_AUTOSCROLL_N ): mnActDeltaX = +0L, mnActDeltaY = +1L; break;
+ case( POINTER_AUTOSCROLL_S ): mnActDeltaX = +0L, mnActDeltaY = -1L; break;
+ case( POINTER_AUTOSCROLL_W ): mnActDeltaX = +1L, mnActDeltaY = +0L; break;
+ case( POINTER_AUTOSCROLL_E ): mnActDeltaX = -1L, mnActDeltaY = +0L; break;
+ case( POINTER_AUTOSCROLL_NW ): mnActDeltaX = +1L, mnActDeltaY = +1L; break;
+ case( POINTER_AUTOSCROLL_NE ): mnActDeltaX = -1L, mnActDeltaY = +1L; break;
+ case( POINTER_AUTOSCROLL_SW ): mnActDeltaX = +1L, mnActDeltaY = -1L; break;
+ case( POINTER_AUTOSCROLL_SE ): mnActDeltaX = -1L, mnActDeltaY = -1L; break;
+
+ default:
+ break;
+ }
+ }
+
+ ImplRecalcScrollValues();
+ maLastMousePos = aMousePos;
+ SetPointer( eActStyle );
+
+ if( bHorz && bVert )
+ ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_VH : WHEELMODE_VH );
+ else if( bHorz )
+ ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_H : WHEELMODE_H );
+ else
+ ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_V : WHEELMODE_V );
+}
+
+// ------------------------------------------------------------------------
+
+void ImplWheelWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if( mnActDist > WHEEL_RADIUS )
+ GetParent()->EndAutoScroll();
+ else
+ FloatingWindow::MouseButtonUp( rMEvt );
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK( ImplWheelWindow, ImplScrollHdl, Timer*, pTimer )
+{
+ if ( mnActDeltaX || mnActDeltaY )
+ {
+ Window* pWindow = GetParent();
+ const Point aMousePos( pWindow->OutputToScreenPixel( pWindow->GetPointerPosPixel() ) );
+ Point aCmdMousePos( pWindow->ImplFrameToOutput( aMousePos ) );
+ CommandScrollData aScrollData( mnActDeltaX, mnActDeltaY );
+ CommandEvent aCEvt( aCmdMousePos, COMMAND_AUTOSCROLL, TRUE, &aScrollData );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
+
+ if ( !ImplCallPreNotify( aNCmdEvt ) )
+ {
+ const ULONG nTime = Time::GetSystemTicks();
+ pWindow->Command( aCEvt );
+ mnRepaintTime = Max( Time::GetSystemTicks() - nTime, 1UL );
+ ImplRecalcScrollValues();
+ }
+ }
+
+ if ( mnTimeout != mpTimer->GetTimeout() )
+ mpTimer->SetTimeout( mnTimeout );
+ mpTimer->Start();
+
+ return 0L;
+}
diff --git a/vcl/source/window/scrwnd.hxx b/vcl/source/window/scrwnd.hxx
new file mode 100644
index 000000000000..885c55267b18
--- /dev/null
+++ b/vcl/source/window/scrwnd.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * $RCSfile: scrwnd.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <floatwin.hxx>
+#include <bitmap.hxx>
+#include <image.hxx>
+
+// -----------
+// - Defines -
+// -----------
+
+#define WHEELMODE_NONE 0x00000000UL
+#define WHEELMODE_VH 0x00000001UL
+#define WHEELMODE_V 0x00000002UL
+#define WHEELMODE_H 0x00000004UL
+#define WHEELMODE_SCROLL_VH 0x00000008UL
+#define WHEELMODE_SCROLL_V 0x00000010UL
+#define WHEELMODE_SCROLL_H 0x00000020UL
+
+// -------------------
+// - ImplWheelWindow -
+// -------------------
+
+class Timer;
+
+class ImplWheelWindow : public FloatingWindow
+{
+private:
+
+ ImageList maImgList;
+ Bitmap maWheelBmp;
+ CommandScrollData maCommandScrollData;
+ Point maLastMousePos;
+ Point maCenter;
+ Timer* mpTimer;
+ ULONG mnRepaintTime;
+ ULONG mnTimeout;
+ ULONG mnWheelMode;
+ ULONG mnMaxWidth;
+ ULONG mnActWidth;
+ ULONG mnActDist;
+ long mnActDeltaX;
+ long mnActDeltaY;
+
+ void ImplCreateImageList();
+ void ImplSetRegion( const Bitmap& rRegionBmp );
+ PointerStyle ImplGetMousePointer( long nDistX, long nDistY );
+ void ImplDrawWheel();
+ void ImplRecalcScrollValues();
+
+ DECL_LINK( ImplScrollHdl, Timer* pTimer );
+
+protected:
+
+ virtual void Paint( const Rectangle& rRect );
+ virtual void MouseMove( const MouseEvent& rMEvt );
+ virtual void MouseButtonUp( const MouseEvent& rMEvt );
+
+public:
+
+ ImplWheelWindow( Window* pParent );
+ ~ImplWheelWindow();
+
+ void ImplSetWheelMode( ULONG nWheelMode );
+ ULONG ImplGetWheelMode() const { return mnWheelMode; }
+};
diff --git a/vcl/source/window/seleng.cxx b/vcl/source/window/seleng.cxx
new file mode 100644
index 000000000000..8fd3b665aa8a
--- /dev/null
+++ b/vcl/source/window/seleng.cxx
@@ -0,0 +1,506 @@
+/*************************************************************************
+ *
+ * $RCSfile: seleng.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <tools/ref.hxx>
+#include <window.hxx>
+#include <seleng.hxx>
+#include <tools/debug.hxx>
+
+#pragma hdrstop
+
+// TODO: FunctionSet::SelectAtPoint raus
+
+/*************************************************************************
+|*
+|* SelectionEngine::SelectionEngine()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+SelectionEngine::SelectionEngine( Window* pWindow, FunctionSet* pFuncSet ) :
+ pWin( pWindow )
+{
+ eSelMode = SINGLE_SELECTION;
+ pFunctionSet = pFuncSet;
+ nFlags = SELENG_EXPANDONMOVE;
+ nLockedMods = 0;
+
+ aWTimer.SetTimeoutHdl( LINK( this, SelectionEngine, ImpWatchDog ) );
+ aWTimer.SetTimeout( SELENG_AUTOREPEAT_INTERVAL );
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::~SelectionEngine()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+SelectionEngine::~SelectionEngine()
+{
+ aWTimer.Stop();
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::ImpWatchDog()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+IMPL_LINK( SelectionEngine, ImpWatchDog, Timer*, EMPTYARG )
+{
+ if ( !aArea.IsInside( aLastMove.GetPosPixel() ) )
+ SelMouseMove( aLastMove );
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SetSelectionMode()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+void SelectionEngine::SetSelectionMode( SelectionMode eMode )
+{
+ eSelMode = eMode;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::ActivateDragMode()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+void SelectionEngine::ActivateDragMode()
+{
+ DBG_ERRORFILE( "SelectionEngine::ActivateDragMode not implemented" );
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::CursorPosChanging()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+void SelectionEngine::CursorPosChanging( BOOL bShift, BOOL /* bMod1 */ )
+{
+ if ( !pFunctionSet )
+ return;
+
+ if ( bShift && eSelMode != SINGLE_SELECTION )
+ {
+ if ( IsAddMode() )
+ {
+ if ( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ pFunctionSet->CreateAnchor();
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ }
+ else
+ {
+ if ( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ pFunctionSet->DeselectAll();
+ pFunctionSet->CreateAnchor();
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ }
+ }
+ else
+ {
+ if ( IsAddMode() )
+ {
+ if ( nFlags & SELENG_HAS_ANCH )
+ {
+ // pFunctionSet->CreateCursor();
+ pFunctionSet->DestroyAnchor();
+ nFlags &= (~SELENG_HAS_ANCH);
+ }
+ }
+ else
+ {
+ pFunctionSet->DeselectAll();
+ nFlags &= (~SELENG_HAS_ANCH);
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SelMouseButtonDown()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 07.06.95
+|*
+*************************************************************************/
+
+BOOL SelectionEngine::SelMouseButtonDown( const MouseEvent& rMEvt )
+{
+ nFlags &= (~SELENG_CMDEVT);
+ if ( !pFunctionSet || !pWin || rMEvt.GetClicks() > 1 || rMEvt.IsRight() )
+ return FALSE;
+
+ USHORT nModifier = rMEvt.GetModifier() | nLockedMods;
+ if ( nModifier & KEY_MOD2 )
+ return FALSE;
+ // in SingleSelection: Control-Taste filtern (damit auch
+ // mit Ctrl-Click ein D&D gestartet werden kann)
+ if ( nModifier == KEY_MOD1 && eSelMode == SINGLE_SELECTION )
+ nModifier = 0;
+
+ Point aPos = rMEvt.GetPosPixel();
+ aLastMove = rMEvt;
+
+ pWin->CaptureMouse();
+ nFlags |= SELENG_IN_SEL;
+
+ switch ( nModifier )
+ {
+ case 0: // KEY_NO_KEY
+ {
+ BOOL bSelAtPoint = pFunctionSet->IsSelectionAtPoint( aPos );
+ nFlags &= (~SELENG_IN_ADD);
+ if ( (nFlags & SELENG_DRG_ENAB) && bSelAtPoint )
+ {
+ nFlags |= SELENG_WAIT_UPEVT;
+ nFlags &= ~(SELENG_IN_SEL);
+ pWin->ReleaseMouse();
+ return TRUE; //auf STARTDRAG-Command-Event warten
+ }
+ if ( eSelMode != SINGLE_SELECTION )
+ {
+ if( !IsAddMode() )
+ pFunctionSet->DeselectAll();
+ else
+ pFunctionSet->DestroyAnchor();
+ nFlags &= (~SELENG_HAS_ANCH); // bHasAnchor = FALSE;
+ }
+ pFunctionSet->SetCursorAtPoint( aPos );
+ // Sonderbehandlung Single-Selection, damit Select+Drag
+ // in einem Zug moeglich ist
+ if (eSelMode == SINGLE_SELECTION && (nFlags & SELENG_DRG_ENAB))
+ nFlags |= SELENG_WAIT_UPEVT;
+ return TRUE;
+ }
+
+ case KEY_SHIFT:
+ if ( eSelMode == SINGLE_SELECTION )
+ {
+ pWin->ReleaseMouse();
+ nFlags &= (~SELENG_IN_SEL);
+ return FALSE;
+ }
+ if ( nFlags & SELENG_ADD_ALW )
+ nFlags |= SELENG_IN_ADD;
+ else
+ nFlags &= (~SELENG_IN_ADD);
+
+ if( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ if ( !(nFlags & SELENG_IN_ADD) )
+ pFunctionSet->DeselectAll();
+ pFunctionSet->CreateAnchor();
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ pFunctionSet->SetCursorAtPoint( aPos );
+ return TRUE;
+
+ case KEY_MOD1:
+ // Control nur bei Mehrfachselektion erlaubt
+ if ( eSelMode != MULTIPLE_SELECTION )
+ {
+ nFlags &= (~SELENG_IN_SEL);
+ pWin->ReleaseMouse();
+ return TRUE; // Mausclick verschlucken
+ }
+ if ( nFlags & SELENG_HAS_ANCH )
+ {
+ // pFunctionSet->CreateCursor();
+ pFunctionSet->DestroyAnchor();
+ nFlags &= (~SELENG_HAS_ANCH);
+ }
+ if ( pFunctionSet->IsSelectionAtPoint( aPos ) )
+ {
+ pFunctionSet->DeselectAtPoint( aPos );
+ pFunctionSet->SetCursorAtPoint( aPos, TRUE );
+ }
+ else
+ {
+ pFunctionSet->SetCursorAtPoint( aPos );
+ }
+ return TRUE;
+
+ case KEY_SHIFT + KEY_MOD1:
+ if ( eSelMode != MULTIPLE_SELECTION )
+ {
+ pWin->ReleaseMouse();
+ nFlags &= (~SELENG_IN_SEL);
+ return FALSE;
+ }
+ nFlags |= SELENG_IN_ADD; //bIsInAddMode = TRUE;
+ if ( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ pFunctionSet->CreateAnchor();
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ pFunctionSet->SetCursorAtPoint( aPos );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SelMouseButtonUp()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+BOOL SelectionEngine::SelMouseButtonUp( const MouseEvent& /* rMEvt */ )
+{
+ aWTimer.Stop();
+ //DbgOut("Up");
+ if( !pFunctionSet || !pWin )
+ {
+ nFlags &= ~(SELENG_CMDEVT | SELENG_WAIT_UPEVT | SELENG_IN_SEL);
+ return FALSE;
+ }
+ pWin->ReleaseMouse();
+
+ if( (nFlags & SELENG_WAIT_UPEVT) && !(nFlags & SELENG_CMDEVT) &&
+ eSelMode != SINGLE_SELECTION)
+ {
+ // MouseButtonDown in Sel aber kein CommandEvent eingetrudelt
+ // ==> deselektieren
+ USHORT nModifier = aLastMove.GetModifier() | nLockedMods;
+ if( nModifier == KEY_MOD1 || IsAlwaysAdding() )
+ {
+ if( !(nModifier & KEY_SHIFT) )
+ {
+ pFunctionSet->DestroyAnchor();
+ nFlags &= (~SELENG_HAS_ANCH); // nix Anker
+ }
+ pFunctionSet->DeselectAtPoint( aLastMove.GetPosPixel() );
+ nFlags &= (~SELENG_HAS_ANCH); // nix Anker
+ pFunctionSet->SetCursorAtPoint( aLastMove.GetPosPixel(), TRUE );
+ }
+ else
+ {
+ pFunctionSet->DeselectAll();
+ nFlags &= (~SELENG_HAS_ANCH); // nix Anker
+ pFunctionSet->SetCursorAtPoint( aLastMove.GetPosPixel() );
+ }
+ }
+
+ nFlags &= ~(SELENG_CMDEVT | SELENG_WAIT_UPEVT | SELENG_IN_SEL);
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SelMouseMove()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+BOOL SelectionEngine::SelMouseMove( const MouseEvent& rMEvt )
+{
+
+ if ( !pFunctionSet || !(nFlags & SELENG_IN_SEL) ||
+ (nFlags & (SELENG_CMDEVT | SELENG_WAIT_UPEVT)) )
+ return FALSE;
+
+ if( !(nFlags & SELENG_EXPANDONMOVE) )
+ return FALSE; // auf DragEvent warten!
+
+ aLastMove = rMEvt;
+ // wenn die Maus ausserhalb der Area steht, dann wird die
+ // Frequenz des SetCursorAtPoint() nur durch den Timer bestimmt
+ if( aWTimer.IsActive() && !aArea.IsInside( rMEvt.GetPosPixel() ))
+ return TRUE;
+
+
+ aWTimer.Start();
+ if ( eSelMode != SINGLE_SELECTION )
+ {
+ if ( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ pFunctionSet->CreateAnchor();
+ //DbgOut("Move:Creating anchor");
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ }
+
+ //DbgOut("Move:SetCursor");
+ pFunctionSet->SetCursorAtPoint( rMEvt.GetPosPixel() );
+
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SetWindow()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+void SelectionEngine::SetWindow( Window* pNewWin )
+{
+ if( pNewWin != pWin )
+ {
+ if ( pWin && (nFlags & SELENG_IN_SEL) )
+ pWin->ReleaseMouse();
+ pWin = pNewWin;
+ if ( pWin && ( nFlags & SELENG_IN_SEL ) )
+ pWin->CaptureMouse();
+ }
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::Reset()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 07.07.95
+|* Letzte Aenderung OV 07.07.95
+|*
+*************************************************************************/
+
+void SelectionEngine::Reset()
+{
+ aWTimer.Stop();
+ if ( nFlags & SELENG_IN_SEL )
+ pWin->ReleaseMouse();
+ nFlags &= ~(SELENG_HAS_ANCH | SELENG_IN_SEL);
+ nLockedMods = 0;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::Command()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 07.07.95
+|* Letzte Aenderung OV 07.07.95
+|*
+*************************************************************************/
+
+void SelectionEngine::Command( const CommandEvent& rCEvt )
+{
+ // Timer aWTimer ist beim Aufspannen einer Selektion aktiv
+ if ( !pFunctionSet || !pWin || aWTimer.IsActive() )
+ return;
+ aWTimer.Stop();
+ nFlags |= SELENG_CMDEVT;
+ if ( rCEvt.GetCommand() == COMMAND_STARTDRAG )
+ {
+ if ( nFlags & SELENG_DRG_ENAB )
+ {
+ DBG_ASSERT( rCEvt.IsMouseEvent(), "STARTDRAG: Not a MouseEvent" );
+ if ( pFunctionSet->IsSelectionAtPoint( rCEvt.GetMousePosPixel() ) )
+ {
+ aLastMove = MouseEvent( rCEvt.GetMousePosPixel(),
+ aLastMove.GetClicks(), aLastMove.GetMode(),
+ aLastMove.GetButtons(), aLastMove.GetModifier() );
+ pFunctionSet->BeginDrag();
+ nFlags &= ~(SELENG_CMDEVT|SELENG_WAIT_UPEVT|SELENG_IN_SEL);
+ }
+ else
+ nFlags &= ~SELENG_CMDEVT;
+ }
+ else
+ nFlags &= ~SELENG_CMDEVT;
+ }
+}
diff --git a/vcl/source/window/split.cxx b/vcl/source/window/split.cxx
new file mode 100644
index 000000000000..440b550b720a
--- /dev/null
+++ b/vcl/source/window/split.cxx
@@ -0,0 +1,365 @@
+/*************************************************************************
+ *
+ * $RCSfile: split.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SPLIT_CXX
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SPLIT_HXX
+#include <split.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+void Splitter::ImplInitData()
+{
+ mpRefWin = NULL;
+ mnSplitPos = 0;
+ mnLastSplitPos = 0;
+ mnStartSplitPos = 0;
+ mbDragFull = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::ImplInit( Window* pParent, WinBits nWinStyle )
+{
+ Window::ImplInit( pParent, nWinStyle, NULL );
+
+ mpRefWin = pParent;
+
+ const StyleSettings& rSettings = GetSettings().GetStyleSettings();
+ long nA = rSettings.GetScrollBarSize();
+ long nB = rSettings.GetSplitSize();
+
+ PointerStyle ePointerStyle;
+
+ if ( nWinStyle & WB_HSCROLL )
+ {
+ ePointerStyle = POINTER_HSPLIT;
+ mbHorzSplit = TRUE;
+ SetSizePixel( Size( nB, nA ) );
+ }
+ else
+ {
+ ePointerStyle = POINTER_VSPLIT;
+ mbHorzSplit = FALSE;
+ SetSizePixel( Size( nA, nB ) );
+ }
+
+ SetPointer( Pointer( ePointerStyle ) );
+ SetBackground( Wallpaper( Color( COL_BLACK ) ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::ImplSplitMousePos( Point& rPos )
+{
+ if ( mbHorzSplit )
+ {
+ if ( rPos.X() > maDragRect.Right()-1 )
+ rPos.X() = maDragRect.Right()-1;
+ if ( rPos.X() < maDragRect.Left()+1 )
+ rPos.X() = maDragRect.Left()+1;
+ }
+ else
+ {
+ if ( rPos.Y() > maDragRect.Bottom()-1 )
+ rPos.Y() = maDragRect.Bottom()-1;
+ if ( rPos.Y() < maDragRect.Top()+1 )
+ rPos.Y() = maDragRect.Top()+1;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::ImplDrawSplitter()
+{
+ Rectangle aInvRect( maDragRect );
+
+ if ( mbHorzSplit )
+ {
+ aInvRect.Left() = maDragPos.X() - 1;
+ aInvRect.Right() = maDragPos.X() + 1;
+ }
+ else
+ {
+ aInvRect.Top() = maDragPos.Y() - 1;
+ aInvRect.Bottom() = maDragPos.Y() + 1;
+ }
+
+ mpRefWin->InvertTracking( aInvRect, SHOWTRACK_SPLIT );
+}
+
+// -----------------------------------------------------------------------
+
+Splitter::Splitter( Window* pParent, WinBits nStyle ) :
+ Window( WINDOW_SPLITTER )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+Splitter::Splitter( Window* pParent, const ResId& rResId ) :
+ Window( WINDOW_SPLITTER )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_SPLITTER );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+Splitter::~Splitter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.GetClicks() == 2 )
+ {
+ if ( mnLastSplitPos != mnSplitPos )
+ {
+ StartSplit();
+ Point aPos = rMEvt.GetPosPixel();
+ if ( mbHorzSplit )
+ aPos.X() = mnLastSplitPos;
+ else
+ aPos.Y() = mnLastSplitPos;
+ ImplSplitMousePos( aPos );
+ Splitting( aPos );
+ ImplSplitMousePos( aPos );
+ long nTemp = mnSplitPos;
+ if ( mbHorzSplit )
+ SetSplitPosPixel( aPos.X() );
+ else
+ SetSplitPosPixel( aPos.Y() );
+ mnLastSplitPos = nTemp;
+ Split();
+ }
+ }
+ else
+ StartDrag();
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( !mbDragFull )
+ ImplDrawSplitter();
+
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ long nNewPos;
+ if ( mbHorzSplit )
+ nNewPos = maDragPos.X();
+ else
+ nNewPos = maDragPos.Y();
+ if ( nNewPos != mnStartSplitPos )
+ {
+ SetSplitPosPixel( nNewPos );
+ mnLastSplitPos = 0;
+ Split();
+ }
+ }
+ else if ( mbDragFull )
+ {
+ SetSplitPosPixel( mnStartSplitPos );
+ Split();
+ }
+ mnStartSplitPos = 0;
+ }
+ else
+ {
+ Point aNewPos = mpRefWin->ScreenToOutputPixel( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) );
+ ImplSplitMousePos( aNewPos );
+ Splitting( aNewPos );
+ ImplSplitMousePos( aNewPos );
+
+ if ( mbHorzSplit )
+ {
+ if ( aNewPos.X() == maDragPos.X() )
+ return;
+ }
+ else
+ {
+ if ( aNewPos.Y() == maDragPos.Y() )
+ return;
+ }
+
+ if ( mbDragFull )
+ {
+ maDragPos = aNewPos;
+ long nNewPos;
+ if ( mbHorzSplit )
+ nNewPos = maDragPos.X();
+ else
+ nNewPos = maDragPos.Y();
+ if ( nNewPos != mnSplitPos )
+ {
+ SetSplitPosPixel( nNewPos );
+ mnLastSplitPos = 0;
+ Split();
+ }
+
+ GetParent()->Update();
+ }
+ else
+ {
+ ImplDrawSplitter();
+ maDragPos = aNewPos;
+ ImplDrawSplitter();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::StartSplit()
+{
+ maStartSplitHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::Split()
+{
+ maSplitHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::Splitting( Point& /* rSplitPos */ )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::SetDragRectPixel( const Rectangle& rDragRect, Window* _pRefWin )
+{
+ maDragRect = rDragRect;
+ if ( !_pRefWin )
+ mpRefWin = GetParent();
+ else
+ mpRefWin = _pRefWin;
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::SetSplitPosPixel( long nNewPos )
+{
+ mnSplitPos = nNewPos;
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::SetLastSplitPosPixel( long nNewPos )
+{
+ mnLastSplitPos = nNewPos;
+}
+
+// -----------------------------------------------------------------------
+
+void Splitter::StartDrag()
+{
+ if ( IsTracking() )
+ return;
+
+ StartSplit();
+
+ // Tracking starten
+ StartTracking();
+
+ // Start-Positon ermitteln
+ maDragPos = mpRefWin->GetPointerPosPixel();
+ ImplSplitMousePos( maDragPos );
+ Splitting( maDragPos );
+ ImplSplitMousePos( maDragPos );
+ if ( mbHorzSplit )
+ mnStartSplitPos = maDragPos.X();
+ else
+ mnStartSplitPos = maDragPos.Y();
+
+ mbDragFull = (Application::GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SPLIT) != 0;
+ if ( !mbDragFull )
+ ImplDrawSplitter();
+}
diff --git a/vcl/source/window/splitwin.cxx b/vcl/source/window/splitwin.cxx
new file mode 100644
index 000000000000..907c98f56d4e
--- /dev/null
+++ b/vcl/source/window/splitwin.cxx
@@ -0,0 +1,3647 @@
+/*************************************************************************
+ *
+ * $RCSfile: splitwin.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SPLITWIN_CXX
+
+#include <string.h>
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_RCID_H
+#include <rcid.h>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_WALL_HXX
+#include <wall.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_SYMBOL_HXX
+#include <symbol.hxx>
+#endif
+#ifndef _SV_SVIDS_HRC
+#include <svids.hrc>
+#endif
+#ifndef _SV_IMAGE_HXX
+#include <image.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#define private public
+#ifndef _SV_SPLITWIN_HXX
+#include <splitwin.hxx>
+#endif
+#undef private
+
+#pragma hdrstop
+
+// =======================================================================
+
+// Achtung: Darf keine Objekte enthalten, da mit memmove/memcpy gearbeitet wird
+struct ImplSplitItem
+{
+ long mnSize;
+ long mnPixSize;
+ long mnLeft;
+ long mnTop;
+ long mnWidth;
+ long mnHeight;
+ long mnSplitPos;
+ long mnSplitSize;
+ long mnOldSplitPos;
+ long mnOldSplitSize;
+ long mnOldWidth;
+ long mnOldHeight;
+ ImplSplitSet* mpSet;
+ Window* mpWindow;
+ Window* mpOrgParent;
+ USHORT mnId;
+ SplitWindowItemBits mnBits;
+ BOOL mbFixed;
+ BOOL mbSubSize;
+};
+
+struct ImplSplitSet
+{
+ ImplSplitItem* mpItems;
+ Wallpaper* mpWallpaper;
+ Bitmap* mpBitmap;
+ long mnLastSize;
+ long mnSplitSize;
+ USHORT mnItems;
+ USHORT mnId;
+ BOOL mbCalcPix;
+};
+
+#define SPLITWIN_SPLITSIZE 6
+#define SPLITWIN_SPLITSIZEEX 6
+#define SPLITWIN_SPLITSIZEAUTOHIDE 40
+#define SPLITWIN_SPLITSIZEFADE 40
+
+#define SPLIT_HORZ ((USHORT)0x0001)
+#define SPLIT_VERT ((USHORT)0x0002)
+#define SPLIT_WINDOW ((USHORT)0x0004)
+#define SPLIT_NOSPLIT ((USHORT)0x8000)
+
+// -----------------------------------------------------------------------
+
+DECLARE_LIST( ImplSplitList, SplitWindow* );
+
+// =======================================================================
+
+static void ImplCalcBorder( WindowAlign eAlign, BOOL bNoAlign,
+ long& rLeft, long& rTop,
+ long& rRight, long& rBottom )
+{
+ if ( bNoAlign )
+ {
+ rLeft = 2;
+ rTop = 2;
+ rRight = 2;
+ rBottom = 2;
+ }
+ else
+ {
+ if ( eAlign == WINDOWALIGN_TOP )
+ {
+ rLeft = 0;
+ rTop = 2;
+ rRight = 0;
+ rBottom = 0;
+ }
+ else if ( eAlign == WINDOWALIGN_LEFT )
+ {
+ rLeft = 2;
+ rTop = 2;
+ rRight = 0;
+ rBottom = 2;
+ }
+ else if ( eAlign == WINDOWALIGN_BOTTOM )
+ {
+ rLeft = 0;
+ rTop = 0;
+ rRight = 0;
+ rBottom = 2;
+ }
+ else
+ {
+ rLeft = 0;
+ rTop = 2;
+ rRight = 2;
+ rBottom = 2;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawBorder( SplitWindow* pWin )
+{
+ const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
+ long nDX = pWin->mnDX;
+ long nDY = pWin->mnDY;
+
+ if ( pWin->mbNoAlign )
+ {
+ DecorationView aDecoView( pWin );
+ Point aTmpPoint;
+ Rectangle aRect( aTmpPoint, Size( nDX, nDY ) );
+ aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
+ }
+ else
+ {
+ if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
+ {
+ pWin->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
+ pWin->SetLineColor( rStyleSettings.GetLightColor() );
+ pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
+ }
+ else
+ {
+ pWin->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
+ pWin->SetLineColor( rStyleSettings.GetLightColor() );
+ pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
+ if ( (pWin->meAlign == WINDOWALIGN_LEFT) || (pWin->meAlign == WINDOWALIGN_RIGHT) )
+ {
+ if ( pWin->meAlign == WINDOWALIGN_LEFT )
+ {
+ pWin->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
+ pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
+ pWin->SetLineColor( rStyleSettings.GetLightColor() );
+ pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
+ pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
+ }
+ else
+ {
+ pWin->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
+ pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
+ pWin->SetLineColor( rStyleSettings.GetLightColor() );
+ pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
+ pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static ImplSplitSet* ImplFindSet( ImplSplitSet* pSet, USHORT nId )
+{
+ if ( pSet->mnId == nId )
+ return pSet;
+
+ USHORT i;
+ USHORT nItems = pSet->mnItems;
+ ImplSplitItem* pItems = pSet->mpItems;
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mnId == nId )
+ return pItems[i].mpSet;
+ }
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpSet )
+ {
+ ImplSplitSet* pFindSet = ImplFindSet( pItems[i].mpSet, nId );
+ if ( pFindSet )
+ return pFindSet;
+ }
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static ImplSplitSet* ImplFindItem( ImplSplitSet* pSet, USHORT nId, USHORT& rPos )
+{
+ USHORT i;
+ USHORT nItems = pSet->mnItems;
+ ImplSplitItem* pItems = pSet->mpItems;
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mnId == nId )
+ {
+ rPos = i;
+ return pSet;
+ }
+ }
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpSet )
+ {
+ ImplSplitSet* pFindSet = ImplFindItem( pItems[i].mpSet, nId, rPos );
+ if ( pFindSet )
+ return pFindSet;
+ }
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplFindItem( ImplSplitSet* pSet, Window* pWindow )
+{
+ USHORT i;
+ USHORT nItems = pSet->mnItems;
+ ImplSplitItem* pItems = pSet->mpItems;
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpWindow == pWindow )
+ return pItems[i].mnId;
+ else
+ {
+ if ( pItems[i].mpSet )
+ {
+ USHORT nId = ImplFindItem( pItems[i].mpSet, pWindow );
+ if ( nId )
+ return nId;
+ }
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplFindItem( ImplSplitSet* pSet, const Point& rPos,
+ BOOL bRows, BOOL bDown = TRUE )
+{
+ USHORT i;
+ USHORT nItems = pSet->mnItems;
+ ImplSplitItem* pItems = pSet->mpItems;
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mnWidth && pItems[i].mnHeight )
+ {
+ // Wegen ICC auftrennen
+ Point aPoint( pItems[i].mnLeft, pItems[i].mnTop );
+ Size aSize( pItems[i].mnWidth, pItems[i].mnHeight );
+ Rectangle aRect( aPoint, aSize );
+ if ( bRows )
+ {
+ if ( bDown )
+ aRect.Bottom() += pSet->mnSplitSize;
+ else
+ aRect.Top() -= pSet->mnSplitSize;
+ }
+ else
+ {
+ if ( bDown )
+ aRect.Right() += pSet->mnSplitSize;
+ else
+ aRect.Left() -= pSet->mnSplitSize;
+ }
+
+ if ( aRect.IsInside( rPos ) )
+ {
+ if ( pItems[i].mpSet && pItems[i].mpSet->mpItems )
+ {
+ return ImplFindItem( pItems[i].mpSet, rPos,
+ ((pItems[i].mnBits & SWIB_COLSET) == 0) );
+ }
+ else
+ return pItems[i].mnId;
+ }
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDeleteSet( ImplSplitSet* pSet )
+{
+ USHORT i;
+ USHORT nItems = pSet->mnItems;
+ ImplSplitItem* pItems = pSet->mpItems;
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpSet )
+ ImplDeleteSet( pItems[i].mpSet );
+ }
+
+ if ( pSet->mpWallpaper )
+ delete pSet->mpWallpaper;
+
+ if ( pSet->mpBitmap )
+ delete pSet->mpBitmap;
+
+ delete pItems;
+ delete pSet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSetSplitSize( ImplSplitSet* pSet, long nNewSize )
+{
+ pSet->mnSplitSize = nNewSize;
+ for ( USHORT i = 0; i < pSet->mnItems; i++ )
+ {
+ if ( pSet->mpItems[i].mpSet )
+ ImplSetSplitSize( pSet->mpItems[i].mpSet, nNewSize );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalcSet( ImplSplitSet* pSet,
+ long nSetLeft, long nSetTop,
+ long nSetWidth, long nSetHeight,
+ BOOL bRows, BOOL bDown = TRUE )
+{
+ if ( !pSet->mpItems )
+ return;
+
+ USHORT i;
+ USHORT j;
+ USHORT nMins;
+ USHORT nCalcItems;
+ USHORT nItems = pSet->mnItems;
+ USHORT nVisItems;
+ USHORT nAbsItems;
+ long nCalcSize;
+ long nSizeDelta;
+ long nCurSize;
+ long nSizeWinSize;
+ long nNewSizeWinSize;
+ long nTemp;
+ long nTempErr;
+ long nErrorSum;
+ long nCurSizeDelta;
+ long nPos;
+ long nMaxPos;
+ long* pSize;
+ ImplSplitItem* pItems = pSet->mpItems;
+ BOOL bEmpty;
+
+ // Anzahl sichtbarer Items ermitteln
+ nVisItems = 0;
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
+ nVisItems++;
+ }
+
+ // Groessen berechnen
+ if ( bRows )
+ nCalcSize = nSetHeight;
+ else
+ nCalcSize = nSetWidth;
+ nCalcSize -= (nVisItems-1)*pSet->mnSplitSize;
+ nCurSize = 0;
+ if ( pSet->mbCalcPix || (pSet->mnLastSize != nCalcSize) )
+ {
+ long nPercentFactor = 10;
+ long nRelCount = 0;
+ long nPercent = 0;
+ long nRelPercent = 0;
+ long nAbsSize = 0;
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
+ {
+ if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
+ nRelCount += pItems[i].mnSize;
+ else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
+ nPercent += pItems[i].mnSize;
+ else
+ nAbsSize += pItems[i].mnSize;
+ }
+ }
+ // Relative-Werte auf prozentual mappen (Percent bei uns 10tel Prozent)
+ nPercent *= nPercentFactor;
+ if ( nRelCount )
+ {
+ long nRelPercentBase = 1000;
+ while ( (nRelCount > nRelPercentBase) && (nPercentFactor < 100000) )
+ {
+ nRelPercentBase *= 10;
+ nPercentFactor *= 10;
+ }
+ if ( nPercent < nRelPercentBase )
+ {
+ nRelPercent = (nRelPercentBase-nPercent)/nRelCount;
+ nPercent += nRelPercent*nRelCount;
+ }
+ else
+ nRelPercent = 0;
+ }
+ if ( !nPercent )
+ nPercent = 1;
+ nSizeDelta = nCalcSize-nAbsSize;
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mnBits & SWIB_INVISIBLE )
+ pItems[i].mnPixSize = 0;
+ else if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
+ {
+ if ( nSizeDelta <= 0 )
+ pItems[i].mnPixSize = 0;
+ else
+ pItems[i].mnPixSize = (nSizeDelta*pItems[i].mnSize*nRelPercent)/nPercent;
+ }
+ else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
+ {
+ if ( nSizeDelta <= 0 )
+ pItems[i].mnPixSize = 0;
+ else
+ pItems[i].mnPixSize = (nSizeDelta*pItems[i].mnSize*nPercentFactor)/nPercent;
+ }
+ else
+ pItems[i].mnPixSize = pItems[i].mnSize;
+ nCurSize += pItems[i].mnPixSize;
+ }
+
+ pSet->mbCalcPix = FALSE;
+ pSet->mnLastSize = nCalcSize;
+
+ // Fenster einpassen
+ nSizeDelta = nCalcSize-nCurSize;
+ if ( nSizeDelta )
+ {
+ nAbsItems = 0;
+ nSizeWinSize = 0;
+ nNewSizeWinSize = 0;
+
+ // Zuerst die absoluten Items relativ resizen
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
+ {
+ if ( !(pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
+ {
+ nAbsItems++;
+ nSizeWinSize += pItems[i].mnPixSize;
+ }
+ }
+ }
+ // Rundungsfehler werden hier nicht ausgelichen
+ if ( (nAbsItems < (USHORT)(Abs( nSizeDelta ))) && nSizeWinSize )
+ {
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
+ {
+ if ( !(pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
+ {
+ pItems[i].mnPixSize += (nSizeDelta*pItems[i].mnPixSize)/nSizeWinSize;
+ nNewSizeWinSize += pItems[i].mnPixSize;
+ }
+ }
+ }
+ nSizeDelta -= nNewSizeWinSize-nSizeWinSize;
+ }
+
+ // Jetzt die Rundunsfehler ausgleichen
+ j = 0;
+ nMins = 0;
+ while ( nSizeDelta && (nItems != nMins) )
+ {
+ // Feststellen, welche Items berechnet werden duerfen
+ nCalcItems = 0;
+ while ( !nCalcItems )
+ {
+ for ( i = 0; i < nItems; i++ )
+ {
+ pItems[i].mbSubSize = FALSE;
+
+ if ( j >= 2 )
+ pItems[i].mbSubSize = TRUE;
+ else
+ {
+ if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
+ {
+ if ( (nSizeDelta > 0) || pItems[i].mnPixSize )
+ {
+ if ( j >= 1 )
+ pItems[i].mbSubSize = TRUE;
+ else
+ {
+ if ( (j == 0) && (pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
+ pItems[i].mbSubSize = TRUE;
+ }
+ }
+ }
+ }
+
+ if ( pItems[i].mbSubSize )
+ nCalcItems++;
+ }
+
+ j++;
+ }
+
+ // Groessen von den einzelnen Items abziehen
+ nErrorSum = nSizeDelta % nCalcItems;
+ nCurSizeDelta = nSizeDelta / nCalcItems;
+ nMins = 0;
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mnBits & SWIB_INVISIBLE )
+ nMins++;
+ else if ( pItems[i].mbSubSize )
+ {
+ pSize = &(pItems[i].mnPixSize);
+
+ if ( nErrorSum )
+ {
+ if ( nErrorSum < 0 )
+ nTempErr = -1;
+ else
+ nTempErr = 1;
+ }
+ else
+ nTempErr = 0;
+
+ if ( (*pSize+nCurSizeDelta+nTempErr) <= 0 )
+ {
+ nTemp = *pSize;
+ if ( nTemp )
+ {
+ *pSize -= nTemp;
+ nSizeDelta += nTemp;
+ }
+ nMins++;
+ }
+ else
+ {
+ *pSize += nCurSizeDelta;
+ nSizeDelta -= nCurSizeDelta;
+ if ( nTempErr && (*pSize || (nTempErr > 0)) )
+ {
+ *pSize += nTempErr;
+ nSizeDelta -= nTempErr;
+ nErrorSum -= nTempErr;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
+ nCurSize += pItems[i].mnPixSize;
+ }
+ }
+
+ // Maximale Groesse berechnen
+ if ( bRows )
+ {
+ nPos = nSetTop;
+ if ( !bDown )
+ nMaxPos = nSetTop-nSetHeight;
+ else
+ nMaxPos = nSetTop+nSetHeight;
+ }
+ else
+ {
+ nPos = nSetLeft;
+ if ( !bDown )
+ nMaxPos = nSetLeft-nSetWidth;
+ else
+ nMaxPos = nSetLeft+nSetWidth;
+ }
+
+ // Fenster anordnen und Werte anpassen
+ for ( i = 0; i < nItems; i++ )
+ {
+ pItems[i].mnOldSplitPos = pItems[i].mnSplitPos;
+ pItems[i].mnOldSplitSize = pItems[i].mnSplitSize;
+ pItems[i].mnOldWidth = pItems[i].mnWidth;
+ pItems[i].mnOldHeight = pItems[i].mnHeight;
+
+ if ( pItems[i].mnBits & SWIB_INVISIBLE )
+ bEmpty = TRUE;
+ else
+ {
+ bEmpty = FALSE;
+ if ( bDown )
+ {
+ if ( nPos+pItems[i].mnPixSize > nMaxPos )
+ bEmpty = TRUE;
+ }
+ else
+ {
+ nPos -= pItems[i].mnPixSize;
+ if ( nPos < nMaxPos )
+ bEmpty = TRUE;
+ }
+ }
+
+ if ( bEmpty )
+ {
+ pItems[i].mnWidth = 0;
+ pItems[i].mnHeight = 0;
+ pItems[i].mnSplitSize = 0;
+ }
+ else
+ {
+ if ( bRows )
+ {
+ pItems[i].mnLeft = nSetLeft;
+ pItems[i].mnTop = nPos;
+ pItems[i].mnWidth = nSetWidth;
+ pItems[i].mnHeight = pItems[i].mnPixSize;
+ }
+ else
+ {
+ pItems[i].mnLeft = nPos;
+ pItems[i].mnTop = nSetTop;
+ pItems[i].mnWidth = pItems[i].mnPixSize;
+ pItems[i].mnHeight = nSetHeight;
+ }
+
+ if ( i > nItems-1 )
+ pItems[i].mnSplitSize = 0;
+ else
+ {
+ pItems[i].mnSplitSize = pSet->mnSplitSize;
+ if ( bDown )
+ {
+ pItems[i].mnSplitPos = nPos+pItems[i].mnPixSize;
+ if ( pItems[i].mnSplitPos+pItems[i].mnSplitSize > nMaxPos )
+ pItems[i].mnSplitSize = nMaxPos-pItems[i].mnSplitPos;
+ }
+ else
+ {
+ pItems[i].mnSplitPos = nPos-pSet->mnSplitSize;
+ if ( pItems[i].mnSplitPos < nMaxPos )
+ pItems[i].mnSplitSize = pItems[i].mnSplitPos+pSet->mnSplitSize-nMaxPos;
+ }
+ }
+ }
+
+ if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
+ {
+ if ( !bDown )
+ nPos -= pSet->mnSplitSize;
+ else
+ nPos += pItems[i].mnPixSize+pSet->mnSplitSize;
+ }
+ }
+
+ // Sub-Set's berechnen
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpSet && pItems[i].mnWidth && pItems[i].mnHeight )
+ {
+ ImplCalcSet( pItems[i].mpSet,
+ pItems[i].mnLeft, pItems[i].mnTop,
+ pItems[i].mnWidth, pItems[i].mnHeight,
+ ((pItems[i].mnBits & SWIB_COLSET) == 0) );
+ }
+ }
+
+ // Fixed setzen
+ for ( i = 0; i < nItems; i++ )
+ {
+ pItems[i].mbFixed = FALSE;
+ if ( pItems[i].mnBits & SWIB_FIXED )
+ pItems[i].mbFixed = TRUE;
+ else
+ {
+ // Wenn Child-Set vorhanden, ist dieses Item auch Fixed, wenn
+ // ein Child fixed ist
+ if ( pItems[i].mpSet )
+ {
+ for ( j = 0; j < pItems[i].mpSet->mnItems; j++ )
+ {
+ if ( pItems[i].mpSet->mpItems[j].mbFixed )
+ {
+ pItems[i].mbFixed = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalcSet2( SplitWindow* pWindow, ImplSplitSet* pSet, BOOL bHide,
+ BOOL bRows, BOOL bDown = TRUE )
+{
+ USHORT i;
+ USHORT nItems = pSet->mnItems;
+ ImplSplitItem* pItems = pSet->mpItems;
+
+ if ( pWindow->IsReallyVisible() && pWindow->IsUpdateMode() && pWindow->mbInvalidate )
+ {
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mnSplitSize )
+ {
+ // Evt. alles invalidieren oder nur einen kleinen Teil
+ if ( (pItems[i].mnOldSplitPos != pItems[i].mnSplitPos) ||
+ (pItems[i].mnOldSplitSize != pItems[i].mnSplitSize) ||
+ (pItems[i].mnOldWidth != pItems[i].mnWidth) ||
+ (pItems[i].mnOldHeight != pItems[i].mnHeight) )
+ {
+ Rectangle aRect;
+
+ // Old Rect invalidieren
+ if ( bRows )
+ {
+ aRect.Left() = pItems[i].mnLeft;
+ aRect.Right() = pItems[i].mnLeft+pItems[i].mnOldWidth-1;
+ aRect.Top() = pItems[i].mnOldSplitPos;
+ aRect.Bottom() = aRect.Top() + pItems[i].mnOldSplitSize;
+ }
+ else
+ {
+ aRect.Top() = pItems[i].mnTop;
+ aRect.Bottom() = pItems[i].mnTop+pItems[i].mnOldHeight-1;
+ aRect.Left() = pItems[i].mnOldSplitPos;
+ aRect.Right() = aRect.Left() + pItems[i].mnOldSplitSize;
+ }
+ pWindow->Invalidate( aRect );
+ // New Rect invalidieren
+ if ( bRows )
+ {
+ aRect.Left() = pItems[i].mnLeft;
+ aRect.Right() = pItems[i].mnLeft+pItems[i].mnWidth-1;
+ aRect.Top() = pItems[i].mnSplitPos;
+ aRect.Bottom() = aRect.Top() + pItems[i].mnSplitSize;
+ }
+ else
+ {
+ aRect.Top() = pItems[i].mnTop;
+ aRect.Bottom() = pItems[i].mnTop+pItems[i].mnHeight-1;
+ aRect.Left() = pItems[i].mnSplitPos;
+ aRect.Right() = aRect.Left() + pItems[i].mnSplitSize;
+ }
+ pWindow->Invalidate( aRect );
+
+ // Leere Sets komplett invalidieren, da diese Flaechen
+ // nicht von Fenstern ueberladen werden
+ if ( pItems[i].mpSet && !pItems[i].mpSet->mpItems )
+ {
+ aRect.Left() = pItems[i].mnLeft;
+ aRect.Top() = pItems[i].mnTop;
+ aRect.Right() = pItems[i].mnLeft+pItems[i].mnWidth-1;
+ aRect.Bottom() = pItems[i].mnTop+pItems[i].mnHeight-1;
+ pWindow->Invalidate( aRect );
+ }
+ }
+ }
+ }
+ }
+
+ // Fenster positionieren
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpSet )
+ {
+ BOOL bTempHide = bHide;
+ if ( !pItems[i].mnWidth || !pItems[i].mnHeight )
+ bTempHide = TRUE;
+ ImplCalcSet2( pWindow, pItems[i].mpSet, bTempHide,
+ ((pItems[i].mnBits & SWIB_COLSET) == 0) );
+ }
+ else
+ {
+ if ( pItems[i].mnWidth && pItems[i].mnHeight && !bHide )
+ {
+ Point aPos( pItems[i].mnLeft, pItems[i].mnTop );
+ Size aSize( pItems[i].mnWidth, pItems[i].mnHeight );
+ pItems[i].mpWindow->SetPosSizePixel( aPos, aSize );
+ }
+ else
+ pItems[i].mpWindow->Hide();
+ }
+ }
+
+ // Fenster anzeigen und Flag zuruecksetzen
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpWindow && pItems[i].mnWidth && pItems[i].mnHeight && !bHide )
+ pItems[i].mpWindow->Show();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalcLogSize( ImplSplitItem* pItems, USHORT nItems )
+{
+ // Original-Groessen updaten
+ USHORT i;
+ long nRelSize = 0;
+ long nPerSize = 0;
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
+ nRelSize += pItems[i].mnPixSize;
+ else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
+ nPerSize += pItems[i].mnPixSize;
+ }
+ nPerSize += nRelSize;
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
+ {
+ if ( nRelSize )
+ pItems[i].mnSize = (pItems[i].mnPixSize+(nRelSize/2))/nRelSize;
+ else
+ pItems[i].mnSize = 1;
+ }
+ else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
+ {
+ if ( nPerSize )
+ pItems[i].mnSize = (pItems[i].mnPixSize*100)/nPerSize;
+ else
+ pItems[i].mnSize = 1;
+ }
+ else
+ pItems[i].mnSize = pItems[i].mnPixSize;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawBack( SplitWindow* pWindow, const Rectangle& rRect,
+ const Wallpaper* pWall, const Bitmap* pBitmap )
+{
+ if ( pBitmap )
+ {
+ Point aPos = rRect.TopLeft();
+ Size aBmpSize = pBitmap->GetSizePixel();
+ pWindow->Push( PUSH_CLIPREGION );
+ pWindow->IntersectClipRegion( rRect );
+ do
+ {
+ aPos.X() = rRect.Left();
+ do
+ {
+ pWindow->DrawBitmap( aPos, *pBitmap );
+ aPos.X() += aBmpSize.Width();
+ }
+ while ( aPos.X() < rRect.Right() );
+ aPos.Y() += aBmpSize.Height();
+ }
+ while ( aPos.Y() < rRect.Bottom() );
+ pWindow->Pop();
+ }
+ else
+ pWindow->DrawWallpaper( rRect, *pWall );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawBack( SplitWindow* pWindow, ImplSplitSet* pSet )
+{
+ USHORT i;
+ USHORT nItems = pSet->mnItems;
+ ImplSplitItem* pItems = pSet->mpItems;
+
+ // Beim Mainset auch den Hintergrund zeichnen
+ if ( pSet->mnId == 0 )
+ {
+ if ( pSet->mpBitmap )
+ {
+ Rectangle aRect( pWindow->mnLeftBorder,
+ pWindow->mnTopBorder,
+ pWindow->mnDX-pWindow->mnRightBorder-1,
+ pWindow->mnDY-pWindow->mnBottomBorder-1 );
+ ImplDrawBack( pWindow, aRect, pSet->mpWallpaper, pSet->mpBitmap );
+ }
+ }
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ pSet = pItems[i].mpSet;
+ if ( pSet )
+ {
+ if ( pSet->mpBitmap || pSet->mpWallpaper )
+ {
+ // Wegen ICC auftrennen
+ Point aPoint( pItems[i].mnLeft, pItems[i].mnTop );
+ Size aSize( pItems[i].mnWidth, pItems[i].mnHeight );
+ Rectangle aRect( aPoint, aSize );
+ ImplDrawBack( pWindow, aRect, pSet->mpWallpaper, pSet->mpBitmap );
+ }
+ }
+ }
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpSet )
+ ImplDrawBack( pWindow, pItems[i].mpSet );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawSplit( SplitWindow* pWindow, ImplSplitSet* pSet,
+ BOOL bRows, BOOL bDown = TRUE )
+{
+ if ( !pSet->mpItems )
+ return;
+
+ USHORT i;
+ USHORT nItems = pSet->mnItems;
+ long nPos;
+ long nTop;
+ long nBottom;
+ ImplSplitItem* pItems = pSet->mpItems;
+ const StyleSettings& rStyleSettings = pWindow->GetSettings().GetStyleSettings();
+
+ BOOL bFlat = (pWindow->GetStyle() & WB_FLATSPLITDRAW) == WB_FLATSPLITDRAW;
+
+ for ( i = 0; i < nItems-1; i++ )
+ {
+ if ( pItems[i].mnSplitSize )
+ {
+ nPos = pItems[i].mnSplitPos;
+
+ long nItemSplitSize = pItems[i].mnSplitSize;
+ long nSplitSize = pSet->mnSplitSize;
+ if ( bRows )
+ {
+ nTop = pItems[i].mnLeft;
+ nBottom = pItems[i].mnLeft+pItems[i].mnWidth-1;
+
+ if ( bFlat ) nPos--;
+
+ if ( bDown || (nItemSplitSize >= nSplitSize) )
+ {
+ pWindow->SetLineColor( rStyleSettings.GetLightColor() );
+ pWindow->DrawLine( Point( nTop, nPos+1 ), Point( nBottom, nPos+1 ) );
+ }
+ nPos += nSplitSize-2;
+ if ( bFlat ) nPos+=2;
+ if ( (!bDown && (nItemSplitSize >= 2)) ||
+ (bDown && (nItemSplitSize >= nSplitSize-1)) )
+ {
+ pWindow->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWindow->DrawLine( Point( nTop, nPos ), Point( nBottom, nPos ) );
+ }
+ if ( !bFlat )
+ {
+ nPos++;
+ if ( !bDown || (nItemSplitSize >= nSplitSize) )
+ {
+ pWindow->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ pWindow->DrawLine( Point( nTop, nPos ), Point( nBottom, nPos ) );
+ }
+ }
+ }
+ else
+ {
+ nTop = pItems[i].mnTop;
+ nBottom = pItems[i].mnTop+pSet->mpItems[i].mnHeight-1;
+
+ if ( bFlat ) nPos--;
+ if ( bDown || (nItemSplitSize >= nSplitSize) )
+ {
+ pWindow->SetLineColor( rStyleSettings.GetLightColor() );
+ pWindow->DrawLine( Point( nPos+1, nTop ), Point( nPos+1, nBottom ) );
+ }
+ nPos += pSet->mnSplitSize-2;
+ if ( bFlat ) nPos+=2;
+ if ( (!bDown && (nItemSplitSize >= 2)) ||
+ (bDown && (nItemSplitSize >= nSplitSize-1)) )
+ {
+ pWindow->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWindow->DrawLine( Point( nPos, nTop ), Point( nPos, nBottom ) );
+ }
+ if( !bFlat )
+ {
+ nPos++;
+ if ( !bDown || (nItemSplitSize >= nSplitSize) )
+ {
+ pWindow->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ pWindow->DrawLine( Point( nPos, nTop ), Point( nPos, nBottom ) );
+ }
+ }
+ }
+ }
+ }
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpSet && pItems[i].mnWidth && pItems[i].mnHeight )
+ ImplDrawSplit( pWindow, pItems[i].mpSet, ((pItems[i].mnBits & SWIB_COLSET) == 0) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplTestSplit( ImplSplitSet* pSet, const Point& rPos,
+ long& rMouseOff, ImplSplitSet** ppFoundSet, USHORT& rFoundPos,
+ BOOL bRows, BOOL bDown = TRUE )
+{
+ if ( !pSet->mpItems )
+ return 0;
+
+ USHORT i;
+ USHORT nSplitTest;
+ USHORT nItems = pSet->mnItems;
+ long nMPos1;
+ long nMPos2;
+ long nPos;
+ long nTop;
+ long nBottom;
+ ImplSplitItem* pItems = pSet->mpItems;
+
+ if ( bRows )
+ {
+ nMPos1 = rPos.X();
+ nMPos2 = rPos.Y();
+ }
+ else
+ {
+ nMPos1 = rPos.Y();
+ nMPos2 = rPos.X();
+ }
+
+ for ( i = 0; i < nItems-1; i++ )
+ {
+ if ( pItems[i].mnSplitSize )
+ {
+ if ( bRows )
+ {
+ nTop = pItems[i].mnLeft;
+ nBottom = pItems[i].mnLeft+pItems[i].mnWidth-1;
+ }
+ else
+ {
+ nTop = pItems[i].mnTop;
+ nBottom = pItems[i].mnTop+pItems[i].mnHeight-1;
+ }
+ nPos = pItems[i].mnSplitPos;
+
+ if ( (nMPos1 >= nTop) && (nMPos1 <= nBottom) &&
+ (nMPos2 >= nPos) && (nMPos2 <= nPos+pItems[i].mnSplitSize) )
+ {
+ if ( !pItems[i].mbFixed && !pItems[i+1].mbFixed )
+ {
+ rMouseOff = nMPos2-nPos;
+ *ppFoundSet = pSet;
+ rFoundPos = i;
+ if ( bRows )
+ return SPLIT_VERT;
+ else
+ return SPLIT_HORZ;
+ }
+ else
+ return SPLIT_NOSPLIT;
+ }
+ }
+ }
+
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mpSet )
+ {
+ nSplitTest = ImplTestSplit( pItems[i].mpSet, rPos,
+ rMouseOff, ppFoundSet, rFoundPos,
+ ((pItems[i].mnBits & SWIB_COLSET) == 0) );
+ if ( nSplitTest )
+ return nSplitTest;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplTestSplit( SplitWindow* pWindow, const Point& rPos,
+ long& rMouseOff, ImplSplitSet** ppFoundSet, USHORT& rFoundPos )
+{
+ // Resizeable SplitWindow muss anders behandelt werden
+ if ( pWindow->mnWinStyle & WB_SIZEABLE )
+ {
+ long nTPos;
+ long nPos;
+ long nBorder;
+
+ if ( pWindow->mbHorz )
+ {
+ if ( pWindow->mbBottomRight )
+ {
+ nBorder = pWindow->mnBottomBorder;
+ nPos = 0;
+ }
+ else
+ {
+ nBorder = pWindow->mnTopBorder;
+ nPos = pWindow->mnDY-nBorder;
+ }
+ nTPos = rPos.Y();
+ }
+ else
+ {
+ if ( pWindow->mbBottomRight )
+ {
+ nBorder = pWindow->mnRightBorder;
+ nPos = 0;
+ }
+ else
+ {
+ nBorder = pWindow->mnLeftBorder;
+ nPos = pWindow->mnDX-nBorder;
+ }
+ nTPos = rPos.X();
+ }
+ long nSplitSize = pWindow->mpMainSet->mnSplitSize-2;
+ if ( pWindow->mbAutoHide || pWindow->mbFadeOut )
+ nSplitSize += SPLITWIN_SPLITSIZEEX;
+ if ( !pWindow->mbBottomRight )
+ nPos -= nSplitSize;
+ if ( (nTPos >= nPos) && (nTPos <= nPos+nSplitSize+nBorder) )
+ {
+ rMouseOff = nTPos-nPos;
+ *ppFoundSet = pWindow->mpMainSet;
+ if ( pWindow->mpMainSet->mpItems )
+ rFoundPos = pWindow->mpMainSet->mnItems-1;
+ else
+ rFoundPos = 0;
+ if ( pWindow->mbHorz )
+ return SPLIT_VERT | SPLIT_WINDOW;
+ else
+ return SPLIT_HORZ | SPLIT_WINDOW;
+ }
+ }
+
+ return ImplTestSplit( pWindow->mpMainSet, rPos, rMouseOff, ppFoundSet, rFoundPos,
+ pWindow->mbHorz, !pWindow->mbBottomRight );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawSplitTracking( SplitWindow* pThis, const Point& rPos )
+{
+ Rectangle aRect;
+
+ if ( pThis->mnSplitTest & SPLIT_HORZ )
+ {
+ aRect.Top() = pThis->maDragRect.Top();
+ aRect.Bottom() = pThis->maDragRect.Bottom();
+ aRect.Left() = rPos.X();
+ aRect.Right() = aRect.Left()+pThis->mpSplitSet->mnSplitSize-1;
+ if ( !(pThis->mnWinStyle & WB_NOSPLITDRAW) )
+ aRect.Right()--;
+ if ( (pThis->mnSplitTest & SPLIT_WINDOW) &&
+ (pThis->mbAutoHide || pThis->mbFadeOut) )
+ {
+ aRect.Left() += SPLITWIN_SPLITSIZEEX;
+ aRect.Right() += SPLITWIN_SPLITSIZEEX;
+ }
+ }
+ else
+ {
+ aRect.Left() = pThis->maDragRect.Left();
+ aRect.Right() = pThis->maDragRect.Right();
+ aRect.Top() = rPos.Y();
+ aRect.Bottom() = aRect.Top()+pThis->mpSplitSet->mnSplitSize-1;
+ if ( !(pThis->mnWinStyle & WB_NOSPLITDRAW) )
+ aRect.Bottom()--;
+ if ( (pThis->mnSplitTest & SPLIT_WINDOW) &&
+ (pThis->mbAutoHide || pThis->mbFadeOut) )
+ {
+ aRect.Top() += SPLITWIN_SPLITSIZEEX;
+ aRect.Bottom() += SPLITWIN_SPLITSIZEEX;
+ }
+ }
+ pThis->ShowTracking( aRect, SHOWTRACK_SPLIT );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplInit( Window* pParent, WinBits nStyle )
+{
+ ImplSplitSet* pNewSet = new ImplSplitSet;
+ pNewSet->mpItems = NULL;
+ pNewSet->mpWallpaper = NULL;
+ pNewSet->mpBitmap = NULL;
+ pNewSet->mnLastSize = 0;
+ pNewSet->mnItems = 0;
+ pNewSet->mnId = 0;
+ pNewSet->mnSplitSize = SPLITWIN_SPLITSIZE;
+ pNewSet->mbCalcPix = TRUE;
+
+ mpMainSet = pNewSet;
+ mpBaseSet = pNewSet;
+ mpSplitSet = NULL;
+ mpLastSizes = NULL;
+ mnDX = 0;
+ mnDY = 0;
+ mnLeftBorder = 0;
+ mnTopBorder = 0;
+ mnRightBorder = 0;
+ mnBottomBorder = 0;
+ mnMaxSize = 0;
+ mnMouseOff = 0;
+ meAlign = WINDOWALIGN_TOP;
+ mnWinStyle = nStyle;
+ mnSplitTest = 0;
+ mnSplitPos = 0;
+ mnMouseModifier = 0;
+ mnMStartPos = 0;
+ mnMSplitPos = 0;
+ mbDragFull = FALSE;
+ mbHorz = TRUE;
+ mbBottomRight = FALSE;
+ mbCalc = FALSE;
+ mbRecalc = TRUE;
+ mbInvalidate = TRUE;
+ mbAutoHide = FALSE;
+ mbFadeIn = FALSE;
+ mbFadeOut = FALSE;
+ mbAutoHideIn = FALSE;
+ mbAutoHideDown = FALSE;
+ mbFadeInDown = FALSE;
+ mbFadeOutDown = FALSE;
+ mbAutoHidePressed = FALSE;
+ mbFadeInPressed = FALSE;
+ mbFadeOutPressed = FALSE;
+ mbFadeNoButtonMode = FALSE;
+ mbNoAlign = FALSE;
+
+ if ( nStyle & WB_NOSPLITDRAW )
+ {
+ pNewSet->mnSplitSize -= 2;
+ mbInvalidate = FALSE;
+ }
+
+ if ( nStyle & WB_BORDER )
+ {
+ ImplCalcBorder( meAlign, mbNoAlign, mnLeftBorder, mnTopBorder,
+ mnRightBorder, mnBottomBorder );
+ }
+ else
+ {
+ mnLeftBorder = 0;
+ mnTopBorder = 0;
+ mnRightBorder = 0;
+ mnBottomBorder = 0;
+ }
+
+ DockingWindow::ImplInit( pParent, (nStyle | WB_CLIPCHILDREN) & ~(WB_BORDER | WB_SIZEABLE) );
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplInitSettings()
+{
+ // Wenn fuer das MainSet eine Bitmap gesetzt wird, dann
+ // brauchen wir nicht mehr den Hintergrund loeschen
+ // Wenn MainSet Wallpaper hat, dann ist das der Hintergrund, ansonsten
+ // sind es die Standard-Farben
+ if ( mpMainSet->mpBitmap )
+ SetBackground();
+ else if ( mpMainSet->mpWallpaper )
+ SetBackground( *mpMainSet->mpWallpaper );
+ else
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else if ( Window::GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetFaceColor();
+ else
+ aColor = rStyleSettings.GetWindowColor();
+ SetBackground( aColor );
+ }
+}
+
+// =======================================================================
+
+SplitWindow::SplitWindow( Window* pParent, WinBits nStyle ) :
+ DockingWindow( WINDOW_SPLITWINDOW )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+SplitWindow::SplitWindow( Window* pParent, const ResId& rResId ) :
+ DockingWindow( WINDOW_SPLITWINDOW )
+{
+ rResId.SetRT( RSC_SPLITWINDOW );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+SplitWindow::~SplitWindow()
+{
+ // Sets loeschen
+ ImplDeleteSet( mpMainSet );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplSetWindowSize( long nDelta )
+{
+ if ( !nDelta )
+ return;
+
+ Size aSize = GetSizePixel();
+ if ( meAlign == WINDOWALIGN_TOP )
+ {
+ aSize.Height() += nDelta;
+ SetSizePixel( aSize );
+ }
+ else if ( meAlign == WINDOWALIGN_BOTTOM )
+ {
+ Point aPos = GetPosPixel();
+ aPos.Y() -= nDelta;
+ aSize.Height() += nDelta;
+ SetPosSizePixel( aPos, aSize );
+ }
+ else if ( meAlign == WINDOWALIGN_LEFT )
+ {
+ aSize.Width() += nDelta;
+ SetSizePixel( aSize );
+ }
+ else // meAlign == WINDOWALIGN_RIGHT
+ {
+ Point aPos = GetPosPixel();
+ aPos.X() -= nDelta;
+ aSize.Width() += nDelta;
+ SetPosSizePixel( aPos, aSize );
+ }
+
+ SplitResize();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplCalcLayout()
+{
+ if ( !mbCalc || !mbRecalc || !mpMainSet->mpItems )
+ return;
+
+ long nSplitSize = mpMainSet->mnSplitSize-2;
+ if ( mbAutoHide || mbFadeOut )
+ nSplitSize += SPLITWIN_SPLITSIZEEX;
+
+ // Wenn Fenster sizeable ist, wird die groesse automatisch nach
+ // dem MainSet festgelegt, wenn kein relatives Fenster enthalten
+ // ist
+ if ( mnWinStyle & WB_SIZEABLE )
+ {
+ long nCurSize;
+ long nCalcSize = 0;
+ USHORT i;
+
+ for ( i = 0; i < mpMainSet->mnItems; i++ )
+ {
+ if ( mpMainSet->mpItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE) )
+ break;
+ else
+ nCalcSize += mpMainSet->mpItems[i].mnSize;
+ }
+
+ if ( i == mpMainSet->mnItems )
+ {
+ if ( mbHorz )
+ nCurSize = mnDY-mnTopBorder-mnBottomBorder;
+ else
+ nCurSize = mnDX-mnLeftBorder-mnRightBorder;
+ nCurSize -= nSplitSize;
+ nCurSize -= (mpMainSet->mnItems-1)*mpMainSet->mnSplitSize;
+
+ mbRecalc = FALSE;
+ ImplSetWindowSize( nCalcSize-nCurSize );
+ mbRecalc = TRUE;
+ }
+ }
+
+ if ( (mnDX <= 0) || (mnDY <= 0) )
+ return;
+
+ // Groessen/Position vorberechnen
+ long nL;
+ long nT;
+ long nW;
+ long nH;
+
+ if ( mbHorz )
+ {
+ if ( mbBottomRight )
+ nT = mnDY-mnBottomBorder;
+ else
+ nT = mnTopBorder;
+ nL = mnLeftBorder;
+ }
+ else
+ {
+ if ( mbBottomRight )
+ nL = mnDX-mnRightBorder;
+ else
+ nL = mnLeftBorder;
+ nT = mnTopBorder;
+ }
+ nW = mnDX-mnLeftBorder-mnRightBorder;
+ nH = mnDY-mnTopBorder-mnBottomBorder;
+ if ( mnWinStyle & WB_SIZEABLE )
+ {
+ if ( mbHorz )
+ nH -= nSplitSize;
+ else
+ nW -= nSplitSize;
+ }
+
+ // Sets rekursiv berechnen
+ ImplCalcSet( mpMainSet, nL, nT, nW, nH, mbHorz, !mbBottomRight );
+ ImplCalcSet2( this, mpMainSet, FALSE, mbHorz, !mbBottomRight );
+ mbCalc = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplUpdate()
+{
+ mbCalc = TRUE;
+
+ if ( IsReallyShown() && IsUpdateMode() && mbRecalc )
+ {
+ if ( mpMainSet->mpItems )
+ ImplCalcLayout();
+ else
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplUpdateSet( ImplSplitSet* pSet )
+{
+ if ( IsReallyShown() && IsUpdateMode() && mbRecalc )
+ {
+ // Wenn wir noch berechnen muessen, dann alles invalidieren.
+ if ( mbCalc )
+ {
+ // Wenn nicht NOSPLITDRAW gesetzt ist, koennen wir uns das
+ // invalidieren sparen, da bei ImplCalcSet2() die freien flaechen
+ // sowieso invalidiert werden
+ if ( !mpMainSet->mpItems || (mnWinStyle & WB_NOSPLITDRAW) )
+ pSet = mpMainSet;
+ else
+ return;
+ }
+
+ Rectangle aRect;
+ if ( pSet == mpMainSet )
+ {
+ aRect.Left() = mnLeftBorder;
+ aRect.Top() = mnTopBorder;
+ aRect.Right() = mnDX-mnRightBorder-1;
+ aRect.Bottom() = mnDY-mnBottomBorder-1;
+ }
+ else
+ {
+ ImplSplitItem* pItem;
+ USHORT nPos;
+
+ pSet = ImplFindItem( mpMainSet, pSet->mnId, nPos );
+ pItem = &(pSet->mpItems[nPos]);
+ aRect.Left() = pItem->mnLeft;
+ aRect.Top() = pItem->mnTop;
+ aRect.Right() = aRect.Left()+pItem->mnWidth;
+ aRect.Bottom() = aRect.Top()+pItem->mnHeight;
+ }
+ Invalidate( aRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplSplitMousePos( Point& rMousePos )
+{
+ if ( mnSplitTest & SPLIT_HORZ )
+ {
+ rMousePos.X() -= mnMouseOff;
+ if ( rMousePos.X() < maDragRect.Left() )
+ rMousePos.X() = maDragRect.Left();
+ else if ( rMousePos.X()+mpSplitSet->mnSplitSize+1 > maDragRect.Right() )
+ rMousePos.X() = maDragRect.Right()-mpSplitSet->mnSplitSize+1;
+ // Wegen FullDrag in Screen-Koordinaaten merken
+ mnMSplitPos = OutputToScreenPixel( rMousePos ).X();
+ }
+ else
+ {
+ rMousePos.Y() -= mnMouseOff;
+ if ( rMousePos.Y() < maDragRect.Top() )
+ rMousePos.Y() = maDragRect.Top();
+ else if ( rMousePos.Y()+mpSplitSet->mnSplitSize+1 > maDragRect.Bottom() )
+ rMousePos.Y() = maDragRect.Bottom()-mpSplitSet->mnSplitSize+1;
+ mnMSplitPos = OutputToScreenPixel( rMousePos ).Y();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplGetButtonRect( Rectangle& rRect, long nEx, BOOL bTest ) const
+{
+ long nSplitSize = mpMainSet->mnSplitSize-2;
+ if ( mbAutoHide || mbFadeOut || mbFadeIn )
+ nSplitSize += SPLITWIN_SPLITSIZEEX;
+
+/* Wir wollen doch erstmal nicht zentrieren
+ long nButtonSize = 0;
+ if ( mbFadeIn )
+ nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
+ if ( mbFadeOut )
+ nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
+ if ( mbAutoHide )
+ nButtonSize += SPLITWIN_SPLITSIZEAUTOHIDE+1;
+ long nCenterEx = 0;
+ if ( mbHorz )
+ nCenterEx += ((mnDX-mnLeftBorder-mnRightBorder)-nButtonSize)/2;
+ else
+ nCenterEx += ((mnDY-mnTopBorder-mnBottomBorder)-nButtonSize)/2;
+ if ( nCenterEx > 0 )
+ nEx += nCenterEx;
+*/
+
+ if ( meAlign == WINDOWALIGN_TOP )
+ {
+ rRect.Left() = mnLeftBorder+nEx;
+ rRect.Top() = mnDY-mnBottomBorder-nSplitSize;
+ rRect.Right() = rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE;
+ rRect.Bottom() = mnDY-mnBottomBorder-1;
+ if ( bTest )
+ {
+ rRect.Top() -= mnTopBorder;
+ rRect.Bottom() += mnBottomBorder;
+ }
+ }
+ else if ( meAlign == WINDOWALIGN_BOTTOM )
+ {
+ rRect.Left() = mnLeftBorder+nEx;
+ rRect.Top() = mnTopBorder;
+ rRect.Right() = rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE;
+ rRect.Bottom() = mnTopBorder+nSplitSize-1;
+ if ( bTest )
+ {
+ rRect.Top() -= mnTopBorder;
+ rRect.Bottom() += mnBottomBorder;
+ }
+ }
+ else if ( meAlign == WINDOWALIGN_LEFT )
+ {
+ rRect.Left() = mnDX-mnRightBorder-nSplitSize;
+ rRect.Top() = mnTopBorder+nEx;
+ rRect.Right() = mnDX-mnRightBorder-1;
+ rRect.Bottom() = rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE;
+ if ( bTest )
+ {
+ rRect.Left() -= mnLeftBorder;
+ rRect.Right() += mnRightBorder;
+ }
+ }
+ else if ( meAlign == WINDOWALIGN_RIGHT )
+ {
+ rRect.Left() = mnLeftBorder;
+ rRect.Top() = mnTopBorder+nEx;
+ rRect.Right() = mnLeftBorder+nSplitSize-1;
+ rRect.Bottom() = rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE;
+ if ( bTest )
+ {
+ rRect.Left() -= mnLeftBorder;
+ rRect.Right() += mnRightBorder;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplGetAutoHideRect( Rectangle& rRect, BOOL bTest ) const
+{
+ Rectangle aRect;
+
+ if ( mbAutoHide )
+ {
+ long nEx = 0;
+ if ( mbFadeIn || mbFadeOut )
+ nEx = SPLITWIN_SPLITSIZEFADE+1;
+ ImplGetButtonRect( aRect, nEx, bTest && mbFadeIn );
+ }
+
+ rRect = aRect;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplGetFadeInRect( Rectangle& rRect, BOOL bTest ) const
+{
+ Rectangle aRect;
+
+ if ( mbFadeIn )
+ ImplGetButtonRect( aRect, 0, bTest );
+
+ rRect = aRect;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplGetFadeOutRect( Rectangle& rRect, BOOL ) const
+{
+ Rectangle aRect;
+
+ if ( mbFadeOut )
+ ImplGetButtonRect( aRect, 0, FALSE );
+
+ rRect = aRect;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplDrawButtonRect( const Rectangle& rRect, long nSize )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( mbHorz )
+ {
+ long nLeft = rRect.Left();
+ long nRight = rRect.Right();
+ long nCenter = rRect.Center().Y();
+ long nEx1 = nLeft+((rRect.GetWidth()-nSize)/2)-2;
+ long nEx2 = nEx1+nSize+3;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Left(), rRect.Bottom() ) );
+ DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Right(), rRect.Top() ) );
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( rRect.Right(), rRect.Top() ), Point( rRect.Right(), rRect.Bottom() ) );
+ DrawLine( Point( rRect.Left(), rRect.Bottom() ), Point( rRect.Right(), rRect.Bottom() ) );
+ long i = nLeft+2;
+ while ( i < nRight-3 )
+ {
+ if ( (i < nEx1) || (i > nEx2 ) )
+ {
+ DrawPixel( Point( i, nCenter-2 ), rStyleSettings.GetLightColor() );
+ DrawPixel( Point( i+1, nCenter-2+1 ), rStyleSettings.GetShadowColor() );
+ }
+ i++;
+ if ( (i < nEx1) || (i > nEx2 ) && (i < nRight-3) )
+ {
+ DrawPixel( Point( i, nCenter+2 ), rStyleSettings.GetLightColor() );
+ DrawPixel( Point( i+1, nCenter+2+1 ), rStyleSettings.GetShadowColor() );
+ }
+ i += 2;
+ }
+ }
+ else
+ {
+ long nTop = rRect.Top();
+ long nBottom = rRect.Bottom();
+ long nCenter = rRect.Center().X();
+ long nEx1 = nTop+((rRect.GetHeight()-nSize)/2)-2;
+ long nEx2 = nEx1+nSize+3;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Right(), rRect.Top() ) );
+ DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Left(), rRect.Bottom() ) );
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( rRect.Right(), rRect.Top() ), Point( rRect.Right(), rRect.Bottom() ) );
+ DrawLine( Point( rRect.Left(), rRect.Bottom() ), Point( rRect.Right(), rRect.Bottom() ) );
+ long i = nTop+2;
+ while ( i < nBottom-3 )
+ {
+ if ( (i < nEx1) || (i > nEx2 ) )
+ {
+ DrawPixel( Point( nCenter-2, i ), rStyleSettings.GetLightColor() );
+ DrawPixel( Point( nCenter-2+1, i+1 ), rStyleSettings.GetShadowColor() );
+ }
+ i++;
+ if ( (i < nEx1) || (i > nEx2 ) && (i < nBottom-3) )
+ {
+ DrawPixel( Point( nCenter+2, i ), rStyleSettings.GetLightColor() );
+ DrawPixel( Point( nCenter+2+1, i+1 ), rStyleSettings.GetShadowColor() );
+ }
+ i += 2;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplDrawAutoHide( BOOL bInPaint )
+{
+ if ( mbAutoHide )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aTempRect;
+ ImplGetAutoHideRect( aTempRect );
+
+ if ( !bInPaint )
+ Erase( aTempRect );
+
+ // ImageListe laden, wenn noch nicht vorhanden
+ ImplSVData* pSVData = ImplGetSVData();
+ ImageList* pImageList;
+ if ( mbHorz )
+ {
+ if ( !pSVData->maCtrlData.mpSplitHPinImgList )
+ {
+ Bitmap aBmp( ResId( SV_RESID_BITMAP_SPLITHPIN, ImplGetResMgr() ) );
+ pSVData->maCtrlData.mpSplitHPinImgList = new ImageList( aBmp, Color( 0x00, 0x00, 0xFF ), 4 );
+ }
+ pImageList = pSVData->maCtrlData.mpSplitHPinImgList;
+ }
+ else
+ {
+ if ( !pSVData->maCtrlData.mpSplitVPinImgList )
+ {
+ Bitmap aBmp( ResId( SV_RESID_BITMAP_SPLITVPIN, ImplGetResMgr() ) );
+ pSVData->maCtrlData.mpSplitVPinImgList = new ImageList( aBmp, Color( 0x00, 0x00, 0xFF ), 4 );
+ }
+ pImageList = pSVData->maCtrlData.mpSplitVPinImgList;
+ }
+
+ // Image ermitteln und zurueckgeben
+ USHORT nId;
+ if ( mbAutoHidePressed )
+ {
+ if ( mbAutoHideIn )
+ nId = 3;
+ else
+ nId = 4;
+ }
+ else
+ {
+ if ( mbAutoHideIn )
+ nId = 1;
+ else
+ nId = 2;
+ }
+
+ Image aImage = pImageList->GetImage( nId );
+ Size aImageSize = aImage.GetSizePixel();
+ Point aPos( aTempRect.Left()+((aTempRect.GetWidth()-aImageSize.Width())/2),
+ aTempRect.Top()+((aTempRect.GetHeight()-aImageSize.Height())/2) );
+ long nSize;
+ if ( mbHorz )
+ nSize = aImageSize.Width();
+ else
+ nSize = aImageSize.Height();
+ ImplDrawButtonRect( aTempRect, nSize );
+ DrawImage( aPos, aImage );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetSplitArrowImage( BOOL bHorz, BOOL bLeft, BOOL bPressed,
+ Image& rImage )
+{
+ // ImageListe laden, wenn noch nicht vorhanden
+ ImplSVData* pSVData = ImplGetSVData();
+ ImageList* pImageList;
+ if ( bHorz )
+ {
+ if ( !pSVData->maCtrlData.mpSplitHArwImgList )
+ {
+ Bitmap aBmp( ResId( SV_RESID_BITMAP_SPLITHARW, ImplGetResMgr() ) );
+ pSVData->maCtrlData.mpSplitHArwImgList = new ImageList( aBmp, Color( 0x00, 0x00, 0xFF ), 4 );
+ }
+ pImageList = pSVData->maCtrlData.mpSplitHArwImgList;
+ }
+ else
+ {
+ if ( !pSVData->maCtrlData.mpSplitVArwImgList )
+ {
+ Bitmap aBmp( ResId( SV_RESID_BITMAP_SPLITVARW, ImplGetResMgr() ) );
+ pSVData->maCtrlData.mpSplitVArwImgList = new ImageList( aBmp, Color( 0x00, 0x00, 0xFF ), 4 );
+ }
+ pImageList = pSVData->maCtrlData.mpSplitVArwImgList;
+ }
+
+ // Image ermitteln und zurueckgeben
+ USHORT nId = 1;
+ if ( !bLeft )
+ nId += 2;
+ if ( bPressed )
+ nId++;
+
+ rImage = pImageList->GetImage( nId );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplDrawFadeIn( BOOL bInPaint )
+{
+ if ( mbFadeIn )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aTempRect;
+ Image aImage;
+ ImplGetFadeInRect( aTempRect );
+
+ BOOL bLeft;
+ if ( meAlign == WINDOWALIGN_TOP )
+ bLeft = FALSE;
+ else if ( meAlign == WINDOWALIGN_BOTTOM )
+ bLeft = TRUE;
+ else if ( meAlign == WINDOWALIGN_LEFT )
+ bLeft = FALSE;
+ else if ( meAlign == WINDOWALIGN_RIGHT )
+ bLeft = TRUE;
+ ImplGetSplitArrowImage( mbHorz, bLeft, mbFadeInPressed, aImage );
+
+ if ( !bInPaint )
+ Erase( aTempRect );
+
+ Size aImageSize = aImage.GetSizePixel();
+ Point aPos( aTempRect.Left()+((aTempRect.GetWidth()-aImageSize.Width())/2),
+ aTempRect.Top()+((aTempRect.GetHeight()-aImageSize.Height())/2) );
+ long nSize;
+ if ( mbHorz )
+ nSize = aImageSize.Width();
+ else
+ nSize = aImageSize.Height();
+ ImplDrawButtonRect( aTempRect, nSize );
+ DrawImage( aPos, aImage );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplDrawFadeOut( BOOL bInPaint )
+{
+ if ( mbFadeOut )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aTempRect;
+ Image aImage;
+ ImplGetFadeOutRect( aTempRect );
+
+ BOOL bLeft;
+ if ( meAlign == WINDOWALIGN_TOP )
+ bLeft = TRUE;
+ else if ( meAlign == WINDOWALIGN_BOTTOM )
+ bLeft = FALSE;
+ else if ( meAlign == WINDOWALIGN_LEFT )
+ bLeft = TRUE;
+ else if ( meAlign == WINDOWALIGN_RIGHT )
+ bLeft = FALSE;
+ ImplGetSplitArrowImage( mbHorz, bLeft, mbFadeOutPressed, aImage );
+
+ if ( !bInPaint )
+ Erase( aTempRect );
+
+ Size aImageSize = aImage.GetSizePixel();
+ Point aPos( aTempRect.Left()+((aTempRect.GetWidth()-aImageSize.Width())/2),
+ aTempRect.Top()+((aTempRect.GetHeight()-aImageSize.Height())/2) );
+ long nSize;
+ if ( mbHorz )
+ nSize = aImageSize.Width();
+ else
+ nSize = aImageSize.Height();
+ ImplDrawButtonRect( aTempRect, nSize );
+ DrawImage( aPos, aImage );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::StartSplit()
+{
+ maStartSplitHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::Split()
+{
+ maSplitHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SplitResize()
+{
+ maSplitResizeHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::AutoHide()
+{
+ maAutoHideHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::FadeIn()
+{
+ maFadeInHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::FadeOut()
+{
+ maFadeOutHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( !rMEvt.IsLeft() || rMEvt.IsMod2() )
+ {
+ DockingWindow::MouseButtonDown( rMEvt );
+ return;
+ }
+
+ Point aMousePosPixel = rMEvt.GetPosPixel();
+ Rectangle aTestRect;
+
+ mbFadeNoButtonMode = FALSE;
+ ImplGetAutoHideRect( aTestRect, TRUE );
+ if ( aTestRect.IsInside( aMousePosPixel ) )
+ {
+ mbAutoHideDown = TRUE;
+ mbAutoHidePressed = TRUE;
+ ImplDrawAutoHide( FALSE );
+ }
+ else
+ {
+ ImplGetFadeOutRect( aTestRect, TRUE );
+ if ( aTestRect.IsInside( aMousePosPixel ) )
+ {
+ mbFadeOutDown = TRUE;
+ mbFadeOutPressed = TRUE;
+ ImplDrawFadeOut( FALSE );
+ }
+ else
+ {
+ ImplGetFadeInRect( aTestRect, TRUE );
+ if ( aTestRect.IsInside( aMousePosPixel ) )
+ {
+ mbFadeInDown = TRUE;
+ mbFadeInPressed = TRUE;
+ ImplDrawFadeIn( FALSE );
+ }
+ else if ( !aTestRect.IsEmpty() && !(mnWinStyle & WB_SIZEABLE) )
+ {
+ mbFadeNoButtonMode = TRUE;
+ FadeIn();
+ return;
+ }
+ }
+ }
+
+ if ( mbAutoHideDown || mbFadeInDown || mbFadeOutDown )
+ StartTracking();
+ else
+ {
+ mnSplitTest = ImplTestSplit( this, aMousePosPixel, mnMouseOff, &mpSplitSet, mnSplitPos );
+ if ( mnSplitTest && !(mnSplitTest & SPLIT_NOSPLIT) )
+ {
+ ImplSplitItem* pSplitItem;
+ long nCurMaxSize;
+ USHORT nTemp;
+ BOOL bDown;
+ BOOL bPropSmaller;
+
+ mnMouseModifier = rMEvt.GetModifier();
+ if ( !(mnMouseModifier & KEY_SHIFT) || (mnSplitPos+1 >= mpSplitSet->mnItems) )
+ bPropSmaller = FALSE;
+ else
+ bPropSmaller = TRUE;
+
+ // Hier kann noch die maximale Groesse gesetzt werden
+ StartSplit();
+
+ if ( mnMaxSize )
+ nCurMaxSize = mnMaxSize;
+ else
+ {
+ Size aSize = GetParent()->GetOutputSizePixel();
+ if ( mbHorz )
+ nCurMaxSize = aSize.Height();
+ else
+ nCurMaxSize = aSize.Width();
+ }
+
+ if ( mpSplitSet->mpItems )
+ {
+ bDown = TRUE;
+ if ( (mpSplitSet == mpMainSet) && mbBottomRight )
+ bDown = FALSE;
+
+ pSplitItem = &(mpSplitSet->mpItems[mnSplitPos]);
+ maDragRect.Left() = pSplitItem->mnLeft;
+ maDragRect.Top() = pSplitItem->mnTop;
+ maDragRect.Right() = pSplitItem->mnLeft+pSplitItem->mnWidth-1;
+ maDragRect.Bottom() = pSplitItem->mnTop+pSplitItem->mnHeight-1;
+
+ if ( mnSplitTest & SPLIT_HORZ )
+ {
+ if ( bDown )
+ maDragRect.Right() += mpSplitSet->mnSplitSize;
+ else
+ maDragRect.Left() -= mpSplitSet->mnSplitSize;
+ }
+ else
+ {
+ if ( bDown )
+ maDragRect.Bottom() += mpSplitSet->mnSplitSize;
+ else
+ maDragRect.Top() -= mpSplitSet->mnSplitSize;
+ }
+
+ if ( mnSplitPos )
+ {
+ nTemp = mnSplitPos;
+ while ( nTemp )
+ {
+ pSplitItem = &(mpSplitSet->mpItems[nTemp-1]);
+ if ( pSplitItem->mbFixed )
+ break;
+ else
+ {
+ if ( mnSplitTest & SPLIT_HORZ )
+ {
+ if ( bDown )
+ maDragRect.Left() -= pSplitItem->mnPixSize;
+ else
+ maDragRect.Right() += pSplitItem->mnPixSize;
+ }
+ else
+ {
+ if ( bDown )
+ maDragRect.Top() -= pSplitItem->mnPixSize;
+ else
+ maDragRect.Bottom() += pSplitItem->mnPixSize;
+ }
+ }
+ nTemp--;
+ }
+ }
+
+ if ( (mpSplitSet == mpMainSet) && (mnWinStyle & WB_SIZEABLE) && !bPropSmaller )
+ {
+ if ( bDown )
+ {
+ if ( mbHorz )
+ maDragRect.Bottom() += nCurMaxSize-mnDY-mnTopBorder;
+ else
+ maDragRect.Right() += nCurMaxSize-mnDX-mnLeftBorder;
+ }
+ else
+ {
+ if ( mbHorz )
+ maDragRect.Top() -= nCurMaxSize-mnDY-mnBottomBorder;
+ else
+ maDragRect.Left() -= nCurMaxSize-mnDX-mnRightBorder;
+ }
+ }
+ else
+ {
+ nTemp = mnSplitPos+1;
+ while ( nTemp < mpSplitSet->mnItems )
+ {
+ pSplitItem = &(mpSplitSet->mpItems[nTemp]);
+ if ( pSplitItem->mbFixed )
+ break;
+ else
+ {
+ if ( mnSplitTest & SPLIT_HORZ )
+ {
+ if ( bDown )
+ maDragRect.Right() += pSplitItem->mnPixSize;
+ else
+ maDragRect.Left() -= pSplitItem->mnPixSize;
+ }
+ else
+ {
+ if ( bDown )
+ maDragRect.Bottom() += pSplitItem->mnPixSize;
+ else
+ maDragRect.Top() -= pSplitItem->mnPixSize;
+ }
+ }
+ nTemp++;
+ }
+ }
+ }
+ else
+ {
+ maDragRect.Left() = mnLeftBorder;
+ maDragRect.Top() = mnTopBorder;
+ maDragRect.Right() = mnDX-mnRightBorder-1;
+ maDragRect.Bottom() = mnDY-mnBottomBorder-1;
+ if ( mbHorz )
+ {
+ if ( mbBottomRight )
+ maDragRect.Top() -= nCurMaxSize-mnDY-mnBottomBorder;
+ else
+ maDragRect.Bottom() += nCurMaxSize-mnDY-mnTopBorder;
+ }
+ else
+ {
+ if ( mbBottomRight )
+ maDragRect.Left() -= nCurMaxSize-mnDX-mnRightBorder;
+ else
+ maDragRect.Right() += nCurMaxSize-mnDX-mnLeftBorder;
+ }
+ }
+
+ StartTracking();
+
+ mbDragFull = (GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SPLIT) != 0;
+ ImplSplitMousePos( aMousePosPixel );
+ if ( !mbDragFull )
+ ImplDrawSplitTracking( this, aMousePosPixel );
+ else
+ {
+ ImplSplitItem* pItems = mpSplitSet->mpItems;
+ USHORT nItems = mpSplitSet->mnItems;
+ mpLastSizes = new long[nItems*2];
+ for ( USHORT i = 0; i < nItems; i++ )
+ {
+ mpLastSizes[i*2] = pItems[i].mnSize;
+ mpLastSizes[i*2+1] = pItems[i].mnPixSize;
+ }
+ }
+ mnMStartPos = mnMSplitPos;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( !IsTracking() )
+ {
+ Point aPos = rMEvt.GetPosPixel();
+ long nTemp;
+ ImplSplitSet* pTempSplitSet;
+ USHORT nTempSplitPos;
+ USHORT nSplitTest = ImplTestSplit( this, aPos, nTemp, &pTempSplitSet, nTempSplitPos );
+ PointerStyle eStyle = POINTER_ARROW;
+ Rectangle aAutoHideRect;
+ Rectangle aFadeInRect;
+ Rectangle aFadeOutRect;
+
+ ImplGetAutoHideRect( aAutoHideRect );
+ ImplGetFadeInRect( aFadeInRect );
+ ImplGetFadeOutRect( aFadeOutRect );
+ if ( !aAutoHideRect.IsInside( aPos ) &&
+ !aFadeInRect.IsInside( aPos ) &&
+ !aFadeOutRect.IsInside( aPos ) )
+ {
+ if ( nSplitTest && !(nSplitTest & SPLIT_NOSPLIT) )
+ {
+ if ( nSplitTest & SPLIT_HORZ )
+ eStyle = POINTER_HSPLIT;
+ else if ( nSplitTest & SPLIT_VERT )
+ eStyle = POINTER_VSPLIT;
+ }
+ }
+
+ Pointer aPtr( eStyle );
+ SetPointer( aPtr );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::Tracking( const TrackingEvent& rTEvt )
+{
+ Point aMousePosPixel = rTEvt.GetMouseEvent().GetPosPixel();
+
+ if ( mbAutoHideDown )
+ {
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ mbAutoHideDown = FALSE;
+ if ( mbAutoHidePressed )
+ {
+ mbAutoHidePressed = FALSE;
+
+ if ( !rTEvt.IsTrackingCanceled() )
+ {
+ mbAutoHideIn = !mbAutoHideIn;
+ ImplDrawAutoHide( FALSE );
+ AutoHide();
+ }
+ else
+ ImplDrawAutoHide( FALSE );
+ }
+ }
+ else
+ {
+ Rectangle aTestRect;
+ ImplGetAutoHideRect( aTestRect, TRUE );
+ BOOL bNewPressed = aTestRect.IsInside( aMousePosPixel );
+ if ( bNewPressed != mbAutoHidePressed )
+ {
+ mbAutoHidePressed = bNewPressed;
+ ImplDrawAutoHide( FALSE );
+ }
+ }
+ }
+ else if ( mbFadeInDown )
+ {
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ mbFadeInDown = FALSE;
+ if ( mbFadeInPressed )
+ {
+ mbFadeInPressed = FALSE;
+ ImplDrawFadeIn( FALSE );
+
+ if ( !rTEvt.IsTrackingCanceled() )
+ FadeIn();
+ }
+ }
+ else
+ {
+ Rectangle aTestRect;
+ ImplGetFadeInRect( aTestRect, TRUE );
+ BOOL bNewPressed = aTestRect.IsInside( aMousePosPixel );
+ if ( bNewPressed != mbFadeInPressed )
+ {
+ mbFadeInPressed = bNewPressed;
+ ImplDrawFadeIn( FALSE );
+ }
+ }
+ }
+ else if ( mbFadeOutDown )
+ {
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ mbFadeOutDown = FALSE;
+ if ( mbFadeOutPressed )
+ {
+ mbFadeOutPressed = FALSE;
+ ImplDrawFadeOut( FALSE );
+
+ if ( !rTEvt.IsTrackingCanceled() )
+ FadeOut();
+ }
+ }
+ else
+ {
+ Rectangle aTestRect;
+ ImplGetFadeOutRect( aTestRect, TRUE );
+ BOOL bNewPressed = aTestRect.IsInside( aMousePosPixel );
+ if ( bNewPressed != mbFadeOutPressed )
+ {
+ mbFadeOutPressed = bNewPressed;
+ ImplDrawFadeOut( FALSE );
+ }
+ }
+ }
+ else
+ {
+ ImplSplitMousePos( aMousePosPixel );
+ BOOL bSplit = TRUE;
+ if ( mbDragFull )
+ {
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( rTEvt.IsTrackingCanceled() )
+ {
+ ImplSplitItem* pItems = mpSplitSet->mpItems;
+ USHORT nItems = mpSplitSet->mnItems;
+ for ( USHORT i = 0; i < nItems; i++ )
+ {
+ pItems[i].mnSize = mpLastSizes[i*2];
+ pItems[i].mnPixSize = mpLastSizes[i*2+1];
+ }
+ ImplUpdate();
+ Split();
+ }
+ bSplit = FALSE;
+ }
+ }
+ else
+ {
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ HideTracking();
+ bSplit = !rTEvt.IsTrackingCanceled();
+ }
+ else
+ {
+ ImplDrawSplitTracking( this, aMousePosPixel );
+ bSplit = FALSE;
+ }
+ }
+
+ if ( bSplit )
+ {
+ BOOL bPropSmaller = (mnMouseModifier & KEY_SHIFT) ? TRUE : FALSE;
+ BOOL bPropGreater = (mnMouseModifier & KEY_MOD1) ? TRUE : FALSE;
+ long nDelta = mnMSplitPos-mnMStartPos;
+
+ if ( (mnSplitTest & SPLIT_WINDOW) && !mpMainSet->mpItems )
+ {
+ if ( (mpSplitSet == mpMainSet) && mbBottomRight )
+ nDelta *= -1;
+ ImplSetWindowSize( nDelta );
+ }
+ else
+ {
+ long nNewSize = mpSplitSet->mpItems[mnSplitPos].mnPixSize;
+ if ( (mpSplitSet == mpMainSet) && mbBottomRight )
+ nNewSize -= nDelta;
+ else
+ nNewSize += nDelta;
+ SplitItem( mpSplitSet->mpItems[mnSplitPos].mnId, nNewSize,
+ bPropSmaller, bPropGreater );
+ }
+
+ Split();
+
+ if ( mbDragFull )
+ {
+ Update();
+ mnMStartPos = mnMSplitPos;
+ }
+ }
+
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( mpLastSizes )
+ delete mpLastSizes;
+ mpLastSizes = NULL;
+ mpSplitSet = NULL;
+ mnMouseOff = 0;
+ mnMStartPos = 0;
+ mnMSplitPos = 0;
+ mnMouseModifier = 0;
+ mnSplitTest = 0;
+ mnSplitPos = 0;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::Paint( const Rectangle& )
+{
+ if ( mnWinStyle & WB_BORDER )
+ ImplDrawBorder( this );
+
+ ImplDrawFadeOut( TRUE );
+ ImplDrawFadeIn( TRUE );
+ ImplDrawAutoHide( TRUE );
+
+ // FrameSet-Hintergruende zeichnen
+ ImplDrawBack( this, mpMainSet );
+
+ // Splitter zeichnen
+ if ( !(mnWinStyle & WB_NOSPLITDRAW) )
+ ImplDrawSplit( this, mpMainSet, mbHorz, !mbBottomRight );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::Move()
+{
+ DockingWindow::Move();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::Resize()
+{
+ Size aSize = GetOutputSizePixel();
+ mnDX = aSize.Width();
+ mnDY = aSize.Height();
+
+ ImplUpdate();
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
+ {
+ Point aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
+ Rectangle aHelpRect;
+ USHORT nHelpResId = 0;
+
+ ImplGetAutoHideRect( aHelpRect, TRUE );
+ if ( aHelpRect.IsInside( aMousePosPixel ) )
+ {
+ if ( mbAutoHideIn )
+ nHelpResId = SV_HELPTEXT_SPLITFIXED;
+ else
+ nHelpResId = SV_HELPTEXT_SPLITFLOATING;
+ }
+ else
+ {
+ ImplGetFadeInRect( aHelpRect, TRUE );
+ if ( aHelpRect.IsInside( aMousePosPixel ) )
+ nHelpResId = SV_HELPTEXT_FADEIN;
+ else
+ {
+ ImplGetFadeOutRect( aHelpRect, TRUE );
+ if ( aHelpRect.IsInside( aMousePosPixel ) )
+ nHelpResId = SV_HELPTEXT_FADEOUT;
+ }
+ }
+
+ // Rechteck ermitteln
+ if ( nHelpResId )
+ {
+ Point aPt = OutputToScreenPixel( aHelpRect.TopLeft() );
+ aHelpRect.Left() = aPt.X();
+ aHelpRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aHelpRect.BottomRight() );
+ aHelpRect.Right() = aPt.X();
+ aHelpRect.Bottom() = aPt.Y();
+
+ // Text ermitteln und anzeigen
+ XubString aStr( ResId( nHelpResId, ImplGetResMgr() ) );
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aStr );
+ else
+ Help::ShowQuickHelp( this, aHelpRect, aStr );
+ return;
+ }
+ }
+
+ DockingWindow::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if ( IsUpdateMode() )
+ ImplCalcLayout();
+ }
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsUpdateMode() && IsReallyShown() )
+ ImplCalcLayout();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+
+ DockingWindow::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+ else
+ DockingWindow::DataChanged( rDCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::InsertItem( USHORT nId, Window* pWindow, long nSize,
+ USHORT nPos, USHORT nSetId,
+ SplitWindowItemBits nBits )
+{
+#ifdef DBG_UTIL
+ USHORT nDbgDummy;
+ DBG_ASSERT( ImplFindSet( mpMainSet, nSetId ), "SplitWindow::InsertItem() - Set not exists" );
+ DBG_ASSERT( !ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::InsertItem() - Id already exists" );
+#endif
+
+ // Size muss min. 1 sein
+ if ( nSize < 1 )
+ nSize = 1;
+
+ ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
+ ImplSplitSet* pNewSet;
+ ImplSplitItem* pItem;
+
+ // Platz fuer neues Item schaffen
+ if ( nPos > pSet->mnItems )
+ nPos = pSet->mnItems;
+ ImplSplitItem* pNewItems = new ImplSplitItem[pSet->mnItems+1];
+ if ( nPos )
+ memcpy( pNewItems, pSet->mpItems, sizeof( ImplSplitItem )*nPos );
+ if ( nPos < pSet->mnItems )
+ memcpy( pNewItems+nPos+1, pSet->mpItems+nPos, sizeof( ImplSplitItem )*(pSet->mnItems-nPos) );
+ delete pSet->mpItems;
+ pSet->mpItems = pNewItems;
+ pSet->mnItems++;
+ pSet->mbCalcPix = TRUE;
+
+ // Item anlegen und erweitern
+ pItem = &(pSet->mpItems[nPos]);
+ memset( pItem, 0, sizeof( ImplSplitItem ) );
+ pItem->mnSize = nSize;
+ pItem->mnId = nId;
+ pItem->mnBits = nBits;
+
+ if ( pWindow )
+ {
+ pItem->mpWindow = pWindow;
+ pItem->mpOrgParent = pWindow->GetParent();
+
+ // Window mit SplitWindow verbinden
+ pWindow->Hide();
+ pWindow->SetParent( this );
+ }
+ else
+ {
+ pNewSet = new ImplSplitSet;
+ pNewSet->mpItems = NULL;
+ pNewSet->mpWallpaper = NULL;
+ pNewSet->mpBitmap = NULL;
+ pNewSet->mnLastSize = 0;
+ pNewSet->mnItems = 0;
+ pNewSet->mnId = nId;
+ pNewSet->mnSplitSize = pSet->mnSplitSize;
+ pNewSet->mbCalcPix = TRUE;
+
+ pItem->mpSet = pNewSet;
+ }
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::InsertItem( USHORT nId, long nSize,
+ USHORT nPos, USHORT nSetId,
+ SplitWindowItemBits nBits )
+{
+ InsertItem( nId, NULL, nSize, nPos, nSetId, nBits );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::MoveItem( USHORT nId, USHORT nNewPos, USHORT nNewSetId )
+{
+#ifdef DBG_UTIL
+ USHORT nDbgDummy;
+ DBG_ASSERT( ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::MoveItem() - Id not found" );
+ DBG_ASSERT( ImplFindSet( mpMainSet, nNewSetId ), "SplitWindow::MoveItem() - Set not exists" );
+#endif
+
+ USHORT nPos;
+ ImplSplitSet* pNewSet = ImplFindSet( mpMainSet, nNewSetId );
+ ImplSplitSet* pSet = ImplFindItem( mpMainSet, nId, nPos );
+ ImplSplitItem aTempItem;
+
+ if ( pNewSet == pSet )
+ {
+ if ( nNewPos >= pNewSet->mnItems )
+ nNewPos = pNewSet->mnItems-1;
+ if ( nPos != nNewPos )
+ {
+ memcpy( &aTempItem, &(pSet->mpItems[nPos]), sizeof( aTempItem ) );
+ if ( nPos < nNewPos )
+ {
+ memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
+ (nNewPos-nPos)*sizeof( ImplSplitItem ) );
+ }
+ else
+ {
+ memmove( pSet->mpItems+nNewPos+1, pSet->mpItems+nNewPos,
+ (nPos-nNewPos)*sizeof( ImplSplitItem ) );
+ }
+ memcpy( &(pSet->mpItems[nNewPos]), &aTempItem, sizeof( aTempItem ) );
+
+ ImplUpdate();
+ }
+ }
+ else
+ {
+ if ( nNewPos >= pNewSet->mnItems )
+ nNewPos = pNewSet->mnItems;
+ memcpy( &aTempItem, &(pSet->mpItems[nPos]), sizeof( aTempItem ) );
+ pSet->mnItems--;
+ pSet->mbCalcPix = TRUE;
+ if ( pSet->mnItems )
+ {
+ memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
+ (pSet->mnItems-nPos)*sizeof( ImplSplitItem ) );
+ }
+ else
+ {
+ delete pSet->mpItems;
+ pSet->mpItems = NULL;
+ }
+ ImplSplitItem* pNewItems = new ImplSplitItem[pNewSet->mnItems+1];
+ if ( nNewPos )
+ memcpy( pNewItems, pNewSet->mpItems, sizeof( ImplSplitItem )*nNewPos );
+ if ( nNewPos < pNewSet->mnItems )
+ {
+ memcpy( pNewItems+nNewPos+1, pNewSet->mpItems+nNewPos,
+ sizeof( ImplSplitItem )*(pNewSet->mnItems-nNewPos) );
+ }
+ delete pNewSet->mpItems;
+ pNewSet->mpItems = pNewItems;
+ pNewSet->mnItems++;
+ pNewSet->mbCalcPix = TRUE;
+ memcpy( &(pNewSet->mpItems[nNewPos]), &aTempItem, sizeof( aTempItem ) );
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::RemoveItem( USHORT nId, BOOL bHide )
+{
+#ifdef DBG_UTIL
+ USHORT nDbgDummy;
+ DBG_ASSERT( ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::RemoveItem() - Id not found" );
+#endif
+
+ // Set suchen
+ USHORT nPos;
+ ImplSplitSet* pSet = ImplFindItem( mpMainSet, nId, nPos );
+ ImplSplitItem* pItem = &(pSet->mpItems[nPos]);
+ Window* pWindow = pItem->mpWindow;
+ Window* pOrgParent = pItem->mpOrgParent;
+
+ // Evt. Set loeschen
+ if ( !pWindow )
+ ImplDeleteSet( pItem->mpSet );
+
+ // Item entfernen
+ pSet->mnItems--;
+ pSet->mbCalcPix = TRUE;
+ if ( pSet->mnItems )
+ {
+ memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
+ (pSet->mnItems-nPos)*sizeof( ImplSplitItem ) );
+ }
+ else
+ {
+ delete pSet->mpItems;
+ pSet->mpItems = NULL;
+ }
+
+ ImplUpdate();
+
+ // Window erst hier loeschen, um weniger Paints zu haben
+ if ( pWindow )
+ {
+ // Fenster wieder herstellen
+ if ( bHide || (pOrgParent != this) )
+ {
+ pWindow->Hide();
+ pWindow->SetParent( pOrgParent );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::Clear()
+{
+ // Alle Sets loeschen
+ ImplDeleteSet( mpMainSet );
+
+ // Main-Set wieder anlegen
+ mpMainSet = new ImplSplitSet;
+ mpMainSet->mpItems = NULL;
+ mpMainSet->mpWallpaper = NULL;
+ mpMainSet->mpBitmap = NULL;
+ mpMainSet->mnLastSize = 0;
+ mpMainSet->mnItems = 0;
+ mpMainSet->mnId = 0;
+ mpMainSet->mnSplitSize = SPLITWIN_SPLITSIZE;
+ mpMainSet->mbCalcPix = TRUE;
+ if ( mnWinStyle & WB_NOSPLITDRAW )
+ mpMainSet->mnSplitSize -= 2;
+ mpBaseSet = mpMainSet;
+
+ // Und neu invalidieren
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetBaseSet( USHORT nSetId )
+{
+ mpBaseSet = ImplFindSet( mpMainSet, nSetId );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SplitWindow::GetBaseSet() const
+{
+ return mpBaseSet->mnId;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetSplitSize( USHORT nSetId, long nSplitSize,
+ BOOL bWithChilds )
+{
+ ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
+ if ( pSet )
+ {
+ if ( bWithChilds )
+ ImplSetSplitSize( pSet, nSplitSize );
+ else
+ pSet->mnSplitSize = nSplitSize;
+ }
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+long SplitWindow::GetSplitSize( USHORT nSetId ) const
+{
+ ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
+ if ( pSet )
+ return pSet->mnSplitSize;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetItemBackground( USHORT nSetId )
+{
+ Wallpaper aWall;
+ SetItemBackground( nSetId, aWall );
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetItemBackground( USHORT nSetId, const Wallpaper& rWallpaper )
+{
+ ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
+
+ if ( pSet )
+ {
+ BOOL bUpdate = TRUE;
+
+ if ( rWallpaper.GetStyle() == WALLPAPER_NULL )
+ {
+ if ( pSet->mpWallpaper )
+ {
+ delete pSet->mpWallpaper;
+ pSet->mpWallpaper = NULL;
+ }
+ else
+ bUpdate = FALSE;
+ }
+ else
+ {
+ // Ab jetzt muss immer invalidiert werden
+ mbInvalidate = TRUE;
+
+ if ( !pSet->mpWallpaper )
+ pSet->mpWallpaper = new Wallpaper( rWallpaper );
+ else
+ *(pSet->mpWallpaper) = rWallpaper;
+ }
+
+ // Beim MainSet koennen wir den Background umsetzen
+ if ( pSet == mpMainSet )
+ ImplInitSettings();
+
+ if ( bUpdate )
+ ImplUpdateSet( pSet );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Wallpaper SplitWindow::GetItemBackground( USHORT nSetId ) const
+{
+ ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
+
+ if ( pSet && pSet->mpWallpaper )
+ return *(pSet->mpWallpaper);
+ else
+ {
+ Wallpaper aWall;
+ return aWall;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SplitWindow::IsItemBackground( USHORT nSetId ) const
+{
+ ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
+
+ if ( pSet && pSet->mpWallpaper )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetItemBitmap( USHORT nSetId, const Bitmap& rBitmap )
+{
+ ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
+
+ if ( pSet )
+ {
+ BOOL bUpdate = TRUE;
+
+ if ( !rBitmap )
+ {
+ if ( pSet->mpBitmap )
+ {
+ delete pSet->mpBitmap;
+ pSet->mpBitmap = NULL;
+ }
+ else
+ bUpdate = FALSE;
+ }
+ else
+ {
+ // Ab jetzt muss immer invalidiert werden
+ mbInvalidate = TRUE;
+
+ if ( !pSet->mpBitmap )
+ pSet->mpBitmap = new Bitmap( rBitmap );
+ else
+ *(pSet->mpBitmap) = rBitmap;
+ }
+
+ // Beim MainSet koennen wir den Background umsetzen
+ if ( pSet == mpMainSet )
+ ImplInitSettings();
+
+ if ( bUpdate )
+ ImplUpdateSet( pSet );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Bitmap SplitWindow::GetItemBitmap( USHORT nSetId ) const
+{
+ ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
+
+ if ( pSet && pSet->mpBitmap )
+ return *(pSet->mpBitmap);
+ else
+ {
+ Bitmap aBitmap;
+ return aBitmap;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SplitItem( USHORT nId, long nNewSize,
+ BOOL bPropSmall, BOOL bPropGreat )
+{
+ USHORT nItems;
+ USHORT nPos;
+ USHORT nMin;
+ USHORT nMax;
+ USHORT i;
+ USHORT n;
+ long nDelta;
+ long nTempDelta;
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
+ ImplSplitItem* pItems;
+
+ if ( !pSet )
+ return;
+
+ nItems = pSet->mnItems;
+ pItems = pSet->mpItems;
+
+ if ( mbCalc )
+ {
+ pItems[nPos].mnSize = nNewSize;
+ return;
+ }
+
+ nDelta = nNewSize-pItems[nPos].mnPixSize;
+ if ( !nDelta )
+ return;
+
+ // Bereich berechnen, der beim Splitten betroffen sein kann
+ nMin = 0;
+ nMax = nItems;
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( pItems[i].mbFixed )
+ {
+ if ( i < nPos )
+ nMin = i+1;
+ else
+ nMax = i;
+ }
+ }
+
+ // Wenn das Fenster sizeable ist, wird das TopSet anders behandelt
+ BOOL bSmall = TRUE;
+ BOOL bGreat = TRUE;
+ if ( (pSet == mpMainSet) && (mnWinStyle & WB_SIZEABLE) )
+ {
+ if ( nPos < pSet->mnItems-1 )
+ {
+ if ( !((bPropSmall && bPropGreat) ||
+ ((nDelta > 0) && bPropSmall) ||
+ ((nDelta < 0) && bPropGreat)) )
+ {
+ if ( nDelta < 0 )
+ bGreat = FALSE;
+ else
+ bSmall = FALSE;
+ }
+ }
+ else
+ {
+ if ( nDelta < 0 )
+ bGreat = FALSE;
+ else
+ bSmall = FALSE;
+ }
+ }
+ else if ( nPos >= nMax )
+ {
+ bSmall = FALSE;
+ bGreat = FALSE;
+ }
+ else if ( nPos && (nPos >= pSet->mnItems-1) )
+ {
+ nPos--;
+ nDelta *= -1;
+ BOOL bTemp = bPropSmall;
+ bPropSmall = bPropGreat;
+ bPropGreat = bTemp;
+ }
+
+ // Jetzt die Fenster splitten
+ if ( nDelta < 0 )
+ {
+ if ( bGreat )
+ {
+ if ( bPropGreat )
+ {
+ nTempDelta = nDelta;
+ do
+ {
+ n = nPos+1;
+ do
+ {
+ if ( nTempDelta )
+ {
+ pItems[n].mnPixSize++;
+ nTempDelta++;
+ }
+ n++;
+ }
+ while ( n < nMax );
+ }
+ while ( nTempDelta );
+ }
+ else
+ pItems[nPos+1].mnPixSize -= nDelta;
+ }
+
+ if ( bSmall )
+ {
+ if ( bPropSmall )
+ {
+ do
+ {
+ n = nPos+1;
+ do
+ {
+ if ( nDelta && pItems[n-1].mnPixSize )
+ {
+ pItems[n-1].mnPixSize--;
+ nDelta++;
+ }
+
+ n--;
+ }
+ while ( n > nMin );
+ }
+ while ( nDelta );
+ }
+ else
+ {
+ n = nPos+1;
+ do
+ {
+ if ( pItems[n-1].mnPixSize+nDelta < 0 )
+ {
+ nDelta += pItems[n-1].mnPixSize;
+ pItems[n-1].mnPixSize = 0;
+ }
+ else
+ {
+ pItems[n-1].mnPixSize += nDelta;
+ break;
+ }
+ n--;
+ }
+ while ( n > nMin );
+ }
+ }
+ }
+ else
+ {
+ if ( bGreat )
+ {
+ if ( bPropGreat )
+ {
+ nTempDelta = nDelta;
+ do
+ {
+ n = nPos+1;
+ do
+ {
+ if ( nTempDelta )
+ {
+ pItems[n-1].mnPixSize++;
+ nTempDelta--;
+ }
+ n--;
+ }
+ while ( n > nMin );
+ }
+ while ( nTempDelta );
+ }
+ else
+ pItems[nPos].mnPixSize += nDelta;
+ }
+
+ if ( bSmall )
+ {
+ if ( bPropSmall )
+ {
+ do
+ {
+ n = nPos+1;
+ do
+ {
+ if ( nDelta && pItems[n].mnPixSize )
+ {
+ pItems[n].mnPixSize--;
+ nDelta--;
+ }
+
+ n++;
+ }
+ while ( n < nMax );
+ }
+ while ( nDelta );
+ }
+ else
+ {
+ n = nPos+1;
+ do
+ {
+ if ( pItems[n].mnPixSize-nDelta < 0 )
+ {
+ nDelta -= pItems[n].mnPixSize;
+ pItems[n].mnPixSize = 0;
+ }
+ else
+ {
+ pItems[n].mnPixSize -= nDelta;
+ break;
+ }
+ n++;
+ }
+ while ( n < nMax );
+ }
+ }
+ }
+
+ // Original-Groessen updaten
+ ImplCalcLogSize( pItems, nItems );
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetItemSize( USHORT nId, long nNewSize )
+{
+ USHORT nPos;
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
+ ImplSplitItem* pItem;
+
+ if ( !pSet )
+ return;
+
+ // Testen, ob sich Groesse aendert
+ pItem = &(pSet->mpItems[nPos]);
+ if ( pItem->mnSize != nNewSize )
+ {
+ // Neue Groesse setzen und neu durchrechnen
+ pItem->mnSize = nNewSize;
+ pSet->mbCalcPix = TRUE;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long SplitWindow::GetItemSize( USHORT nId ) const
+{
+ USHORT nPos;
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
+
+ if ( pSet )
+ return pSet->mpItems[nPos].mnSize;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long SplitWindow::GetItemSize( USHORT nId, SplitWindowItemBits nBits ) const
+{
+ USHORT nPos;
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
+
+ if ( pSet )
+ {
+ if ( nBits == pSet->mpItems[nPos].mnBits )
+ return pSet->mpItems[nPos].mnSize;
+ else
+ {
+ ((SplitWindow*)this)->ImplCalcLayout();
+
+ long nRelSize = 0;
+ long nPerSize = 0;
+ ImplSplitItem* pItems;
+ USHORT nItems;
+ SplitWindowItemBits nTempBits;
+ USHORT i;
+ nItems = pSet->mnItems;
+ pItems = pSet->mpItems;
+ for ( i = 0; i < nItems; i++ )
+ {
+ if ( i == nPos )
+ nTempBits = nBits;
+ else
+ nTempBits = pItems[i].mnBits;
+ if ( nTempBits & SWIB_RELATIVESIZE )
+ nRelSize += pItems[i].mnPixSize;
+ else if ( nTempBits & SWIB_PERCENTSIZE )
+ nPerSize += pItems[i].mnPixSize;
+ }
+ nPerSize += nRelSize;
+ if ( nBits & SWIB_RELATIVESIZE )
+ {
+ if ( nRelSize )
+ return (pItems[nPos].mnPixSize+(nRelSize/2))/nRelSize;
+ else
+ return 1;
+ }
+ else if ( nBits & SWIB_PERCENTSIZE )
+ {
+ if ( nPerSize )
+ return (pItems[nPos].mnPixSize*100)/nPerSize;
+ else
+ return 1;
+ }
+ else
+ return pItems[nPos].mnPixSize;
+ }
+ }
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetItemBits( USHORT nId, SplitWindowItemBits nNewBits )
+{
+ USHORT nPos;
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
+ ImplSplitItem* pItem;
+
+ if ( !pSet )
+ return;
+
+ pItem = &(pSet->mpItems[nPos]);
+ if ( pItem->mpWindow )
+ nNewBits &= ~SWIB_COLSET;
+
+ if ( pItem->mnBits != nNewBits )
+ {
+ // Neue Bits setzen und neu durchrechnen
+ pItem->mnBits = nNewBits;
+ pSet->mbCalcPix = TRUE;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SplitWindowItemBits SplitWindow::GetItemBits( USHORT nId ) const
+{
+ USHORT nPos;
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
+
+ if ( pSet )
+ return pSet->mpItems[nPos].mnBits;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Window* SplitWindow::GetItemWindow( USHORT nId ) const
+{
+ USHORT nPos;
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
+
+ if ( pSet )
+ return pSet->mpItems[nPos].mpWindow;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SplitWindow::GetSet( USHORT nId ) const
+{
+ USHORT nPos;
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
+
+ if ( pSet )
+ return pSet->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SplitWindow::GetSet( USHORT nId, USHORT& rSetId, USHORT& rPos ) const
+{
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, rPos );
+ if ( pSet )
+ {
+ rSetId = pSet->mnId;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SplitWindow::IsItemValid( USHORT nId ) const
+{
+ USHORT nPos;
+ ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
+
+ if ( pSet )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SplitWindow::GetItemId( Window* pWindow ) const
+{
+ return ImplFindItem( mpBaseSet, pWindow );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SplitWindow::GetItemId( const Point& rPos ) const
+{
+ return ImplFindItem( mpBaseSet, rPos, mbHorz, !mbBottomRight );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SplitWindow::GetItemPos( USHORT nId, USHORT nSetId ) const
+{
+ ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
+ USHORT nPos = SPLITWINDOW_ITEM_NOTFOUND;
+
+ if ( pSet )
+ {
+ for ( USHORT i = 0; i < pSet->mnItems; i++ )
+ {
+ if ( pSet->mpItems[i].mnId == nId )
+ {
+ nPos = i;
+ break;
+ }
+ }
+ }
+
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SplitWindow::GetItemId( USHORT nPos, USHORT nSetId ) const
+{
+ ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
+ if ( pSet && (nPos < pSet->mnItems) )
+ return pSet->mpItems[nPos].mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SplitWindow::GetItemCount( USHORT nSetId ) const
+{
+ ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
+ if ( pSet )
+ return pSet->mnItems;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ImplNewAlign()
+{
+ if ( mbNoAlign )
+ {
+ mbHorz = FALSE;
+ mbBottomRight = FALSE;
+ }
+ else if ( meAlign == WINDOWALIGN_TOP )
+ {
+ mbHorz = TRUE;
+ mbBottomRight = FALSE;
+ }
+ else if ( meAlign == WINDOWALIGN_BOTTOM )
+ {
+ mbHorz = TRUE;
+ mbBottomRight = TRUE;
+ }
+ else if ( meAlign == WINDOWALIGN_LEFT )
+ {
+ mbHorz = FALSE;
+ mbBottomRight = FALSE;
+ }
+ else if ( meAlign == WINDOWALIGN_RIGHT )
+ {
+ mbHorz = FALSE;
+ mbBottomRight = TRUE;
+ }
+
+ if ( mnWinStyle & WB_BORDER )
+ {
+ ImplCalcBorder( meAlign, mbNoAlign, mnLeftBorder, mnTopBorder,
+ mnRightBorder, mnBottomBorder );
+ }
+
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetNoAlign( BOOL bNoAlign )
+{
+ bNoAlign = bNoAlign != 0;
+ if ( mbNoAlign != bNoAlign )
+ {
+ mbNoAlign = bNoAlign;
+ ImplNewAlign();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetAlign( WindowAlign eNewAlign )
+{
+ if ( meAlign != eNewAlign )
+ {
+ meAlign = eNewAlign;
+ ImplNewAlign();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size SplitWindow::CalcWindowSizePixel( const Size& rSize, WindowAlign eAlign,
+ WinBits nWinStyle, BOOL bExtra )
+{
+ long nLeft;
+ long nTop;
+ long nRight;
+ long nBottom;
+ Size aSize = rSize;
+
+ ImplCalcBorder( eAlign, FALSE, nLeft, nTop, nRight, nBottom );
+ aSize.Width() += nLeft+nRight;
+ aSize.Height() += nTop+nBottom;
+
+ if ( nWinStyle & WB_SIZEABLE )
+ {
+ if ( (eAlign == WINDOWALIGN_TOP) || (eAlign == WINDOWALIGN_BOTTOM) )
+ {
+ aSize.Height() += SPLITWIN_SPLITSIZE-2;
+ if ( bExtra )
+ aSize.Height() += SPLITWIN_SPLITSIZEEX;
+ }
+ else
+ {
+ aSize.Width() += SPLITWIN_SPLITSIZE-2;
+ if ( bExtra )
+ aSize.Width() += SPLITWIN_SPLITSIZEEX;
+ }
+ }
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ShowAutoHideButton( BOOL bShow )
+{
+ mbAutoHide = bShow;
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ShowFadeInHideButton( BOOL bShow )
+{
+ mbFadeIn = bShow;
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::ShowFadeOutButton( BOOL bShow )
+{
+ mbFadeOut = bShow;
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void SplitWindow::SetAutoHideState( BOOL bAutoHide )
+{
+ mbAutoHideIn = bAutoHide;
+ if ( IsReallyVisible() )
+ {
+ Rectangle aRect;
+ ImplGetAutoHideRect( aRect );
+ Invalidate( aRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long SplitWindow::GetFadeInSize() const
+{
+ long n = 0;
+
+ if ( mbHorz )
+ n = mnTopBorder+mnBottomBorder;
+ else
+ n = mnLeftBorder+mnRightBorder;
+
+ return n+SPLITWIN_SPLITSIZE+SPLITWIN_SPLITSIZEEX-2;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle SplitWindow::GetAutoHideRect() const
+{
+ Rectangle aRect;
+ ImplGetAutoHideRect( aRect, TRUE );
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle SplitWindow::GetFadeInRect() const
+{
+ Rectangle aRect;
+ ImplGetFadeInRect( aRect, TRUE );
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle SplitWindow::GetFadeOutRect() const
+{
+ Rectangle aRect;
+ ImplGetFadeOutRect( aRect, TRUE );
+ return aRect;
+}
diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx
new file mode 100644
index 000000000000..e96593eb6cfd
--- /dev/null
+++ b/vcl/source/window/status.cxx
@@ -0,0 +1,1411 @@
+/*************************************************************************
+ *
+ * $RCSfile: status.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_STATUS_CXX
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_STATUS_HXX
+#include <status.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define STATUSBAR_OFFSET_X STATUSBAR_OFFSET
+#define STATUSBAR_OFFSET_Y 2
+#define STATUSBAR_OFFSET_TEXTY 3
+
+#define STATUSBAR_PRGS_OFFSET 3
+#define STATUSBAR_PRGS_COUNT 100
+#define STATUSBAR_PRGS_MIN 5
+
+// -----------------------------------------------------------------------
+
+struct ImplStatusItem
+{
+ USHORT mnId;
+ StatusBarItemBits mnBits;
+ long mnWidth;
+ long mnOffset;
+ long mnExtraWidth;
+ long mnX;
+ XubString maText;
+ XubString maHelpText;
+ ULONG mnHelpId;
+ void* mpUserData;
+ BOOL mbVisible;
+};
+
+DECLARE_LIST( ImplStatusItemList, ImplStatusItem* );
+
+// =======================================================================
+
+inline long ImplCalcProgessWidth( USHORT nMax, long nSize )
+{
+ return ((nMax*(nSize+(nSize/2)))-(nSize/2)+(STATUSBAR_PRGS_OFFSET*2));
+}
+
+// -----------------------------------------------------------------------
+
+static Point ImplGetItemTextPos( const Size& rRectSize, const Size& rTextSize,
+ USHORT nStyle )
+{
+ long nX;
+ long nY;
+
+ if ( nStyle & SIB_LEFT )
+ nX = 0;
+ else if ( nStyle & SIB_RIGHT )
+ nX = rRectSize.Width()-rTextSize.Width();
+ else // SIB_CENTER
+ nX = (rRectSize.Width()-rTextSize.Width())/2;
+ nY = (rRectSize.Height()-rTextSize.Height())/2 + 1;
+ return Point( nX, nY );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL StatusBar::ImplIsItemUpdate()
+{
+ if ( !mbProgressMode && mbVisibleItems && IsReallyVisible() && IsUpdateMode() )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::ImplInit( Window* pParent, WinBits nStyle )
+{
+ // Default ist RightAlign
+ if ( !(nStyle & (WB_LEFT | WB_RIGHT)) )
+ nStyle |= WB_RIGHT;
+
+ Window::ImplInit( pParent, nStyle & ~WB_BORDER, NULL );
+
+ // WinBits merken
+ mpItemList = new ImplStatusItemList;
+ mpVirDev = new VirtualDevice( *this );
+ mnCurItemId = 0;
+ mbFormat = TRUE;
+ mbVisibleItems = TRUE;
+ mbProgressMode = FALSE;
+ mbInUserDraw = FALSE;
+ mbBottomBorder = FALSE;
+ mnDX = 0;
+ mnDY = 0;
+ mnCalcHeight = 0;
+ mnItemY = STATUSBAR_OFFSET_Y;
+ mnTextY = STATUSBAR_OFFSET_TEXTY;
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ SetLineColor();
+
+ SetSizePixel( CalcWindowSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+StatusBar::StatusBar( Window* pParent, WinBits nStyle ) :
+ Window( WINDOW_STATUSBAR )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+StatusBar::StatusBar( Window* pParent, const ResId& rResId ) :
+ Window( WINDOW_STATUSBAR )
+{
+ rResId.SetRT( RSC_STATUSBAR );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+StatusBar::~StatusBar()
+{
+ // Alle Items loeschen
+ ImplStatusItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ delete mpItemList;
+
+ // VirtualDevice loeschen
+ delete mpVirDev;
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetToolFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else if ( GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetButtonTextColor();
+ else
+ aColor = rStyleSettings.GetWindowTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+
+ mpVirDev->SetFont( GetFont() );
+ mpVirDev->SetTextColor( GetTextColor() );
+ mpVirDev->SetTextAlign( GetTextAlign() );
+ mpVirDev->SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else if ( GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetFaceColor();
+ else
+ aColor = rStyleSettings.GetWindowColor();
+ SetBackground( aColor );
+ mpVirDev->SetBackground( GetBackground() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::ImplFormat()
+{
+ ImplStatusItem* pItem;
+ long nExtraWidth;
+ long nExtraWidth2;
+ long nX;
+ USHORT nAutoSizeItems = 0;
+
+ // Breiten zusammenrechnen
+ mnItemsWidth = STATUSBAR_OFFSET_X;
+ long nOffset = 0;
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbVisible )
+ {
+ if ( pItem->mnBits & SIB_AUTOSIZE )
+ nAutoSizeItems++;
+
+ mnItemsWidth += pItem->mnWidth + nOffset;
+ nOffset = pItem->mnOffset;
+ }
+
+ pItem = mpItemList->Next();
+ }
+
+ if ( GetStyle() & WB_RIGHT )
+ {
+ // Bei rechtsbuendiger Ausrichtung wird kein AutoSize ausgewertet,
+ // da wir links den Text anzeigen, der mit SetText gesetzt wird
+ nX = mnDX - mnItemsWidth;
+ nExtraWidth = 0;
+ nExtraWidth2 = 0;
+ }
+ else
+ {
+ mnItemsWidth += STATUSBAR_OFFSET_X;
+
+ // Bei linksbuendiger Ausrichtung muessen wir gegebenenfalls noch
+ // AutoSize auswerten
+ if ( nAutoSizeItems && (mnDX > (mnItemsWidth - STATUSBAR_OFFSET)) )
+ {
+ nExtraWidth = (mnDX - mnItemsWidth - 1) / nAutoSizeItems;
+ nExtraWidth2 = (mnDX - mnItemsWidth - 1) % nAutoSizeItems;
+ }
+ else
+ {
+ nExtraWidth = 0;
+ nExtraWidth2 = 0;
+ }
+ nX = STATUSBAR_OFFSET_X;
+ }
+
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbVisible )
+ {
+ if ( pItem->mnBits & SIB_AUTOSIZE )
+ {
+ pItem->mnExtraWidth = nExtraWidth;
+ if ( nExtraWidth2 )
+ {
+ pItem->mnExtraWidth++;
+ nExtraWidth2--;
+ }
+ }
+ else
+ pItem->mnExtraWidth = 0;
+
+ pItem->mnX = nX;
+ nX += pItem->mnWidth + pItem->mnExtraWidth + pItem->mnOffset;
+ }
+
+ pItem = mpItemList->Next();
+ }
+
+ mbFormat = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle StatusBar::ImplGetItemRectPos( USHORT nPos ) const
+{
+ Rectangle aRect;
+ ImplStatusItem* pItem;
+
+ pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem )
+ {
+ if ( pItem->mbVisible )
+ {
+ aRect.Left() = pItem->mnX;
+ aRect.Right() = aRect.Left() + pItem->mnWidth + pItem->mnExtraWidth;
+ aRect.Top() = mnItemY;
+ aRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y;
+ }
+ }
+
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::ImplDrawText( BOOL bOffScreen, long nOldTextWidth )
+{
+ // Das ueberschreiben der Item-Box verhindern
+ Rectangle aTextRect;
+ aTextRect.Left() = STATUSBAR_OFFSET_X+1;
+ aTextRect.Top() = mnTextY;
+ if ( mbVisibleItems && (GetStyle() & WB_RIGHT) )
+ aTextRect.Right() = mnDX - mnItemsWidth - 1;
+ else
+ aTextRect.Right() = mnDX - 1;
+ if ( aTextRect.Right() > aTextRect.Left() )
+ {
+ // Position ermitteln
+ XubString aStr = GetText();
+ USHORT nPos = aStr.Search( _LF );
+ if ( nPos != STRING_NOTFOUND )
+ aStr.Erase( nPos );
+
+ aTextRect.Bottom() = aTextRect.Top()+GetTextHeight()+1;
+
+ if ( bOffScreen )
+ {
+ long nMaxWidth = Max( nOldTextWidth, GetTextWidth( aStr ) );
+ Size aVirDevSize( nMaxWidth, aTextRect.GetHeight() );
+ mpVirDev->SetOutputSizePixel( aVirDevSize );
+ Rectangle aTempRect = aTextRect;
+ aTempRect.SetPos( Point( 0, 0 ) );
+ mpVirDev->DrawText( aTempRect, aStr, TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_CLIP | TEXT_DRAW_ENDELLIPSIS );
+ DrawOutDev( aTextRect.TopLeft(), aVirDevSize, Point(), aVirDevSize, *mpVirDev );
+ }
+ else
+ DrawText( aTextRect, aStr, TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_CLIP | TEXT_DRAW_ENDELLIPSIS );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::ImplDrawItem( BOOL bOffScreen, USHORT nPos, BOOL bDrawText, BOOL bDrawFrame )
+{
+ Rectangle aRect = ImplGetItemRectPos( nPos );
+
+ if ( aRect.IsEmpty() )
+ return;
+
+ // Ausgabebereich berechnen
+ ImplStatusItem* pItem = mpItemList->GetObject( nPos );
+ Rectangle aTextRect( aRect.Left()+1, aRect.Top()+1,
+ aRect.Right()-1, aRect.Bottom()-1 );
+ Size aTextRectSize( aTextRect.GetSize() );
+
+ if ( bOffScreen )
+ mpVirDev->SetOutputSizePixel( aTextRectSize );
+ else
+ {
+ Region aRegion( aTextRect );
+ SetClipRegion( aRegion );
+ }
+
+ // Text ausgeben
+ if ( bDrawText )
+ {
+ Size aTextSize( GetTextWidth( pItem->maText ), GetTextHeight() );
+ Point aTextPos = ImplGetItemTextPos( aTextRectSize, aTextSize, pItem->mnBits );
+ if ( bOffScreen )
+ mpVirDev->DrawText( aTextPos, pItem->maText );
+ else
+ {
+ aTextPos.X() += aTextRect.Left();
+ aTextPos.Y() += aTextRect.Top();
+ DrawText( aTextPos, pItem->maText );
+ }
+ }
+
+ // Gegebenenfalls auch DrawItem aufrufen
+ if ( pItem->mnBits & SIB_USERDRAW )
+ {
+ if ( bOffScreen )
+ {
+ mbInUserDraw = TRUE;
+ UserDrawEvent aODEvt( mpVirDev, Rectangle( Point(), aTextRectSize ), pItem->mnId );
+ UserDraw( aODEvt );
+ mbInUserDraw = FALSE;
+ }
+ else
+ {
+ UserDrawEvent aODEvt( this, aTextRect, pItem->mnId );
+ UserDraw( aODEvt );
+ }
+ }
+
+ if ( bOffScreen )
+ DrawOutDev( aTextRect.TopLeft(), aTextRectSize, Point(), aTextRectSize, *mpVirDev );
+ else
+ SetClipRegion();
+
+ // Frame ausgeben
+ if ( bDrawFrame && !(pItem->mnBits & SIB_FLAT) )
+ {
+ USHORT nStyle;
+
+ if ( pItem->mnBits & SIB_IN )
+ nStyle = FRAME_DRAW_IN;
+ else
+ nStyle = FRAME_DRAW_OUT;
+
+ DecorationView aDecoView( this );
+ aDecoView.DrawFrame( aRect, nStyle );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize( "", off )
+#endif
+
+void DrawProgress( Window* pWindow, const Point& rPos,
+ long nOffset, long nPrgsWidth, long nPrgsHeight,
+ USHORT nPercent1, USHORT nPercent2, USHORT nPercentCount )
+{
+ // Werte vorberechnen
+ USHORT nPerc1 = nPercent1 / nPercentCount;
+ USHORT nPerc2 = nPercent2 / nPercentCount;
+
+ // Percent-Rechtecke malen
+ if ( nPerc1 < nPerc2 )
+ {
+ // Wenn Percent2 ueber 100%, Werte anpassen
+ if ( nPercent2 > 10000 )
+ {
+ nPerc2 = 10000 / nPercentCount;
+ if ( nPerc1 >= nPerc2 )
+ nPerc1 = nPerc2-1;
+ }
+
+ // Rechteck berechnen
+ long nDX = nPrgsWidth + nOffset;
+ long nLeft = rPos.X()+(nPerc1*nDX);
+ Rectangle aRect( nLeft, rPos.Y(), nLeft+nPrgsWidth, rPos.Y()+nPrgsHeight );
+
+ do
+ {
+ pWindow->DrawRect( aRect );
+ aRect.Left() += nDX;
+ aRect.Right() += nDX;
+ nPerc1++;
+ }
+ while ( nPerc1 < nPerc2 );
+
+ // Bei mehr als 100%, lassen wir das Rechteck blinken
+ if ( nPercent2 > 10000 )
+ {
+ // an/aus-Status festlegen
+ if ( ((nPercent2 / nPercentCount) & 0x01) == (nPercentCount & 0x01) )
+ {
+ aRect.Left() -= nDX;
+ aRect.Right() -= nDX;
+ pWindow->Erase( aRect );
+ }
+ }
+
+ pWindow->Flush();
+ }
+}
+
+#ifdef _MSC_VER
+#pragma optimize( "", on )
+#endif
+
+// -----------------------------------------------------------------------
+
+void StatusBar::ImplDrawProgress( BOOL bPaint,
+ USHORT nPercent1, USHORT nPercent2 )
+{
+ // Wenn Paint, dann muss auch Text und Frame gemalt werden
+ if ( bPaint )
+ {
+ DrawText( maPrgsTxtPos, maPrgsTxt );
+ DecorationView aDecoView( this );
+ aDecoView.DrawFrame( maPrgsFrameRect, FRAME_DRAW_IN );
+ }
+
+ Point aPos( maPrgsFrameRect.Left()+STATUSBAR_PRGS_OFFSET,
+ maPrgsFrameRect.Top()+STATUSBAR_PRGS_OFFSET );
+ DrawProgress( this, aPos, mnPrgsSize/2, mnPrgsSize, mnPrgsSize,
+ nPercent1*100, nPercent2*100, mnPercentCount );
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::ImplCalcProgressRect()
+{
+ // Groessen berechnen
+ Size aPrgsTxtSize( GetTextWidth( maPrgsTxt ), GetTextHeight() );
+ maPrgsTxtPos.X() = STATUSBAR_OFFSET_X+1;
+ maPrgsTxtPos.Y() = mnTextY;
+
+ // Progress-Frame berechnen
+ maPrgsFrameRect.Left() = maPrgsTxtPos.X()+aPrgsTxtSize.Width()+STATUSBAR_OFFSET;
+ maPrgsFrameRect.Top() = mnItemY;
+ maPrgsFrameRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y;
+
+ // Dabei die Breite des Fensters berechnen
+ mnPrgsSize = maPrgsFrameRect.Bottom()-maPrgsFrameRect.Top()-(STATUSBAR_PRGS_OFFSET*2);
+ USHORT nMaxPercent = STATUSBAR_PRGS_COUNT;
+
+ long nMaxWidth = mnDX-STATUSBAR_OFFSET-1;
+
+ // Wenn es zu viele Percent-Rects sind, verkuerzen wir
+ while ( maPrgsFrameRect.Left()+ImplCalcProgessWidth( nMaxPercent, mnPrgsSize ) > nMaxWidth )
+ {
+ nMaxPercent--;
+ if ( nMaxPercent <= STATUSBAR_PRGS_MIN )
+ break;
+ }
+ maPrgsFrameRect.Right() = maPrgsFrameRect.Left() + ImplCalcProgessWidth( nMaxPercent, mnPrgsSize );
+ // Fuer die weitere Berechnung brauchen wir den Teiler
+ mnPercentCount = 10000 / nMaxPercent;
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ // Nur bei linker Maustaste ToolBox ausloesen
+ if ( rMEvt.IsLeft() )
+ {
+ if ( mbVisibleItems )
+ {
+ Point aMousePos = rMEvt.GetPosPixel();
+ USHORT i = 0;
+
+ // Item suchen, das geklickt wurde
+ ImplStatusItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Ist es dieses Item
+ if ( ImplGetItemRectPos( i ).IsInside( aMousePos ) )
+ {
+ mnCurItemId = pItem->mnId;
+ if ( rMEvt.GetClicks() == 2 )
+ DoubleClick();
+ else
+ Click();
+ mnCurItemId = 0;
+
+ // Item wurde gefunden
+ return;
+ }
+
+ i++;
+ pItem = mpItemList->Next();
+ }
+ }
+
+ // Kein Item, dann nur Click oder DoubleClick
+ if ( rMEvt.GetClicks() == 2 )
+ DoubleClick();
+ else
+ Click();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::Paint( const Rectangle& )
+{
+ if ( mbFormat )
+ ImplFormat();
+
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+
+ if ( mbProgressMode )
+ ImplDrawProgress( TRUE, 0, mnPercent );
+ else
+ {
+ // Text zeichen
+ if ( !mbVisibleItems || (GetStyle() & WB_RIGHT) )
+ ImplDrawText( FALSE, 0 );
+
+ // Items zeichnen
+ if ( mbVisibleItems )
+ {
+ // Items zeichnen
+ for ( USHORT i = 0; i < nItemCount; i++ )
+ ImplDrawItem( FALSE, i, TRUE, TRUE );
+ }
+ }
+
+ if ( mbBottomBorder )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( 0, mnDY-2 ), Point( mnDX-1, mnDY-2 ) );
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::Move()
+{
+ Window::Move();
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::Resize()
+{
+ // Breite und Hoehe abfragen und merken
+ long nOldDY = mnDX;
+ Size aSize = GetOutputSizePixel();
+ mnDX = aSize.Width();
+ mnDY = aSize.Height();
+ mnCalcHeight = mnDY;
+ if ( mbBottomBorder )
+ mnCalcHeight -= 2;
+
+ // Evt. neue Textposition berechnen
+ if ( nOldDY && (nOldDY < mnDY) )
+ {
+ mnTextY = 0;
+ mnTextY += (mnCalcHeight-GetTextHeight()-mnTextY)/2;
+ }
+
+ // Formatierung neu ausloesen
+ mbFormat = TRUE;
+
+ if ( mbProgressMode )
+ ImplCalcProgressRect();
+
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::RequestHelp( const HelpEvent& rHEvt )
+{
+ USHORT nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+
+ if ( nItemId )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ {
+ Rectangle aItemRect = GetItemRect( nItemId );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ XubString aStr = GetHelpText( nItemId );
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ return;
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_QUICK )
+ {
+ Rectangle aItemRect = GetItemRect( nItemId );
+ XubString aStr = GetItemText( nItemId );
+ // Wir zeigen die Quick-Hilfe nur an, wenn Text nicht
+ // vollstaendig sichtbar
+ if ( GetTextWidth( aStr ) > aItemRect.GetWidth() )
+ {
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ Help::ShowQuickHelp( this, aItemRect, aStr );
+ return;
+ }
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
+ {
+ ULONG nHelpId = GetHelpId( nItemId );
+ if ( nHelpId )
+ {
+ // Wenn eine Hilfe existiert, dann ausloesen
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nHelpId );
+ return;
+ }
+ }
+ }
+
+ Window::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ImplFormat();
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ Invalidate();
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ mbFormat = TRUE;
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ mbFormat = TRUE;
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::Click()
+{
+ maClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::UserDraw( const UserDrawEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::InsertItem( USHORT nItemId, ULONG nWidth,
+ StatusBarItemBits nBits,
+ long nOffset, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "StatusBar::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == STATUSBAR_ITEM_NOTFOUND,
+ "StatusBar::InsertItem(): ItemId already exists" );
+
+ // IN und CENTER sind Default
+ if ( !(nBits & (SIB_IN | SIB_OUT | SIB_FLAT)) )
+ nBits |= SIB_IN;
+ if ( !(nBits & (SIB_LEFT | SIB_RIGHT | SIB_CENTER)) )
+ nBits |= SIB_CENTER;
+
+ // Item anlegen
+ ImplStatusItem* pItem = new ImplStatusItem;
+ pItem->mnId = nItemId;
+ pItem->mnBits = nBits;
+ pItem->mnWidth = (long)nWidth+2;
+ pItem->mnOffset = nOffset;
+ pItem->mnHelpId = 0;
+ pItem->mpUserData = 0;
+ pItem->mbVisible = TRUE;
+
+ // Item in die Liste einfuegen
+ mpItemList->Insert( pItem, nPos );
+
+ mbFormat = TRUE;
+ if ( ImplIsItemUpdate() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::RemoveItem( USHORT nItemId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ {
+ ImplStatusItem* pItem = mpItemList->Remove( nPos );
+ delete pItem;
+
+ mbFormat = TRUE;
+ if ( ImplIsItemUpdate() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::ShowItem( USHORT nItemId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ {
+ ImplStatusItem* pItem = mpItemList->GetObject( nPos );
+ if ( !pItem->mbVisible )
+ {
+ pItem->mbVisible = TRUE;
+
+ mbFormat = TRUE;
+ if ( ImplIsItemUpdate() )
+ Invalidate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::HideItem( USHORT nItemId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ {
+ ImplStatusItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem->mbVisible )
+ {
+ pItem->mbVisible = FALSE;
+
+ mbFormat = TRUE;
+ if ( ImplIsItemUpdate() )
+ Invalidate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL StatusBar::IsItemVisible( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mbVisible;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::ShowItems()
+{
+ if ( !mbVisibleItems )
+ {
+ mbVisibleItems = TRUE;
+ if ( !mbProgressMode )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::HideItems()
+{
+ if ( mbVisibleItems )
+ {
+ mbVisibleItems = FALSE;
+ if ( !mbProgressMode )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::CopyItems( const StatusBar& rStatusBar )
+{
+ // Alle Items entfernen
+ ImplStatusItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Items aus der Liste loeschen
+ mpItemList->Clear();
+
+ // Items kopieren
+ ULONG i = 0;
+ pItem = rStatusBar.mpItemList->GetObject( i );
+ while ( pItem )
+ {
+ mpItemList->Insert( new ImplStatusItem( *pItem ), LIST_APPEND );
+ i++;
+ pItem = rStatusBar.mpItemList->GetObject( i );
+ }
+
+ mbFormat = TRUE;
+ if ( ImplIsItemUpdate() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::Clear()
+{
+ // Alle Item loeschen
+ ImplStatusItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Items aus der Liste loeschen
+ mpItemList->Clear();
+
+ mbFormat = TRUE;
+ if ( ImplIsItemUpdate() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT StatusBar::GetItemCount() const
+{
+ return (USHORT)mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT StatusBar::GetItemId( USHORT nPos ) const
+{
+ ImplStatusItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem )
+ return pItem->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT StatusBar::GetItemPos( USHORT nItemId ) const
+{
+ ImplStatusItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nItemId )
+ return (USHORT)mpItemList->GetCurPos();
+
+ pItem = mpItemList->Next();
+ }
+
+ return STATUSBAR_ITEM_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT StatusBar::GetItemId( const Point& rPos ) const
+{
+ if ( AreItemsVisible() && !mbFormat )
+ {
+ USHORT nItemCount = GetItemCount();
+ USHORT nPos;
+ for ( nPos = 0; nPos < nItemCount; nPos++ )
+ {
+ // Rechteck holen
+ Rectangle aRect = ImplGetItemRectPos( nPos );
+ if ( aRect.IsInside( rPos ) )
+ return mpItemList->GetObject( nPos )->mnId;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle StatusBar::GetItemRect( USHORT nItemId ) const
+{
+ Rectangle aRect;
+
+ if ( AreItemsVisible() && !mbFormat )
+ {
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ {
+ // Rechteck holen und Rahmen abziehen
+ aRect = ImplGetItemRectPos( nPos );
+ aRect.Left()++;
+ aRect.Right()--;
+ return aRect;
+ }
+ }
+
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+Point StatusBar::GetItemTextPos( USHORT nItemId ) const
+{
+ if ( !mbFormat )
+ {
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ {
+ // Rechteck holen
+ ImplStatusItem* pItem = mpItemList->GetObject( nPos );
+ Rectangle aRect = ImplGetItemRectPos( nPos );
+ Rectangle aTextRect( aRect.Left()+1, aRect.Top()+1,
+ aRect.Right()-1, aRect.Bottom()-1 );
+ Point aPos = ImplGetItemTextPos( aTextRect.GetSize(),
+ Size( GetTextWidth( pItem->maText ), GetTextHeight() ),
+ pItem->mnBits );
+ if ( !mbInUserDraw )
+ {
+ aPos.X() += aTextRect.Left();
+ aPos.Y() += aTextRect.Top();
+ }
+ return aPos;
+ }
+ }
+
+ return Point();
+}
+
+// -----------------------------------------------------------------------
+
+ULONG StatusBar::GetItemWidth( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnWidth;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+StatusBarItemBits StatusBar::GetItemBits( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnBits;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long StatusBar::GetItemOffset( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnOffset;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::SetItemText( USHORT nItemId, const XubString& rText )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ {
+ ImplStatusItem* pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->maText != rText )
+ {
+ pItem->maText = rText;
+
+ // Item neu Zeichen, wenn StatusBar sichtbar und
+ // UpdateMode gesetzt ist
+ if ( pItem->mbVisible && !mbFormat && ImplIsItemUpdate() )
+ {
+ Update();
+ ImplDrawItem( TRUE, nPos, TRUE, FALSE );
+ Flush();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& StatusBar::GetItemText( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maText;
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::SetItemData( USHORT nItemId, void* pNewData )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ {
+ ImplStatusItem* pItem = mpItemList->GetObject( nPos );
+ pItem->mpUserData = pNewData;
+
+ // Wenn es ein User-Item ist, DrawItem-Aufrufen
+ if ( (pItem->mnBits & SIB_USERDRAW) && pItem->mbVisible &&
+ !mbFormat && ImplIsItemUpdate() )
+ {
+ Update();
+ ImplDrawItem( TRUE, nPos, FALSE, FALSE );
+ Flush();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void* StatusBar::GetItemData( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mpUserData;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::SetHelpText( USHORT nItemId, const XubString& rText )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ mpItemList->GetObject( nPos )->maHelpText = rText;
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& StatusBar::GetHelpText( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ {
+ ImplStatusItem* pItem = mpItemList->GetObject( nPos );
+ if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId );
+ }
+
+ return pItem->maHelpText;
+ }
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::SetHelpId( USHORT nItemId, ULONG nHelpId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ mpItemList->GetObject( nPos )->mnHelpId = nHelpId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG StatusBar::GetHelpId( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != STATUSBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnHelpId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::SetBottomBorder( BOOL bBottomBorder )
+{
+ if ( mbBottomBorder != bBottomBorder )
+ {
+ mbBottomBorder = bBottomBorder;
+ mnCalcHeight = mnDY;
+ if ( mbBottomBorder )
+ mnCalcHeight -= 2;
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::StartProgressMode( const XubString& rText )
+{
+ DBG_ASSERT( !mbProgressMode, "StatusBar::StartProgressMode(): progress mode is active" );
+
+ mbProgressMode = TRUE;
+ mnPercent = 0;
+ maPrgsTxt = rText;
+
+ // Groessen berechnen
+ ImplCalcProgressRect();
+
+ // Paint ausloesen (dort wird der Text und der Frame gemalt)
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Color aPrgsColor = rStyleSettings.GetHighlightColor();
+ if ( aPrgsColor == rStyleSettings.GetFaceColor() )
+ aPrgsColor = rStyleSettings.GetDarkShadowColor();
+ SetLineColor();
+ SetFillColor( aPrgsColor );
+ if ( IsReallyVisible() )
+ {
+ Invalidate();
+ Update();
+ Flush();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::SetProgressValue( USHORT nNewPercent )
+{
+ DBG_ASSERT( mbProgressMode, "StatusBar::SetProgressValue(): no progrss mode" );
+ DBG_ASSERTWARNING( nNewPercent <= 100, "StatusBar::SetProgressValue(): nPercent > 100" );
+
+ if ( mbProgressMode && IsReallyVisible() )
+ {
+ Update();
+ SetLineColor();
+ ImplDrawProgress( FALSE, mnPercent, nNewPercent );
+ Flush();
+ }
+ mnPercent = nNewPercent;
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::EndProgressMode()
+{
+ DBG_ASSERT( mbProgressMode, "StatusBar::EndProgressMode(): no progress mode" );
+
+ mbProgressMode = FALSE;
+ maPrgsTxt.Erase();
+
+ // Paint neu ausloesen um StatusBar wieder herzustellen
+ SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
+ if ( IsReallyVisible() )
+ {
+ Invalidate();
+ Update();
+ Flush();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void StatusBar::SetText( const XubString& rText )
+{
+ if ( (!mbVisibleItems || (GetStyle() & WB_RIGHT)) && !mbProgressMode &&
+ IsReallyVisible() && IsUpdateMode() )
+ {
+ if ( mbFormat )
+ {
+ Invalidate();
+ Window::SetText( rText );
+ }
+ else
+ {
+ Update();
+ long nOldTextWidth = GetTextWidth( GetText() );
+ Window::SetText( rText );
+ ImplDrawText( TRUE, nOldTextWidth );
+ Flush();
+ }
+ }
+ else
+ Window::SetText( rText );
+}
+
+// -----------------------------------------------------------------------
+
+Size StatusBar::CalcWindowSizePixel() const
+{
+ ULONG i = 0;
+ ULONG nCount = mpItemList->Count();
+ long nOffset = 0;
+ long nCalcWidth = (STATUSBAR_OFFSET_X*2);
+ long nCalcHeight;
+
+ while ( i < nCount )
+ {
+ ImplStatusItem* pItem = mpItemList->GetObject( i );
+ nCalcWidth += pItem->mnWidth + nOffset;
+ nOffset = pItem->mnOffset;
+ i++;
+ }
+
+ nCalcHeight = GetTextHeight()+(STATUSBAR_OFFSET_TEXTY*2);
+ if ( mbBottomBorder )
+ nCalcHeight += 2;
+
+ return Size( nCalcWidth, nCalcHeight );
+}
diff --git a/vcl/source/window/syschild.cxx b/vcl/source/window/syschild.cxx
new file mode 100644
index 000000000000..99991bc91b3e
--- /dev/null
+++ b/vcl/source/window/syschild.cxx
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * $RCSfile: syschild.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SYSCHILD_CXX
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#include <window.hxx>
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_WIDNOW_H
+#include <window.h>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_SYSCHILD_HXX
+#include <syschild.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+#ifndef REMOTE_APPSERVER
+
+long ImplSysChildProc( void* pInst, SalObject* /* pObject */,
+ USHORT nEvent, const void* /* pEvent */ )
+{
+ SystemChildWindow* pWindow = (SystemChildWindow*)pInst;
+ long nRet = 0;
+
+ switch ( nEvent )
+ {
+ case SALOBJ_EVENT_GETFOCUS:
+ // Focus holen und zwar so, das alle Handler gerufen
+ // werden, als ob dieses Fenster den Focus bekommt,
+ // ohne das der Frame den Focus wieder klaut
+ pWindow->ImplGetFrameData()->mbSysObjFocus = TRUE;
+ pWindow->ImplGetFrameData()->mbInSysObjToTopHdl = TRUE;
+ pWindow->ToTop( TOTOP_NOGRABFOCUS );
+ pWindow->ImplGetFrameData()->mbInSysObjToTopHdl = FALSE;
+ pWindow->ImplGetFrameData()->mbInSysObjFocusHdl = TRUE;
+ pWindow->GrabFocus();
+ pWindow->ImplGetFrameData()->mbInSysObjFocusHdl = FALSE;
+ break;
+
+ case SALOBJ_EVENT_LOSEFOCUS:
+ // Hintenrum einen LoseFocus ausloesen, das der Status
+ // der Fenster dem entsprechenden Activate-Status
+ // entspricht
+ pWindow->ImplGetFrameData()->mbSysObjFocus = FALSE;
+ if ( !pWindow->ImplGetFrameData()->mnFocusId )
+ {
+ pWindow->ImplGetFrameData()->mbStartFocusState = TRUE;
+ Application::PostUserEvent( pWindow->ImplGetFrameData()->mnFocusId, LINK( pWindow->ImplGetFrameWindow(), Window, ImplAsyncFocusHdl ) );
+ }
+ break;
+
+ case SALOBJ_EVENT_TOTOP:
+ pWindow->ImplGetFrameData()->mbInSysObjToTopHdl = TRUE;
+ if ( !Application::GetFocusWindow() || pWindow->HasChildPathFocus() )
+ pWindow->ToTop( TOTOP_NOGRABFOCUS );
+ else
+ pWindow->ToTop();
+ pWindow->GrabFocus();
+ pWindow->ImplGetFrameData()->mbInSysObjToTopHdl = FALSE;
+ break;
+ }
+
+ return nRet;
+}
+
+#endif
+
+// =======================================================================
+
+void SystemChildWindow::ImplInit( Window* pParent, WinBits nStyle )
+{
+#ifndef REMOTE_APPSERVER
+ mpSysObj = ImplGetSVData()->mpDefInst->CreateObject( pParent->ImplGetFrame() );
+#endif
+
+ Window::ImplInit( pParent, nStyle, NULL );
+
+#ifndef REMOTE_APPSERVER
+ // Wenn es ein richtiges SysChild ist, dann painten wir auch nicht
+ if ( GetSystemData() )
+ {
+ mpSysObj->SetCallback( this, ImplSysChildProc );
+ SetParentClipMode( PARENTCLIPMODE_CLIP );
+ SetBackground();
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+SystemChildWindow::SystemChildWindow( Window* pParent, WinBits nStyle ) :
+ Window( WINDOW_SYSTEMCHILDWINDOW )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+SystemChildWindow::SystemChildWindow( Window* pParent, const ResId& rResId ) :
+ Window( WINDOW_SYSTEMCHILDWINDOW )
+{
+ rResId.SetRT( RSC_WINDOW );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+SystemChildWindow::~SystemChildWindow()
+{
+#ifndef REMOTE_APPSERVER
+ Hide();
+ if ( mpSysObj )
+ {
+ ImplGetSVData()->mpDefInst->DestroyObject( mpSysObj );
+ mpSysObj = NULL;
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* SystemChildWindow::GetSystemData() const
+{
+#ifndef REMOTE_APPSERVER
+ if ( mpSysObj )
+ return mpSysObj->GetSystemData();
+ else
+ return NULL;
+#else
+ return NULL;
+#endif
+}
+
diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx
new file mode 100644
index 000000000000..786f1af2b15a
--- /dev/null
+++ b/vcl/source/window/syswin.cxx
@@ -0,0 +1,389 @@
+/*************************************************************************
+ *
+ * $RCSfile: syswin.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SYSWIN_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+#ifndef _SV_MENU_HXX
+#include <menu.hxx>
+#endif
+#ifndef _SV_ACCESS_HXX
+#include <access.hxx>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_SYSWIN_HXX
+#include <syswin.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+
+#include <unowrap.hxx>
+
+#pragma hdrstop
+
+// =======================================================================
+
+SystemWindow::SystemWindow( WindowType nType ) :
+ Window( nType )
+{
+ mbSysWin = TRUE;
+ mnActivateMode = ACTIVATE_MODE_GRABFOCUS;
+
+ mpMenuBar = NULL;
+ mbPined = FALSE;
+ mbRollUp = FALSE;
+ mbRollFunc = FALSE;
+ mbDockBtn = FALSE;
+ mbHideBtn = FALSE;
+ mnMenuBarMode = MENUBAR_MODE_NORMAL;
+}
+
+// -----------------------------------------------------------------------
+
+long SystemWindow::Notify( NotifyEvent& rNEvt )
+{
+ // Abfangen von KeyEvents fuer Menu-Steuerung
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ MenuBar* pMBar = mpMenuBar;
+ if ( !pMBar && ( GetType() == WINDOW_FLOATINGWINDOW ) )
+ {
+ SystemWindow* pW = (SystemWindow*)ImplGetFrameWindow()->ImplGetWindow();
+ if ( pW )
+ pMBar = pW->GetMenuBar();
+ }
+ if ( pMBar && pMBar->ImplHandleKeyEvent( *rNEvt.GetKeyEvent(), FALSE ) )
+ return TRUE;
+ }
+
+ return Window::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SystemWindow::Close()
+{
+ if ( mxWindowPeer.is() )
+ {
+ // #76482# This window can be destroyed in WindowEvent_Close.
+ // => Don't use members after calling WindowEvent_Close
+ BOOL bCreatedWithToolkit = IsCreatedWithToolkit();
+ Application::GetUnoWrapper()->WindowEvent_Close( this );
+ if ( bCreatedWithToolkit )
+ return FALSE;
+ }
+
+ Hide();
+
+ // Ist es das Applikationsfenster, dann beende die Applikation
+ if ( Application::GetAppWindow() == (const WorkWindow*)this )
+ GetpApp()->Quit();
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::TitleButtonClick( USHORT )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::Pin()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::Roll()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::Resizing( Size& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::SetZLevel( BYTE nLevel )
+{
+ Window* pWindow = this;
+ while ( pWindow->mpBorderWindow )
+ pWindow = pWindow->mpBorderWindow;
+ if ( pWindow->mbOverlapWin && !pWindow->mbFrame )
+ {
+ BYTE nOldLevel = pWindow->mpOverlapData->mnTopLevel;
+ pWindow->mpOverlapData->mnTopLevel = nLevel;
+ // Wenn der neue Level groesser als der alte ist, schieben
+ // wir das Fenster nach hinten
+ if ( !IsReallyVisible() && (nLevel > nOldLevel) && pWindow->mpNext )
+ {
+ // Fenster aus der Liste entfernen
+ if ( pWindow->mpPrev )
+ pWindow->mpPrev->mpNext = pWindow->mpNext;
+ else
+ pWindow->mpOverlapWindow->mpFirstOverlap = pWindow->mpNext;
+ pWindow->mpNext->mpPrev = pWindow->mpPrev;
+ pWindow->mpNext = NULL;
+ // und Fenster wieder in die Liste am Ende eintragen
+ pWindow->mpPrev = pWindow->mpOverlapWindow->mpLastOverlap;
+ pWindow->mpOverlapWindow->mpLastOverlap = pWindow;
+ pWindow->mpPrev->mpNext = pWindow;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BYTE SystemWindow::GetZLevel() const
+{
+ const Window* pWindow = this;
+ while ( pWindow->mpBorderWindow )
+ pWindow = pWindow->mpBorderWindow;
+ if ( pWindow->mpOverlapData )
+ return pWindow->mpOverlapData->mnTopLevel;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::EnableSaveBackground( BOOL bSave )
+{
+ Window* pWindow = this;
+ while ( pWindow->mpBorderWindow )
+ pWindow = pWindow->mpBorderWindow;
+ if ( pWindow->mbOverlapWin && !pWindow->mbFrame )
+ {
+ pWindow->mpOverlapData->mbSaveBack = bSave;
+ if ( !bSave )
+ pWindow->ImplDeleteOverlapBackground();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SystemWindow::IsSaveBackgroundEnabled() const
+{
+ const Window* pWindow = this;
+ while ( pWindow->mpBorderWindow )
+ pWindow = pWindow->mpBorderWindow;
+ if ( pWindow->mpOverlapData )
+ return pWindow->mpOverlapData->mbSaveBack;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::ShowTitleButton( USHORT nButton, BOOL bVisible )
+{
+ if ( nButton == TITLE_BUTTON_DOCKING )
+ {
+ if ( mbDockBtn != bVisible )
+ {
+ mbDockBtn = bVisible;
+ if ( mpBorderWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->SetDockButton( bVisible );
+ }
+ }
+ else /* if ( nButton == TITLE_BUTTON_HIDE ) */
+ {
+ if ( mbHideBtn != bVisible )
+ {
+ mbHideBtn = bVisible;
+ if ( mpBorderWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->SetHideButton( bVisible );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SystemWindow::IsTitleButtonVisible( USHORT nButton ) const
+{
+ if ( nButton == TITLE_BUTTON_DOCKING )
+ return mbDockBtn;
+ else /* if ( nButton == TITLE_BUTTON_HIDE ) */
+ return mbHideBtn;
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::SetPin( BOOL bPin )
+{
+ if ( bPin != mbPined )
+ {
+ mbPined = bPin;
+ if ( mpBorderWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->SetPin( bPin );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::RollUp()
+{
+ if ( !mbRollUp )
+ {
+ maOrgSize = GetOutputSizePixel();
+ mbRollFunc = TRUE;
+ Size aSize = maRollUpOutSize;
+ if ( !aSize.Width() )
+ aSize.Width() = GetOutputSizePixel().Width();
+ mbRollUp = TRUE;
+ if ( mpBorderWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->SetRollUp( TRUE, aSize );
+ else
+ SetOutputSizePixel( aSize );
+ mbRollFunc = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::RollDown()
+{
+ if ( mbRollUp )
+ {
+ mbRollUp = FALSE;
+ if ( mpBorderWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->SetRollUp( FALSE, maOrgSize );
+ else
+ SetOutputSizePixel( maOrgSize );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::SetMinOutputSizePixel( const Size& rSize )
+{
+ maMinOutSize = rSize;
+ if ( mpBorderWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->SetMinOutputSize( rSize.Width(), rSize.Height() );
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::SetMenuBar( MenuBar* pMenuBar )
+{
+ if ( mpMenuBar != pMenuBar )
+ {
+ MenuBar* pOldMenuBar = mpMenuBar;
+ Window* pOldWindow;
+ mpMenuBar = pMenuBar;
+
+ if ( mpBorderWindow && (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) )
+ {
+ if ( pOldMenuBar )
+ pOldWindow = pOldMenuBar->ImplGetWindow();
+ else
+ pOldWindow = NULL;
+ if ( pMenuBar )
+ {
+ DBG_ASSERT( !pMenuBar->pWindow, "SystemWindow::SetMenuBar() - MenuBars can only set in one SystemWindow at time" );
+ ((ImplBorderWindow*)mpBorderWindow)->SetMenuBarWindow( MenuBar::ImplCreate( mpBorderWindow, pOldWindow, pMenuBar ) );
+ }
+ else
+ ((ImplBorderWindow*)mpBorderWindow)->SetMenuBarWindow( NULL );
+ ImplToBottomChild();
+ if ( pOldMenuBar )
+ MenuBar::ImplDestroy( pOldMenuBar, pMenuBar == 0 );
+ }
+
+ Application::GenerateAccessEvent( ACCESS_EVENT_MENUBAR );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SystemWindow::SetMenuBarMode( USHORT nMode )
+{
+ if ( mnMenuBarMode != nMode )
+ {
+ mnMenuBarMode = nMode;
+ if ( mpBorderWindow && (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) )
+ {
+ if ( nMode == MENUBAR_MODE_HIDE )
+ ((ImplBorderWindow*)mpBorderWindow)->SetMenuBarMode( TRUE );
+ else
+ ((ImplBorderWindow*)mpBorderWindow)->SetMenuBarMode( FALSE );
+ }
+ }
+}
diff --git a/vcl/source/window/tabdlg.cxx b/vcl/source/window/tabdlg.cxx
new file mode 100644
index 000000000000..b4b212d90ec1
--- /dev/null
+++ b/vcl/source/window/tabdlg.cxx
@@ -0,0 +1,315 @@
+/*************************************************************************
+ *
+ * $RCSfile: tabdlg.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_TABDLG_CXX
+
+#ifndef _SV_FIXED_HXX
+#include <fixed.hxx>
+#endif
+#ifndef _SV_TABCTRL_HXX
+#include <tabctrl.hxx>
+#endif
+#ifndef _SV_TABDLG_HXX
+#include <tabdlg.hxx>
+#endif
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+void TabDialog::ImplInitData()
+{
+ mpFixedLine = NULL;
+ mpViewWindow = NULL;
+ meViewAlign = WINDOWALIGN_LEFT;
+ mbPosControls = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void TabDialog::ImplPosControls()
+{
+ Size aCtrlSize( IMPL_MINSIZE_BUTTON_WIDTH, IMPL_MINSIZE_BUTTON_HEIGHT );
+ long nDownCtrl = 0;
+ long nOffY = 0;
+ TabControl* pTabControl = NULL;
+
+ Window* pChild = GetWindow( WINDOW_FIRSTCHILD );
+ while ( pChild )
+ {
+ if ( pChild->IsVisible() && (pChild != mpViewWindow) )
+ {
+ if ( pChild->GetType() == WINDOW_TABCONTROL )
+ pTabControl = (TabControl*)pChild;
+ else if ( pTabControl )
+ {
+ long nTxtWidth = pChild->GetCtrlTextWidth( pChild->GetText() );
+ nTxtWidth += IMPL_EXTRA_BUTTON_WIDTH;
+ if ( nTxtWidth > aCtrlSize.Width() )
+ aCtrlSize.Width() = nTxtWidth;
+ long nTxtHeight = pChild->GetTextHeight();
+ nTxtHeight += IMPL_EXTRA_BUTTON_HEIGHT;
+ if ( nTxtHeight > aCtrlSize.Height() )
+ aCtrlSize.Height() = nTxtHeight;
+ nDownCtrl++;
+ }
+ else
+ {
+ long nHeight = pChild->GetSizePixel().Height();
+ if ( nHeight > nOffY )
+ nOffY = nHeight;
+ }
+ }
+
+ pChild = pChild->GetWindow( WINDOW_NEXT );
+ }
+
+ // Haben wir ueberhaupt ein TabControl
+ if ( pTabControl )
+ {
+ // Offset bei weiteren Controls um einen weiteren Abstand anpassen
+ if ( nOffY )
+ nOffY += IMPL_DIALOG_BAR_OFFSET*2 + 2;
+
+ Point aTabOffset( IMPL_DIALOG_OFFSET, IMPL_DIALOG_OFFSET+nOffY );
+ Size aTabSize = pTabControl->GetSizePixel();
+ Size aDlgSize( aTabSize.Width() + IMPL_DIALOG_OFFSET*2,
+ aTabSize.Height() + IMPL_DIALOG_OFFSET*2 + nOffY );
+ long nBtnEx = 0;
+
+ // Preview-Fenster beruecksichtigen und die Groessen/Offsets anpassen
+ if ( mpViewWindow && mpViewWindow->IsVisible() )
+ {
+ long nViewOffX = 0;
+ long nViewOffY = 0;
+ long nViewWidth = 0;
+ long nViewHeight = 0;
+ USHORT nViewPosFlags = WINDOW_POSSIZE_POS;
+ Size aViewSize = mpViewWindow->GetSizePixel();
+ if ( meViewAlign == WINDOWALIGN_TOP )
+ {
+ nViewOffX = aTabOffset.X();
+ nViewOffY = nOffY+IMPL_DIALOG_OFFSET;
+ nViewWidth = aTabSize.Width();
+ nViewPosFlags |= WINDOW_POSSIZE_WIDTH;
+ aTabOffset.Y() += aViewSize.Height()+IMPL_DIALOG_OFFSET;
+ aDlgSize.Height() += aViewSize.Height()+IMPL_DIALOG_OFFSET;
+ }
+ else if ( meViewAlign == WINDOWALIGN_BOTTOM )
+ {
+ nViewOffX = aTabOffset.X();
+ nViewOffY = aTabOffset.Y()+aTabSize.Height()+IMPL_DIALOG_OFFSET;
+ nViewWidth = aTabSize.Width();
+ nViewPosFlags |= WINDOW_POSSIZE_WIDTH;
+ aDlgSize.Height() += aViewSize.Height()+IMPL_DIALOG_OFFSET;
+ }
+ else if ( meViewAlign == WINDOWALIGN_RIGHT )
+ {
+ nViewOffX = aTabOffset.X()+aTabSize.Width()+IMPL_DIALOG_OFFSET;
+ nViewOffY = aTabOffset.Y();
+ nViewHeight = aTabSize.Height();
+ nViewPosFlags |= WINDOW_POSSIZE_HEIGHT;
+ aDlgSize.Width() += aViewSize.Width()+IMPL_DIALOG_OFFSET;
+ nBtnEx = aViewSize.Width()+IMPL_DIALOG_OFFSET;
+ }
+ else // meViewAlign == WINDOWALIGN_LEFT
+ {
+ nViewOffX = IMPL_DIALOG_OFFSET;
+ nViewOffY = aTabOffset.Y();
+ nViewHeight = aTabSize.Height();
+ nViewPosFlags |= WINDOW_POSSIZE_HEIGHT;
+ aTabOffset.X() += aViewSize.Width()+IMPL_DIALOG_OFFSET;
+ aDlgSize.Width() += aViewSize.Width()+IMPL_DIALOG_OFFSET;
+ nBtnEx = aViewSize.Width()+IMPL_DIALOG_OFFSET;
+ }
+
+ mpViewWindow->SetPosSizePixel( nViewOffX, nViewOffY,
+ nViewWidth, nViewHeight,
+ nViewPosFlags );
+ }
+
+ // Positionierung vornehmen
+ pTabControl->SetPosPixel( aTabOffset );
+
+ // Alle anderen Childs positionieren
+ BOOL bTabCtrl = FALSE;
+ int nLines = 0;
+ long nX;
+ long nY = aDlgSize.Height();
+ long nTopX = IMPL_DIALOG_OFFSET;
+
+ // Unter Windows 95 werden die Buttons rechtsbuendig angeordnet
+ nX = IMPL_DIALOG_OFFSET;
+ long nCtrlBarWidth = ((aCtrlSize.Width()+IMPL_DIALOG_OFFSET)*nDownCtrl)-IMPL_DIALOG_OFFSET;
+ if ( nCtrlBarWidth <= (aTabSize.Width()+nBtnEx) )
+ nX = (aTabSize.Width()+nBtnEx) - nCtrlBarWidth + IMPL_DIALOG_OFFSET;
+
+ pChild = pChild = GetWindow( WINDOW_FIRSTCHILD );
+ while ( pChild )
+ {
+ if ( pChild->IsVisible() && (pChild != mpViewWindow) )
+ {
+ if ( pChild == pTabControl )
+ bTabCtrl = TRUE;
+ else if ( bTabCtrl )
+ {
+ if ( !nLines )
+ nLines = 1;
+
+ if ( nX+aCtrlSize.Width()-IMPL_DIALOG_OFFSET > (aTabSize.Width()+nBtnEx) )
+ {
+ nY += aCtrlSize.Height()+IMPL_DIALOG_OFFSET;
+ nX = IMPL_DIALOG_OFFSET;
+ nLines++;
+ }
+
+ pChild->SetPosSizePixel( Point( nX, nY ), aCtrlSize );
+ nX += aCtrlSize.Width()+IMPL_DIALOG_OFFSET;
+ }
+ else
+ {
+ Size aChildSize = pChild->GetSizePixel();
+ pChild->SetPosPixel( Point( nTopX, (nOffY-aChildSize.Height())/2 ) );
+ nTopX += aChildSize.Width()+2;
+ }
+ }
+
+ pChild = pChild->GetWindow( WINDOW_NEXT );
+ }
+
+ aDlgSize.Height() += nLines * (aCtrlSize.Height()+IMPL_DIALOG_OFFSET);
+ SetOutputSizePixel( aDlgSize );
+ }
+
+ // Offset merken
+ if ( nOffY )
+ {
+ Size aDlgSize = GetOutputSizePixel();
+ if ( !mpFixedLine )
+ mpFixedLine = new FixedLine( this );
+ mpFixedLine->SetPosSizePixel( Point( 0, nOffY ),
+ Size( aDlgSize.Width(), 2 ) );
+ mpFixedLine->Show();
+ }
+
+ mbPosControls = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+TabDialog::TabDialog( Window* pParent, WinBits nStyle ) :
+ Dialog( WINDOW_TABDIALOG )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+TabDialog::TabDialog( Window* pParent, const ResId& rResId ) :
+ Dialog( WINDOW_TABDIALOG )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_TABDIALOG );
+ ImplInit( pParent, ImplInitRes( rResId ) );
+ ImplLoadRes( rResId );
+}
+
+// -----------------------------------------------------------------------
+
+TabDialog::~TabDialog()
+{
+ if ( mpFixedLine )
+ delete mpFixedLine;
+}
+
+// -----------------------------------------------------------------------
+
+void TabDialog::Resize()
+{
+// !!! In the future the controls should be automaticly rearrange
+// !!! if the window is resized
+// !!! if ( !IsRollUp() )
+// !!! ImplPosControls();
+}
+
+// -----------------------------------------------------------------------
+
+void TabDialog::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ // Calculate the Layout only for the initialized state
+ if ( mbPosControls )
+ ImplPosControls();
+ }
+ Dialog::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void TabDialog::AdjustLayout()
+{
+ ImplPosControls();
+}
diff --git a/vcl/source/window/tabpage.cxx b/vcl/source/window/tabpage.cxx
new file mode 100644
index 000000000000..af9d5b0a6f4b
--- /dev/null
+++ b/vcl/source/window/tabpage.cxx
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *
+ * $RCSfile: tabpage.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_TABPAGE_CXX
+
+#include <tools/ref.hxx>
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_TABPAGE_HXX
+#include <tabpage.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+void TabPage::ImplInit( Window* pParent, WinBits nStyle )
+{
+ if ( !(nStyle & WB_NODIALOGCONTROL) )
+ nStyle |= WB_DIALOGCONTROL;
+
+ Window::ImplInit( pParent, nStyle, NULL );
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void TabPage::ImplInitSettings()
+{
+ Window* pParent = GetParent();
+ if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
+ {
+ EnableChildTransparentMode( TRUE );
+ SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ }
+ else
+ {
+ EnableChildTransparentMode( FALSE );
+ SetParentClipMode( 0 );
+ SetPaintTransparent( FALSE );
+
+ if ( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( pParent->GetBackground() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+TabPage::TabPage( Window* pParent, WinBits nStyle ) :
+ Window( WINDOW_TABPAGE )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+TabPage::TabPage( Window* pParent, const ResId& rResId ) :
+ Window( WINDOW_TABPAGE )
+{
+ rResId.SetRT( RSC_TABPAGE );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void TabPage::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if ( Application::IsAutoMnemonicEnabled() )
+ ImplWindowAutoMnemonic( this );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabPage::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabPage::ActivatePage()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void TabPage::DeactivatePage()
+{
+}
diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx
new file mode 100644
index 000000000000..fcc618cba323
--- /dev/null
+++ b/vcl/source/window/toolbox.cxx
@@ -0,0 +1,4176 @@
+/*************************************************************************
+ *
+ * $RCSfile: toolbox.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_TOOLBOX_CXX
+
+#include <string.h>
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_DECOVIEW_HXX
+#include <decoview.hxx>
+#endif
+#ifndef _SV_ACCEL_HXX
+#include <accel.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_SOUND_HXX
+#include <sound.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_SPIN_H
+#include <spin.h>
+#endif
+#ifndef _SV_ACCESS_HXX
+#include <access.hxx>
+#endif
+#define private public
+#ifndef _SV_TOOLBOX_HXX
+#include <toolbox.hxx>
+#endif
+#undef private
+#ifndef _SV_TOOLBOX_H
+#include <toolbox.h>
+#endif
+
+// =======================================================================
+
+DBG_NAMEEX( Window );
+
+// =======================================================================
+
+#define SMALLBUTTON_HSIZE 7
+#define SMALLBUTTON_VSIZE 7
+
+#define SMALLBUTTON_OFF_NORMAL_X 3
+#define SMALLBUTTON_OFF_NORMAL_Y 3
+#define SMALLBUTTON_OFF_CHECKED_X 4
+#define SMALLBUTTON_OFF_CHECKED_Y 4
+#define SMALLBUTTON_OFF_PRESSED_X 5
+#define SMALLBUTTON_OFF_PRESSED_Y 5
+
+#define OUTBUTTON_SIZE 6
+#define OUTBUTTON_BORDER 4
+#define OUTBUTTON_OFF_NORMAL_X 1
+#define OUTBUTTON_OFF_NORMAL_Y 1
+
+// -----------------------------------------------------------------------
+
+#define DEF_MIN_WIDTH 8
+#define DEF_MIN_HEIGHT 8
+#define DEF_IMAGE_WIDTH 16
+#define DEF_IMAGE_HEIGHT 15
+#define DEF_TEXT_WIDTH 40
+
+#define TB_TEXTOFFSET 2
+#define TB_LINESPACING 3
+#define TB_SPIN_SIZE 14
+#define TB_SPIN_OFFSET 2
+#define TB_BORDER_OFFSET1 4
+#define TB_BORDER_OFFSET2 2
+#define TB_CUSTOMIZE_OFFSET 2
+#define TB_RESIZE_OFFSET 3
+#define TB_MAXLINES 5
+#define TB_MAXNOSCROLL 32765
+
+#define TB_MIN_WIN_WIDTH 20
+
+#define TB_CALCMODE_HORZ 1
+#define TB_CALCMODE_VERT 2
+#define TB_CALCMODE_FLOAT 3
+
+#define TB_WBLINESIZING (WB_SIZEABLE | WB_DOCKABLE | WB_SCROLL)
+
+#define TB_MAX_GROUPS 100
+
+#define DOCK_LINEHSIZE ((USHORT)0x0001)
+#define DOCK_LINEVSIZE ((USHORT)0x0002)
+#define DOCK_LINERIGHT ((USHORT)0x1000)
+#define DOCK_LINEBOTTOM ((USHORT)0x2000)
+#define DOCK_LINELEFT ((USHORT)0x4000)
+#define DOCK_LINETOP ((USHORT)0x8000)
+#define DOCK_LINEOFFSET 3
+
+// -----------------------------------------------------------------------
+
+struct ImplToolSize
+{
+ long mnWidth;
+ long mnHeight;
+ USHORT mnLines;
+};
+
+// -----------------------------------------------------------------------
+
+struct ImplButtonData
+{
+ VirtualDevice* mpBtnDev;
+ long mnWidth;
+ long mnHeight;
+ USHORT mnRefCount;
+};
+
+DECLARE_LIST( ImplButtonList, ImplButtonData* );
+
+// -----------------------------------------------------------------------
+
+DECLARE_LIST( ImplTBList, ToolBox* );
+
+class ImplTBDragMgr
+{
+private:
+ ImplTBList* mpBoxList;
+ ToolBox* mpDragBox;
+ Point maMouseOff;
+ Rectangle maRect;
+ Rectangle maStartRect;
+ Accelerator maAccel;
+ long mnMinWidth;
+ long mnMaxWidth;
+ USHORT mnLineMode;
+ USHORT mnStartLines;
+ void* mpCustomizeData;
+ BOOL mbCustomizeMode;
+ BOOL mbResizeMode;
+ BOOL mbShowDragRect;
+
+public:
+ ImplTBDragMgr();
+ ~ImplTBDragMgr();
+
+ void Insert( ToolBox* pBox )
+ { mpBoxList->Insert( pBox ); }
+ void Remove( ToolBox* pBox )
+ { mpBoxList->Remove( pBox ); }
+ ULONG Count() const
+ { return mpBoxList->Count(); }
+
+ ToolBox* FindToolBox( const Rectangle& rRect );
+
+ void StartDragging( ToolBox* pDragBox,
+ const Point& rPos, const Rectangle& rRect,
+ USHORT nLineMode, BOOL bResizeItem,
+ void* pData = NULL );
+ void Dragging( const Point& rPos );
+ void EndDragging( BOOL bOK = TRUE );
+ void HideDragRect() { if ( mbShowDragRect ) mpDragBox->HideTracking(); }
+ void UpdateDragRect();
+ DECL_LINK( SelectHdl, Accelerator* );
+
+ void StartCustomizeMode();
+ void EndCustomizeMode();
+ BOOL IsCustomizeMode() { return mbCustomizeMode; }
+ BOOL IsResizeMode() { return mbResizeMode; }
+};
+
+// -----------------------------------------------------------------------
+
+static ImplTBDragMgr* ImplGetTBDragMgr()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->maCtrlData.mpTBDragMgr )
+ pSVData->maCtrlData.mpTBDragMgr = new ImplTBDragMgr;
+ return pSVData->maCtrlData.mpTBDragMgr;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawConfigFrame( ToolBox* pThis, const Rectangle& rRect )
+{
+/*
+ Color aBlackColor( COL_BLACK );
+ Pen aOldPen;
+ Brush aOldBrush;
+ Pen aNullPen( PEN_NULL );
+
+ aOldPen = pThis->GetPen();
+ pThis->SetPen( aNullPen );
+ if ( pThis->IsSVLook() )
+ {
+ Color aFaceColor( COL_3DFACE );
+ Brush aBrush( aFaceColor, aBlackColor, BRUSH_50 );
+ aOldBrush = pThis->GetFillInBrush();
+ pThis->SetFillInBrush( aBrush );
+ }
+ else
+ {
+ Color aWhiteColor( COL_WHITE );
+ Brush aBrush( aBlackColor, aWhiteColor, BRUSH_50 );
+ aOldBrush = pThis->GetFillInBrush();
+ pThis->SetFillInBrush( aBrush );
+ }
+ pThis->DrawRect( Rectangle( rRect.Left(), rRect.Top(),
+ rRect.Right(), rRect.Top()+2 ) );
+ pThis->DrawRect( Rectangle( rRect.Left(), rRect.Top(),
+ rRect.Left()+2, rRect.Bottom() ) );
+ pThis->DrawRect( Rectangle( rRect.Left(), rRect.Bottom()-2,
+ rRect.Right(), rRect.Bottom() ) );
+ pThis->DrawRect( Rectangle( rRect.Right()-2, rRect.Top(),
+ rRect.Right(), rRect.Bottom() ) );
+
+ pThis->SetPen( aOldPen );
+ pThis->SetFillInBrush( aOldBrush );
+*/
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalcBorder( WindowAlign eAlign, long& rLeft, long& rTop,
+ long& rRight, long& rBottom )
+{
+ if ( eAlign == WINDOWALIGN_TOP )
+ {
+ rLeft = 0;
+ rTop = 2;
+ rRight = 0;
+ rBottom = 0;
+ }
+ else if ( eAlign == WINDOWALIGN_LEFT )
+ {
+ rLeft = 2;
+ rTop = 2;
+ rRight = 0;
+ rBottom = 2;
+ }
+ else if ( eAlign == WINDOWALIGN_BOTTOM )
+ {
+ rLeft = 0;
+ rTop = 0;
+ rRight = 0;
+ rBottom = 2;
+ }
+ else
+ {
+ rLeft = 0;
+ rTop = 2;
+ rRight = 2;
+ rBottom = 2;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawBorder( ToolBox* pWin )
+{
+ const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
+ long nDX = pWin->mnDX;
+ long nDY = pWin->mnDY;
+
+ if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
+ {
+ pWin->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
+ pWin->SetLineColor( rStyleSettings.GetLightColor() );
+ pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
+ }
+ else
+ {
+ pWin->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
+ pWin->SetLineColor( rStyleSettings.GetLightColor() );
+ pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
+ if ( (pWin->meAlign == WINDOWALIGN_LEFT) || (pWin->meAlign == WINDOWALIGN_RIGHT) )
+ {
+ if ( pWin->meAlign == WINDOWALIGN_LEFT )
+ {
+ pWin->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
+ pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
+ pWin->SetLineColor( rStyleSettings.GetLightColor() );
+ pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
+ pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
+ }
+ else
+ {
+ pWin->SetLineColor( rStyleSettings.GetShadowColor() );
+ pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
+ pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
+ pWin->SetLineColor( rStyleSettings.GetLightColor() );
+ pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
+ pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static Size ImplCalcSize( const ToolBox* pThis,
+ USHORT nCalcLines, USHORT nCalcMode = 0 )
+{
+ long nMax;
+ long nLeft;
+ long nTop;
+ long nRight;
+ long nBottom;
+ Size aSize;
+ WindowAlign eOldAlign;
+ BOOL bOldHorz;
+
+ // Gegebenenfalls neu durchrechnen
+ if ( nCalcMode )
+ {
+ eOldAlign = pThis->meAlign;
+ bOldHorz = pThis->mbHorz;
+
+ if ( nCalcMode == TB_CALCMODE_HORZ )
+ {
+ ImplCalcBorder( WINDOWALIGN_TOP, nLeft, nTop, nRight, nBottom );
+ ((ToolBox*)pThis)->mbHorz = TRUE;
+ if ( pThis->mbHorz != bOldHorz )
+ ((ToolBox*)pThis)->meAlign = WINDOWALIGN_TOP;
+ }
+ else if ( nCalcMode == TB_CALCMODE_FLOAT )
+ {
+ nLeft = nTop = nRight = nBottom = 0;
+ ((ToolBox*)pThis)->mbHorz = TRUE;
+ if ( pThis->mbHorz != bOldHorz )
+ ((ToolBox*)pThis)->meAlign = WINDOWALIGN_TOP;
+ }
+ else
+ {
+ ImplCalcBorder( WINDOWALIGN_LEFT, nLeft, nTop, nRight, nBottom );
+ ((ToolBox*)pThis)->mbHorz = FALSE;
+ if ( pThis->mbHorz != bOldHorz )
+ ((ToolBox*)pThis)->meAlign = WINDOWALIGN_LEFT;
+ }
+
+ if ( (pThis->meAlign != eOldAlign) || (pThis->mbHorz != bOldHorz) )
+ ((ToolBox*)pThis)->mbCalc = TRUE;
+ }
+ else
+ ImplCalcBorder( pThis->meAlign, nLeft, nTop, nRight, nBottom );
+
+ ((ToolBox*)pThis)->ImplCalcItem();
+
+ if ( pThis->mbHorz )
+ {
+ if ( pThis->mnWinHeight-2 > pThis->mnItemHeight )
+ aSize.Height() = nCalcLines * pThis->mnWinHeight-2;
+ else
+ aSize.Height() = nCalcLines * pThis->mnItemHeight;
+
+ if ( pThis->mnWinStyle & WB_LINESPACING )
+ aSize.Height() += (nCalcLines-1)*TB_LINESPACING;
+
+ if ( pThis->mnWinStyle & WB_BORDER )
+ aSize.Height() += (TB_BORDER_OFFSET2*2) + nTop + nBottom;
+
+ if ( !(pThis->mnWinStyle & WB_SCROLL) )
+ {
+ nMax = 0;
+ ((ToolBox*)pThis)->ImplCalcBreaks( TB_MAXNOSCROLL, &nMax, pThis->mbHorz );
+ if ( nMax )
+ aSize.Width() += nMax;
+
+ if ( pThis->mnWinStyle & WB_BORDER )
+ aSize.Width() += (TB_BORDER_OFFSET1*2) + nLeft + nRight;
+ }
+ }
+ else
+ {
+ aSize.Width() = nCalcLines * pThis->mnItemWidth;
+
+ if ( pThis->mnWinStyle & WB_LINESPACING )
+ aSize.Width() += (nCalcLines-1)*TB_LINESPACING;
+
+ if ( pThis->mnWinStyle & WB_BORDER )
+ aSize.Width() += (TB_BORDER_OFFSET2*2) + nLeft + nRight;
+
+ if ( !(pThis->mnWinStyle & WB_SCROLL) )
+ {
+ nMax = 0;
+ ((ToolBox*)pThis)->ImplCalcBreaks( TB_MAXNOSCROLL, &nMax, pThis->mbHorz );
+ if ( nMax )
+ aSize.Height() += nMax;
+
+ if ( pThis->mnWinStyle & WB_BORDER )
+ aSize.Height() += (TB_BORDER_OFFSET1*2) + nTop + nBottom;
+ }
+ }
+
+ // Gegebenenfalls wieder alte Werte herstellen
+ if ( nCalcMode )
+ {
+ if ( (pThis->meAlign != eOldAlign) || (pThis->mbHorz != bOldHorz) )
+ {
+ ((ToolBox*)pThis)->meAlign = eOldAlign;
+ ((ToolBox*)pThis)->mbHorz = bOldHorz;
+ ((ToolBox*)pThis)->mbCalc = TRUE;
+ }
+ }
+
+ if ( aSize.Width() )
+ aSize.Width() += pThis->mnBorderX*2;
+ if ( aSize.Height() )
+ aSize.Height() += pThis->mnBorderY*2;
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalcFloatSizes( ToolBox* pThis )
+{
+ if ( pThis->mpFloatSizeAry )
+ return;
+
+ // min. Groesse berechnen
+ long nCalcSize = pThis->mnItemWidth;
+ ImplToolItem* pItem;
+ pItem = pThis->mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbVisible )
+ {
+ if ( pItem->mpWindow )
+ {
+ long nTempSize = pItem->mpWindow->GetSizePixel().Width();
+ if ( nTempSize > nCalcSize )
+ nCalcSize = nTempSize;
+ }
+ else if ( pItem->mnNonStdSize )
+ {
+ if ( pItem->mnNonStdSize > nCalcSize )
+ nCalcSize = pItem->mnNonStdSize;
+ }
+ }
+
+ pItem = pThis->mpItemList->Next();
+ }
+
+ USHORT i;
+ USHORT nLines;
+ USHORT nCalcLines;
+ USHORT nTempLines;
+ long nHeight;
+ long nMaxLineWidth;
+ long nDesktopWidth = pThis->GetDesktopRectPixel().GetWidth()-10;
+ nCalcLines = pThis->ImplCalcBreaks( nCalcSize, &nMaxLineWidth, TRUE );
+ pThis->mpFloatSizeAry = new ImplToolSize[nCalcLines];
+ memset( pThis->mpFloatSizeAry, 0, sizeof( ImplToolSize )*nCalcLines );
+ i = 0;
+ nLines = nCalcLines;
+ while ( nLines )
+ {
+ nHeight = ImplCalcSize( pThis, nLines, TB_CALCMODE_FLOAT ).Height();
+ pThis->mpFloatSizeAry[i].mnHeight = nHeight;
+ pThis->mpFloatSizeAry[i].mnLines = nLines;
+ if ( nCalcSize >= nDesktopWidth )
+ {
+ pThis->mpFloatSizeAry[i].mnWidth = nDesktopWidth;
+ nLines--;
+ }
+ else
+ {
+ pThis->mpFloatSizeAry[i].mnWidth = nMaxLineWidth+(TB_BORDER_OFFSET1*2);
+ nLines--;
+ if ( nLines )
+ {
+ do
+ {
+ nCalcSize += pThis->mnItemWidth;
+ nTempLines = pThis->ImplCalcBreaks( nCalcSize, &nMaxLineWidth, TRUE );
+ }
+ while ( (nLines < nTempLines) && (nTempLines != 1) && (nCalcSize < nDesktopWidth) );
+ if ( nTempLines < nLines )
+ nLines = nTempLines;
+ }
+ }
+ i++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static Size ImplCalcFloatSize( ToolBox* pThis, USHORT& rLines )
+{
+ ImplCalcFloatSizes( pThis );
+
+ if ( !rLines )
+ {
+ rLines = pThis->mnFloatLines;
+ if ( !rLines )
+ rLines = pThis->mnLines;
+ }
+
+ USHORT i = 0;
+ while ( rLines < pThis->mpFloatSizeAry[i].mnLines )
+ i++;
+
+ Size aSize( pThis->mpFloatSizeAry[i].mnWidth,
+ pThis->mpFloatSizeAry[i].mnHeight );
+ rLines = pThis->mpFloatSizeAry[i].mnLines;
+ if ( pThis->maNextToolBoxStr.Len() && pThis->mbScroll )
+ aSize.Width() += TB_SPIN_SIZE-TB_SPIN_OFFSET;
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplCalcLines( ToolBox* pThis, long nToolSize )
+{
+ long nLineHeight;
+
+ if ( pThis->mbHorz )
+ {
+ if ( pThis->mnWinHeight-2 > pThis->mnItemHeight )
+ nLineHeight = pThis->mnWinHeight-2;
+ else
+ nLineHeight = pThis->mnItemHeight;
+ }
+ else
+ nLineHeight = pThis->mnItemWidth;
+
+ if ( pThis->mnWinStyle & WB_BORDER )
+ nToolSize -= TB_BORDER_OFFSET2*2;
+
+ if ( pThis->mnWinStyle & WB_LINESPACING )
+ {
+ nLineHeight += TB_LINESPACING;
+ nToolSize += TB_LINESPACING;
+ }
+
+ return (USHORT)(nToolSize/nLineHeight);
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplTestLineSize( ToolBox* pThis, const Point& rPos )
+{
+ if ( !pThis->IsFloatingMode() &&
+ (!pThis->mbScroll || (pThis->mnLines > 1) || (pThis->mnCurLines > pThis->mnVisLines)) )
+ {
+ WindowAlign eAlign = pThis->GetAlign();
+
+ if ( eAlign == WINDOWALIGN_LEFT )
+ {
+ if ( rPos.X() > pThis->mnDX-DOCK_LINEOFFSET )
+ return DOCK_LINEHSIZE | DOCK_LINERIGHT;
+ }
+ else if ( eAlign == WINDOWALIGN_TOP )
+ {
+ if ( rPos.Y() > pThis->mnDY-DOCK_LINEOFFSET )
+ return DOCK_LINEVSIZE | DOCK_LINEBOTTOM;
+ }
+ else if ( eAlign == WINDOWALIGN_RIGHT )
+ {
+ if ( rPos.X() < DOCK_LINEOFFSET )
+ return DOCK_LINEHSIZE | DOCK_LINELEFT;
+ }
+ else if ( eAlign == WINDOWALIGN_BOTTOM )
+ {
+ if ( rPos.Y() < DOCK_LINEOFFSET )
+ return DOCK_LINEVSIZE | DOCK_LINETOP;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplLineSizing( ToolBox* pThis, const Point& rPos, Rectangle& rRect,
+ USHORT nLineMode )
+{
+ BOOL mbHorz;
+ long nOneLineSize;
+ long nCurSize;
+ long nMaxSize;
+ long nSize;
+ Size aSize;
+
+ if ( nLineMode & DOCK_LINERIGHT )
+ {
+ nCurSize = rPos.X() - rRect.Left();
+ mbHorz = FALSE;
+ }
+ else if ( nLineMode & DOCK_LINEBOTTOM )
+ {
+ nCurSize = rPos.Y() - rRect.Top();
+ mbHorz = TRUE;
+ }
+ else if ( nLineMode & DOCK_LINELEFT )
+ {
+ nCurSize = rRect.Right() - rPos.X();
+ mbHorz = FALSE;
+ }
+ else if ( nLineMode & DOCK_LINETOP )
+ {
+ nCurSize = rRect.Bottom() - rPos.Y();
+ mbHorz = TRUE;
+ }
+
+ Size aWinSize = pThis->GetSizePixel();
+ USHORT nMaxLines = (pThis->mnLines > pThis->mnCurLines) ? pThis->mnLines : pThis->mnCurLines;
+ if ( nMaxLines > TB_MAXLINES )
+ nMaxLines = TB_MAXLINES;
+ if ( mbHorz )
+ {
+ nOneLineSize = ImplCalcSize( pThis, 1 ).Height();
+ nMaxSize = pThis->maOutDockRect.GetHeight() - 20;
+ if ( nMaxSize < aWinSize.Height() )
+ nMaxSize = aWinSize.Height();
+ }
+ else
+ {
+ nOneLineSize = ImplCalcSize( pThis, 1 ).Width();
+ nMaxSize = pThis->maOutDockRect.GetWidth() - 20;
+ if ( nMaxSize < aWinSize.Width() )
+ nMaxSize = aWinSize.Width();
+ }
+
+ USHORT i = 1;
+ if ( nCurSize <= nOneLineSize )
+ nSize = nOneLineSize;
+ else
+ {
+ nSize = 0;
+ while ( (nSize < nCurSize) && (i < nMaxLines) )
+ {
+ i++;
+ aSize = ImplCalcSize( pThis, i );
+ if ( mbHorz )
+ nSize = aSize.Height();
+ else
+ nSize = aSize.Width();
+ if ( nSize > nMaxSize )
+ {
+ i--;
+ aSize = ImplCalcSize( pThis, i );
+ if ( mbHorz )
+ nSize = aSize.Height();
+ else
+ nSize = aSize.Width();
+ break;
+ }
+ }
+ }
+
+ if ( nLineMode & DOCK_LINERIGHT )
+ rRect.Right() = rRect.Left()+nSize-1;
+ else if ( nLineMode & DOCK_LINEBOTTOM )
+ rRect.Bottom() = rRect.Top()+nSize-1;
+ else if ( nLineMode & DOCK_LINELEFT )
+ rRect.Left() = rRect.Right()-nSize;
+ else if ( nLineMode & DOCK_LINETOP )
+ rRect.Top() = rRect.Bottom()-nSize;
+
+ pThis->mnDockLines = i;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplFindItemPos( ToolBox* pBox, const Point& rPos )
+{
+ USHORT nPos = 0;
+ long nLast = 0;
+ Point aPos = rPos;
+ Size aSize( pBox->mnDX, pBox->mnDY );
+
+ if ( aPos.X() > aSize.Width()-TB_BORDER_OFFSET1 )
+ aPos.X() = aSize.Width()-TB_BORDER_OFFSET1;
+ if ( aPos.Y() > aSize.Height()-TB_BORDER_OFFSET1 )
+ aPos.Y() = aSize.Height()-TB_BORDER_OFFSET1;
+
+ // Item suchen, das geklickt wurde
+ ImplToolItem* pItem = pBox->mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbVisible )
+ {
+ if ( nLast || !pItem->maRect.IsEmpty() )
+ {
+ if ( pBox->mbHorz )
+ {
+ if ( nLast &&
+ ((nLast < pItem->maRect.Top()) || pItem->maRect.IsEmpty()) )
+ return nPos;
+
+ if ( aPos.Y() <= pItem->maRect.Bottom() )
+ {
+ if ( aPos.X() < pItem->maRect.Left() )
+ return nPos;
+ else if ( aPos.X() < pItem->maRect.Right() )
+ return nPos+1;
+ else if ( !nLast )
+ nLast = pItem->maRect.Bottom();
+ }
+ }
+ else
+ {
+ if ( nLast &&
+ ((nLast < pItem->maRect.Left()) || pItem->maRect.IsEmpty()) )
+ return nPos;
+
+ if ( aPos.X() <= pItem->maRect.Right() )
+ {
+ if ( aPos.Y() < pItem->maRect.Top() )
+ return nPos;
+ else if ( aPos.Y() < pItem->maRect.Bottom() )
+ return nPos+1;
+ else if ( !nLast )
+ nLast = pItem->maRect.Right();
+ }
+ }
+ }
+ }
+
+ nPos++;
+ pItem = pBox->mpItemList->Next();
+ }
+
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+ImplTBDragMgr::ImplTBDragMgr()
+{
+ mpBoxList = new ImplTBList( 4, 4 );
+ mnLineMode = 0;
+ mnStartLines = 0;
+ mbCustomizeMode = FALSE;
+ mbResizeMode = FALSE;
+ mbShowDragRect = FALSE;
+ mpDragBox = NULL;
+
+ maAccel.InsertItem( KEY_RETURN, KeyCode( KEY_RETURN ) );
+ maAccel.InsertItem( KEY_ESCAPE, KeyCode( KEY_ESCAPE ) );
+ maAccel.SetSelectHdl( LINK( this, ImplTBDragMgr, SelectHdl ) );
+}
+
+// -----------------------------------------------------------------------
+
+ImplTBDragMgr::~ImplTBDragMgr()
+{
+ delete mpBoxList;
+}
+
+// -----------------------------------------------------------------------
+
+ToolBox* ImplTBDragMgr::FindToolBox( const Rectangle& rRect )
+{
+ // ToolBox suchen
+ Point aPos = rRect.Center();
+ ToolBox* pBox = mpBoxList->First();
+ while ( pBox )
+ {
+ if ( pBox->IsReallyVisible() )
+ {
+ Window* pWindow = pBox->ImplGetFrameWindow()->FindWindow( aPos );
+ if ( pWindow && pBox->IsWindowOrChild( pWindow ) )
+ return pBox;
+ }
+ pBox = mpBoxList->Next();
+ }
+
+ // Falls so nicht gefunden wurde, suchen wir die ToolBox ueber das Rechteck
+ pBox = mpBoxList->First();
+ while ( pBox )
+ {
+ if ( pBox->IsReallyVisible() )
+ {
+ if ( pBox->IsFloatingMode() )
+ {
+ Rectangle aTempRect( pBox->GetPosPixel(), pBox->GetSizePixel() );
+ if ( aTempRect.IsOver( rRect ) )
+ return pBox;
+ }
+ }
+
+ pBox = mpBoxList->Next();
+ }
+
+ pBox = mpBoxList->First();
+ while ( pBox )
+ {
+ if ( pBox->IsReallyVisible() )
+ {
+ if ( !pBox->IsFloatingMode() )
+ {
+ Point aPos = pBox->GetPosPixel();
+ aPos = pBox->GetParent()->OutputToScreenPixel( aPos );
+ Rectangle aTempRect( aPos, pBox->GetSizePixel() );
+ if ( aTempRect.IsOver( rRect ) )
+ return pBox;
+ }
+ }
+
+ pBox = mpBoxList->Next();
+ }
+
+ return pBox;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTBDragMgr::StartDragging( ToolBox* pToolBox,
+ const Point& rPos, const Rectangle& rRect,
+ USHORT nDragLineMode, BOOL bResizeItem,
+ void* pData )
+{
+ mpDragBox = pToolBox;
+ pToolBox->CaptureMouse();
+ pToolBox->mbDragging = TRUE;
+ Application::InsertAccel( &maAccel );
+
+ if ( nDragLineMode )
+ {
+ mnLineMode = nDragLineMode;
+ mnStartLines = pToolBox->mnDockLines;
+ }
+ else
+ {
+ mpCustomizeData = pData;
+ mbResizeMode = bResizeItem;
+ pToolBox->Activate();
+ pToolBox->mnCurItemId = pToolBox->mnConfigItem;
+ pToolBox->Highlight();
+ pToolBox->mnCurItemId = 0;
+ if ( !mbResizeMode )
+ ImplDrawConfigFrame( pToolBox, rRect );
+ else
+ {
+ if ( rRect.GetWidth() < TB_MIN_WIN_WIDTH )
+ mnMinWidth = rRect.GetWidth();
+ else
+ mnMinWidth = TB_MIN_WIN_WIDTH;
+ mnMaxWidth = pToolBox->GetSizePixel().Width()-rRect.Left()-
+ TB_SPIN_SIZE-TB_BORDER_OFFSET1-(TB_SPIN_OFFSET*2);
+ }
+ }
+
+ // MouseOffset berechnen
+ maMouseOff.X() = rRect.Left() - rPos.X();
+ maMouseOff.Y() = rRect.Top() - rPos.Y();
+ maRect = rRect;
+ maStartRect = rRect;
+ mbShowDragRect = TRUE;
+ pToolBox->ShowTracking( maRect );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTBDragMgr::Dragging( const Point& rPos )
+{
+ if ( mnLineMode )
+ {
+ ImplLineSizing( mpDragBox, rPos, maRect, mnLineMode );
+ Point aPos = mpDragBox->OutputToScreenPixel( rPos );
+ Point aOff = mpDragBox->OutputToScreenPixel( Point() );
+ maRect.Move( aOff.X(), aOff.Y() );
+ mpDragBox->Docking( rPos, maRect );
+ maRect.Move( -aOff.X(), -aOff.Y() );
+ mpDragBox->ShowTracking( maRect );
+ }
+ else
+ {
+ if ( mbResizeMode )
+ {
+ long nXOff = rPos.X()-maStartRect.Left();
+ nXOff += maMouseOff.X()+(maStartRect.Right()-maStartRect.Left());
+ if ( nXOff < mnMinWidth )
+ nXOff = mnMinWidth;
+ if ( nXOff > mnMaxWidth )
+ nXOff = mnMaxWidth;
+ maRect.Right() = maStartRect.Left()+nXOff;
+ }
+ else
+ {
+ maRect.SetPos( rPos );
+ maRect.Move( maMouseOff.X(), maMouseOff.Y() );
+ }
+ mpDragBox->ShowTracking( maRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTBDragMgr::EndDragging( BOOL bOK )
+{
+ mpDragBox->HideTracking();
+ mpDragBox->ReleaseMouse();
+ mpDragBox->mbDragging = FALSE;
+ mbShowDragRect = FALSE;
+ Application::RemoveAccel( &maAccel );
+
+ if ( mnLineMode )
+ {
+ if ( !bOK )
+ {
+ mpDragBox->mnDockLines = mnStartLines;
+ mpDragBox->EndDocking( maStartRect, FALSE );
+ }
+ else
+ mpDragBox->EndDocking( maRect, FALSE );
+ mnLineMode = 0;
+ mnStartLines = 0;
+ }
+ else
+ {
+ USHORT nTempItem = mpDragBox->mnConfigItem;
+ if ( nTempItem )
+ {
+ mpDragBox->mnConfigItem = 0;
+ if ( !mbResizeMode )
+ mpDragBox->Invalidate( mpDragBox->GetItemRect( nTempItem ) );
+ }
+
+ if ( bOK && (maRect != maStartRect) )
+ {
+ if ( mbResizeMode )
+ {
+ ImplToolItem* pItem = mpDragBox->ImplGetItem( nTempItem );
+ Size aSize = pItem->mpWindow->GetSizePixel();
+ aSize.Width() = maRect.GetWidth();
+ pItem->mpWindow->SetSizePixel( aSize );
+
+ // ToolBox neu brechnen und neu ausgeben
+ mpDragBox->ImplInvalidate( TRUE );
+ mpDragBox->Customize( ToolBoxCustomizeEvent( mpDragBox, nTempItem,
+ TOOLBOX_CUSTOMIZE_RESIZE,
+ mpCustomizeData ) );
+ }
+ else
+ {
+ Point aOff = mpDragBox->OutputToScreenPixel( Point() );
+ Rectangle aScreenRect( maRect );
+ aScreenRect.Move( aOff.X(), aOff.Y() );
+ ToolBox* pDropBox = FindToolBox( aScreenRect );
+ if ( pDropBox )
+ {
+ // Such-Position bestimmen
+ Point aPos;
+ if ( pDropBox->mbHorz )
+ {
+ aPos.X() = aScreenRect.Left()-TB_CUSTOMIZE_OFFSET;
+ aPos.Y() = aScreenRect.Center().Y();
+ }
+ else
+ {
+ aPos.X() = aScreenRect.Center().X();
+ aPos.Y() = aScreenRect.Top()-TB_CUSTOMIZE_OFFSET;
+ }
+
+ aPos = pDropBox->ScreenToOutputPixel( aPos );
+ USHORT nPos = ImplFindItemPos( pDropBox, aPos );
+ mpDragBox->Customize( ToolBoxCustomizeEvent( pDropBox, nTempItem,
+ nPos, mpCustomizeData ) );
+ }
+ else
+ {
+ mpDragBox->Customize( ToolBoxCustomizeEvent( NULL, nTempItem,
+ 0, mpCustomizeData ) );
+ }
+ }
+ }
+ mpCustomizeData = NULL;
+ mbResizeMode = FALSE;
+ mpDragBox->Deactivate();
+ }
+
+ mpDragBox = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTBDragMgr::UpdateDragRect()
+{
+ // Nur Updaten, wenn wir schon im Dragging sind
+ if ( !mbShowDragRect )
+ return;
+
+ if ( !mbResizeMode )
+ ImplDrawConfigFrame( mpDragBox, maStartRect );
+
+ mpDragBox->ShowTracking( maRect );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ImplTBDragMgr, SelectHdl, Accelerator*, pAccel )
+{
+ if ( pAccel->GetCurItemId() == KEY_ESCAPE )
+ EndDragging( FALSE );
+ else
+ EndDragging( TRUE );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTBDragMgr::StartCustomizeMode()
+{
+ mbCustomizeMode = TRUE;
+
+ ToolBox* pBox = mpBoxList->First();
+ while ( pBox )
+ {
+ pBox->ImplStartCustomizeMode();
+ pBox = mpBoxList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTBDragMgr::EndCustomizeMode()
+{
+ mbCustomizeMode = FALSE;
+
+ ToolBox* pBox = mpBoxList->First();
+ while ( pBox )
+ {
+ pBox->ImplEndCustomizeMode();
+ pBox = mpBoxList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static ImplButtonList* ImplGetButtonList()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->maCtrlData.mpButtonList )
+ pSVData->maCtrlData.mpButtonList = new ImplButtonList;
+ return pSVData->maCtrlData.mpButtonList;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawOutButton( OutputDevice* pOutDev, const Rectangle& rRect,
+ USHORT nStyle )
+{
+ const StyleSettings& rStyleSettings = pOutDev->GetSettings().GetStyleSettings();
+ Color aShadowColor = rStyleSettings.GetShadowColor();
+ Point aPos( rRect.TopLeft() );
+ Size aSize( rRect.GetSize() );
+ long nOffset = 0;
+
+ if ( pOutDev->GetBackground().GetColor() == aShadowColor )
+ aShadowColor = rStyleSettings.GetDarkShadowColor();
+
+ if ( nStyle & BUTTON_DRAW_PRESSED )
+ {
+ aPos.X()++;
+ aPos.Y()++;
+ nOffset++;
+ }
+
+ // Hintergrund loeschen
+ pOutDev->Erase( rRect );
+
+ // Button zeichnen
+ pOutDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pOutDev->DrawLine( aPos,
+ Point( aPos.X()+aSize.Width()-OUTBUTTON_BORDER, aPos.Y() ) );
+ pOutDev->DrawLine( aPos,
+ Point( aPos.X(), aPos.Y()+aSize.Height()-OUTBUTTON_BORDER ) );
+ pOutDev->SetLineColor( aShadowColor );
+ pOutDev->DrawLine( Point( aPos.X()+aSize.Width()-OUTBUTTON_BORDER, aPos.Y() ),
+ Point( aPos.X()+aSize.Width()-OUTBUTTON_BORDER, aPos.Y()+aSize.Height()-OUTBUTTON_BORDER ) );
+ pOutDev->DrawLine( Point( aPos.X(), aPos.Y()+aSize.Height()-OUTBUTTON_BORDER ),
+ Point( aPos.X()+aSize.Width()-OUTBUTTON_BORDER, aPos.Y()+aSize.Height()-OUTBUTTON_BORDER ) );
+ for ( long i = 0; i < OUTBUTTON_BORDER-1-nOffset; i++ )
+ {
+ pOutDev->DrawLine( Point( aPos.X()+aSize.Width()-(OUTBUTTON_BORDER-i-1), aPos.Y()+OUTBUTTON_BORDER ),
+ Point( aPos.X()+aSize.Width()-(OUTBUTTON_BORDER-i-1), aPos.Y()+aSize.Height()-1 ) );
+ pOutDev->DrawLine( Point( aPos.X()+OUTBUTTON_BORDER, aPos.Y()+aSize.Height()-(OUTBUTTON_BORDER-i-1) ),
+ Point( aPos.X()+aSize.Width()-1, aPos.Y()+aSize.Height()-(OUTBUTTON_BORDER-i-1) ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplInitButtonVirDev( const Window* pBox, VirtualDevice* pVirDev )
+{
+ // Farben/Settings vom Window am virtuellen Device setzen
+ pVirDev->SetSettings( pBox->GetSettings() );
+ const Wallpaper& rWallpaper = pBox->GetBackground();
+ if ( rWallpaper.GetStyle() == WALLPAPER_NULL )
+ pVirDev->SetBackground( Wallpaper( pBox->GetSettings().GetStyleSettings().GetFaceColor() ) );
+ else
+ pVirDev->SetBackground( rWallpaper );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawButtons( VirtualDevice* pVirDev, long nWidth, long nHeight,
+ USHORT nType )
+{
+ // Button Frames ausgeben
+ long nY = 0;
+ if ( nType & TOOLBOX_STYLE_OUTBUTTON )
+ {
+ for ( USHORT i = 0; i < 6; i++ )
+ {
+ USHORT nStyle = 0;
+ if ( i & 0x01 )
+ nStyle = BUTTON_DRAW_PRESSED;
+ ImplDrawOutButton( pVirDev, Rectangle( 0, nY, nWidth-1, nY+nHeight-1 ), nStyle );
+ nY += nHeight;
+ }
+ }
+ else
+ {
+ DecorationView aDecoView( pVirDev );
+
+ aDecoView.DrawButton( Rectangle( 0, 0, nWidth-1, nHeight-1 ), 0 );
+ nY += nHeight;
+ aDecoView.DrawButton( Rectangle( 0, nY, nWidth-1, nY+nHeight-1 ),
+ BUTTON_DRAW_PRESSED );
+ nY += nHeight;
+ aDecoView.DrawButton( Rectangle( 0, nY, nWidth-1, nY+nHeight-1 ),
+ BUTTON_DRAW_CHECKED );
+ nY += nHeight;
+ aDecoView.DrawButton( Rectangle( 0, nY, nWidth-1, nY+nHeight-1 ),
+ BUTTON_DRAW_CHECKED | BUTTON_DRAW_PRESSED );
+ nY += nHeight;
+ aDecoView.DrawButton( Rectangle( 0, nY, nWidth-1, nY+nHeight-1 ),
+ BUTTON_DRAW_DONTKNOW );
+ nY += nHeight;
+ aDecoView.DrawButton( Rectangle( 0, nY, nWidth-1, nY+nHeight-1 ),
+ BUTTON_DRAW_DONTKNOW | BUTTON_DRAW_PRESSED );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplButtonSysChange( ToolBox* pBox, VirtualDevice* pVirDev, USHORT nType )
+{
+ ImplButtonList* pBtnList = ImplGetButtonList();
+ ImplButtonData* pBtnData;
+
+ pBtnData = pBtnList->First();
+ while ( pBtnData )
+ {
+ if ( pBtnData->mpBtnDev == pVirDev )
+ {
+ ImplInitButtonVirDev( pBox, pVirDev );
+ ImplDrawButtons( pVirDev, pBtnData->mnWidth, pBtnData->mnHeight, nType );
+ break;
+ }
+
+ pBtnData = pBtnList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static VirtualDevice* ImplGetButtonDevice( ToolBox* pBox,
+ long nWidth, long nHeight, USHORT nType )
+{
+ ImplButtonList* pBtnList = ImplGetButtonList();
+ ImplButtonData* pBtnData;
+
+ pBtnData = pBtnList->First();
+ while ( pBtnData )
+ {
+ if ( (pBtnData->mnWidth == nWidth) &&
+ (pBtnData->mnHeight == nHeight) )
+ {
+ pBtnData->mnRefCount++;
+ return pBtnData->mpBtnDev;
+ }
+
+ pBtnData = pBtnList->Next();
+ }
+
+ VirtualDevice* pVirDev = new VirtualDevice( *pBox );
+
+ // Neue Groesse vom virtuellen Device setzen
+ pVirDev->SetOutputSizePixel( Size( nWidth, nHeight*6 ), TRUE );
+ ImplInitButtonVirDev( pBox, pVirDev );
+ ImplDrawButtons( pVirDev, nWidth, nHeight, nType );
+
+ pBtnData = new ImplButtonData;
+ pBtnData->mpBtnDev = pVirDev;
+ pBtnData->mnWidth = nWidth;
+ pBtnData->mnHeight = nHeight;
+ pBtnData->mnRefCount = 1;
+ pBtnList->Insert( pBtnData, LIST_APPEND );
+
+ return pVirDev;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplFreeButtonDevice( VirtualDevice* pVirDev )
+{
+ ImplButtonList* pBtnList = ImplGetButtonList();
+ ImplButtonData* pBtnData;
+
+ // Virtuelles Device suchen und loeschen
+ pBtnData = pBtnList->First();
+ while ( pBtnData )
+ {
+ if ( pBtnData->mpBtnDev == pVirDev )
+ {
+ pBtnData->mnRefCount--;
+ if ( !pBtnData->mnRefCount )
+ {
+ delete pBtnData->mpBtnDev;
+ delete pBtnData;
+ pBtnList->Remove();
+ }
+
+ return;
+ }
+
+ pBtnData = pBtnList->Next();
+ }
+
+ DBG_ERRORFILE( "ImplFreeButtonDevice(): Button-Device not in list" );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplInit( Window* pParent, WinBits nStyle )
+{
+ // Variablen initialisieren
+ mpBtnDev = NULL;
+ mpFloatSizeAry = NULL;
+ mpItemList = new ImplToolItemList;
+ mpFloatWin = NULL;
+ mnDX = 0;
+ mnDY = 0;
+ mnItemWidth = 0;
+ mnItemHeight = 0;
+ mnWinHeight = 0;
+ mnBorderX = 0;
+ mnBorderY = 0;
+ mnLeftBorder = 0;
+ mnTopBorder = 0;
+ mnRightBorder = 0;
+ mnBottomBorder = 0;
+ mnLastResizeDY = 0;
+ mnOutStyle = 0;
+ mnHighItemId = 0;
+ mnCurItemId = 0;
+ mnDownItemId = 0;
+ mnCurPos = TOOLBOX_ITEM_NOTFOUND;
+ mnLines = 1;
+ mnCurLine = 1;
+ mnCurLines = 1;
+ mnVisLines = 1;
+ mnFloatLines = 0;
+ mnConfigItem = 0;
+ mnMouseClicks = 0;
+ mnMouseModifier = 0;
+ mbDrag = FALSE;
+ mbSelection = FALSE;
+ mbCommandDrag = FALSE;
+ mbUpper = FALSE;
+ mbLower = FALSE;
+ mbNextTool = FALSE;
+ mbIn = FALSE;
+ mbCalc = TRUE;
+ mbFormat = FALSE;
+ mbFullPaint = FALSE;
+ mbHorz = TRUE;
+ mbScroll = (nStyle & WB_SCROLL) != 0;
+ mbCustomize = FALSE;
+ mbCustomizeMode = FALSE;
+ mbDragging = FALSE;
+ mbHideStatusText = FALSE;
+ mbMenuStrings = FALSE;
+ meButtonType = BUTTON_SYMBOL;
+ meAlign = WINDOWALIGN_TOP;
+ meLastStyle = POINTER_ARROW;
+ mnWinStyle = nStyle;
+ maTimer.SetTimeoutHdl( LINK( this, ToolBox, ImplUpdateHdl ) );
+
+ DockingWindow::ImplInit( pParent, nStyle & ~(WB_BORDER) );
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont = rStyleSettings.GetToolFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else if ( Window::GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetButtonTextColor();
+ else
+ aColor = rStyleSettings.GetWindowTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else if ( Window::GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetFaceColor();
+ else
+ aColor = rStyleSettings.GetWindowColor();
+ SetBackground( aColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplLoadRes( const ResId& rResId )
+{
+ DockingWindow::ImplLoadRes( rResId );
+
+ USHORT nObjMask;
+
+ nObjMask = ReadShortRes();
+
+ if ( nObjMask & RSC_TOOLBOX_BUTTONTYPE )
+ SetButtonType( (ButtonType)ReadShortRes() );
+
+ if ( nObjMask & RSC_TOOLBOX_ALIGN )
+ SetAlign( (WindowAlign)ReadShortRes() );
+
+ if ( nObjMask & RSC_TOOLBOX_LINECOUNT )
+ SetLineCount( ReadShortRes() );
+
+ if ( nObjMask & RSC_TOOLBOX_CUSTOMIZE )
+ {
+ BOOL bCust = (BOOL)ReadShortRes();
+ EnableCustomize( bCust );
+ }
+
+ if ( nObjMask & RSC_TOOLBOX_MENUSTRINGS )
+ {
+ BOOL bCust = (BOOL)ReadShortRes();
+ EnableMenuStrings( bCust );
+ }
+
+ if ( nObjMask & RSC_TOOLBOX_FLOATLINES )
+ SetFloatingLines( ReadShortRes() );
+
+ if ( nObjMask & RSC_TOOLBOX_ITEMIMAGELIST )
+ {
+ maImageList = ImageList( ResId( (RSHEADER_TYPE*)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ }
+
+ if ( nObjMask & RSC_TOOLBOX_ITEMLIST )
+ {
+ USHORT nEle = ReadShortRes();
+
+ // Item hinzufuegen
+ for ( USHORT i = 0; i < nEle; i++ )
+ {
+ InsertItem( ResId( (RSHEADER_TYPE *)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ToolBox::ToolBox( Window* pParent, WinBits nStyle ) :
+ DockingWindow( WINDOW_TOOLBOX )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+ToolBox::ToolBox( Window* pParent, const ResId& rResId ) :
+ DockingWindow( WINDOW_TOOLBOX )
+{
+ rResId.SetRT( RSC_TOOLBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ // Groesse des FloatingWindows berechnen und umschalten, wenn die
+ // ToolBox initial im FloatingModus ist
+ if ( IsFloatingMode() )
+ mbHorz = TRUE;
+ else
+ Resize();
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+ToolBox::~ToolBox()
+{
+ // Falls noch ein Floating-Window connected ist, dann den
+ // PopupModus beenden
+ if ( mpFloatWin )
+ mpFloatWin->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
+
+ // Items aus der Liste loeschen
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Itemlist loeschen
+ delete mpItemList;
+
+ // FloatSizeAry gegebenenfalls loeschen
+ if ( mpFloatSizeAry )
+ delete mpFloatSizeAry;
+
+ // Wenn keine ToolBox-Referenzen mehr auf die Listen bestehen, dann
+ // Listen mit wegloeschen
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maCtrlData.mpTBDragMgr )
+ {
+ // Wenn im TBDrag-Manager, dann wieder rausnehmen
+ if ( mbCustomize )
+ pSVData->maCtrlData.mpTBDragMgr->Remove( this );
+
+ if ( !pSVData->maCtrlData.mpTBDragMgr->Count() )
+ {
+ delete pSVData->maCtrlData.mpTBDragMgr;
+ pSVData->maCtrlData.mpTBDragMgr = NULL;
+ }
+ }
+
+ // Button-Device freigeben
+ if ( mpBtnDev )
+ ImplFreeButtonDevice( mpBtnDev );
+
+ if ( pSVData->maCtrlData.mpButtonList )
+ {
+ if ( !pSVData->maCtrlData.mpButtonList->Count() )
+ {
+ delete pSVData->maCtrlData.mpButtonList;
+ pSVData->maCtrlData.mpButtonList = NULL;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ImplToolItem* ToolBox::ImplGetItem( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nItemId )
+ return pItem;
+
+ pItem = mpItemList->Next();
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ToolBox::ImplCalcItem()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ // Muss Itemgroesse ueberhaupt neu berechnet werden
+ if ( !mbCalc )
+ return FALSE;
+
+ ImplToolItem* pItem;
+ long nDefWidth;
+ long nDefHeight;
+ long nDefLeftWidth;
+ long nDefLeftHeight;
+ long nMaxWidth;
+ long nMaxHeight;
+ long nHeight;
+ BOOL bImage;
+ BOOL bText;
+ Size aItemSize;
+
+ if ( meButtonType == BUTTON_SYMBOL )
+ {
+ nDefWidth = DEF_IMAGE_WIDTH;
+ nDefHeight = DEF_IMAGE_HEIGHT;
+ nDefLeftWidth = nDefWidth;
+ nDefLeftHeight = nDefHeight;
+ }
+ else if ( meButtonType == BUTTON_TEXT )
+ {
+ nDefWidth = DEF_TEXT_WIDTH;
+ nDefHeight = GetTextHeight();
+ nDefLeftWidth = nDefWidth;
+ nDefLeftHeight = nDefHeight;
+ }
+ else
+ {
+ nDefWidth = DEF_TEXT_WIDTH;
+ nDefHeight = DEF_IMAGE_HEIGHT + GetTextHeight();
+ nDefLeftWidth = nDefWidth;
+ nDefLeftHeight = nDefHeight-DEF_IMAGE_HEIGHT;
+ }
+
+ if ( mpItemList->Count() )
+ {
+ nMaxWidth = DEF_MIN_WIDTH;
+ nMaxHeight = DEF_MIN_HEIGHT;
+ mnWinHeight = 0;
+
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->meType == TOOLBOXITEM_BUTTON )
+ {
+ if ( !(pItem->maImage) )
+ bImage = FALSE;
+ else
+ bImage = TRUE;
+ if ( !pItem->maText.Len() )
+ bText = FALSE;
+ else
+ bText = TRUE;
+
+ if ( bImage || bText )
+ {
+ pItem->mbEmptyBtn = FALSE;
+
+ if ( meButtonType == BUTTON_SYMBOL )
+ {
+ if ( bImage || !bText )
+ {
+ aItemSize = pItem->maImage.GetSizePixel();
+ pItem->mnNonStdSize = 0;
+ }
+ else
+ {
+ aItemSize.Width() = 0;
+ aItemSize.Height() = GetTextHeight();
+ pItem->mnNonStdSize = GetCtrlTextWidth( pItem->maText )+TB_TEXTOFFSET;
+ }
+ }
+ else if ( meButtonType == BUTTON_TEXT )
+ {
+ if ( bText || !bImage )
+ {
+ aItemSize.Width() = GetCtrlTextWidth( pItem->maText )+TB_TEXTOFFSET;
+ aItemSize.Height() = GetTextHeight();
+ pItem->mnNonStdSize = 0;
+ }
+ else
+ {
+ Size aImageSize = pItem->maImage.GetSizePixel();
+ if ( mbHorz )
+ {
+ aItemSize.Width() = 0;
+ aItemSize.Height() = aImageSize.Height();
+ pItem->mnNonStdSize = aImageSize.Width();
+ }
+ else
+ {
+ aItemSize.Width() = aImageSize.Width();
+ aItemSize.Height() = 0;
+ pItem->mnNonStdSize = aImageSize.Height();
+ }
+ }
+ }
+ else
+ {
+ aItemSize.Width() = GetCtrlTextWidth( pItem->maText )+TB_TEXTOFFSET;
+ aItemSize.Height() = GetTextHeight();
+ Size aImageSize = pItem->maImage.GetSizePixel();
+ if ( pItem->mnBits & TIB_LEFT )
+ {
+ aItemSize.Width() += aImageSize.Width();
+ if ( aImageSize.Height() > aItemSize.Height() )
+ aItemSize.Height() = aImageSize.Height();
+ }
+ else
+ {
+ aItemSize.Height() += aImageSize.Height();
+ if ( aImageSize.Width() > aItemSize.Width() )
+ aItemSize.Width() = aImageSize.Width();
+ }
+ pItem->mnNonStdSize = 0;
+ }
+
+ if ( !pItem->mnNonStdSize && (pItem->mnBits & TIB_AUTOSIZE) )
+ {
+ pItem->mnNonStdSize = aItemSize.Width();
+ aItemSize.Width() = 0;
+ }
+ }
+ else
+ {
+ if ( pItem->mnBits & TIB_LEFT )
+ {
+ aItemSize.Width() = nDefLeftWidth;
+ aItemSize.Height() = nDefLeftHeight;
+ }
+ else
+ {
+ aItemSize.Width() = nDefWidth;
+ aItemSize.Height() = nDefHeight;
+ }
+ pItem->mbEmptyBtn = TRUE;
+ }
+
+ if ( aItemSize.Width() > nMaxWidth )
+ nMaxWidth = aItemSize.Width();
+ if ( aItemSize.Height() > nMaxHeight )
+ nMaxHeight = aItemSize.Height();
+
+ if ( pItem->mnNonStdSize )
+ {
+ if ( mbHorz )
+ pItem->mnNonStdSize += SMALLBUTTON_HSIZE;
+ else
+ pItem->mnNonStdSize += SMALLBUTTON_VSIZE;
+ }
+
+ // Gegebenenfalls die Fensterhoehe mit beruecksichtigen
+ if ( pItem->mpWindow )
+ {
+ nHeight = pItem->mpWindow->GetSizePixel().Height();
+ if ( nHeight > mnWinHeight )
+ mnWinHeight = nHeight;
+ }
+ }
+
+ pItem = mpItemList->Next();
+ }
+ }
+ else
+ {
+ nMaxWidth = nDefWidth;
+ nMaxHeight = nDefHeight;
+ }
+
+ mbCalc = FALSE;
+ mbFormat = TRUE;
+
+ // Button-Umrandung dazurechnen
+ if ( mnOutStyle & TOOLBOX_STYLE_OUTBUTTON )
+ {
+ nMaxWidth += OUTBUTTON_SIZE;
+ nMaxHeight += OUTBUTTON_SIZE;
+ }
+ else
+ {
+ nMaxWidth += SMALLBUTTON_HSIZE;
+ nMaxHeight += SMALLBUTTON_VSIZE;
+ }
+
+ // Muessen die groessen neu berechnet werden
+ if ( (nMaxWidth != mnItemWidth) || (nMaxHeight != mnItemHeight) )
+ {
+ // Neue Werte zuweisen
+ mnItemWidth = nMaxWidth;
+ mnItemHeight = nMaxHeight;
+
+ // Button-Device freigeben
+ if ( mpBtnDev )
+ {
+ ImplFreeButtonDevice( mpBtnDev );
+ mpBtnDev = NULL;
+ }
+ if ( !(mnOutStyle & TOOLBOX_STYLE_FLAT) )
+ mpBtnDev = ImplGetButtonDevice( this, mnItemWidth, mnItemHeight, mnOutStyle );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ToolBox::ImplCalcBreaks( long nWidth, long* pMaxLineWidth, BOOL bCalcHorz )
+{
+ ImplToolItem* pItem;
+ ULONG nLineStart = 0;
+ ULONG nGroupStart = 0;
+ long nLineWidth = 0;
+ long nCurWidth;
+ long nLastGroupLineWidth = 0;
+ long nMaxLineWidth = 0;
+ USHORT nLines = 1;
+ BOOL bWindow;
+ BOOL bBreak = FALSE;
+
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ pItem->mbBreak = bBreak;
+ bBreak = FALSE;
+
+ if ( pItem->mbVisible )
+ {
+ bWindow = FALSE;
+ bBreak = FALSE;
+ nCurWidth = 0;
+
+ if ( pItem->meType == TOOLBOXITEM_BUTTON )
+ {
+ if ( pItem->mnNonStdSize )
+ nCurWidth = pItem->mnNonStdSize;
+ else
+ {
+ if ( bCalcHorz )
+ nCurWidth = mnItemWidth;
+ else
+ nCurWidth = mnItemHeight;
+ }
+
+ if ( pItem->mpWindow && bCalcHorz )
+ {
+ long nWinItemWidth = pItem->mpWindow->GetSizePixel().Width();
+ if ( !mbScroll || (nWinItemWidth <= nWidth) )
+ {
+ nCurWidth = nWinItemWidth;
+ bWindow = TRUE;
+ }
+ else
+ {
+ if ( pItem->mbEmptyBtn )
+ {
+ nCurWidth = 0;
+ }
+ }
+ }
+
+ if ( (nLineWidth+nCurWidth > nWidth) && mbScroll )
+ bBreak = TRUE;
+ }
+ else if ( pItem->meType == TOOLBOXITEM_SPACE )
+ nCurWidth = mnItemWidth;
+ else if ( pItem->meType == TOOLBOXITEM_SEPARATOR )
+ nCurWidth = pItem->mnSepSize;
+ else if ( pItem->meType == TOOLBOXITEM_BREAK )
+ bBreak = TRUE;
+
+ if ( bBreak )
+ {
+ nLines++;
+
+ // Gruppe auseinanderbrechen oder ganze Gruppe umbrechen?
+ if ( (pItem->meType == TOOLBOXITEM_BREAK) ||
+ (nLineStart == nGroupStart) )
+ {
+ if ( nLineWidth > nMaxLineWidth )
+ nMaxLineWidth = nLineWidth;
+
+ nLineWidth = 0;
+ nLineStart = mpItemList->GetCurPos();
+ nGroupStart = nLineStart;
+ pItem->mbBreak = TRUE;
+ bBreak = FALSE;
+ }
+ else
+ {
+ if ( nLastGroupLineWidth > nMaxLineWidth )
+ nMaxLineWidth = nLastGroupLineWidth;
+
+ // Wenn ganze Gruppe umgebrochen wird, diese auf
+ // Zeilenanfang setzen und wieder neu berechnen
+ nLineWidth = 0;
+ nLineStart = nGroupStart;
+ pItem = mpItemList->Seek( nGroupStart );
+ continue;
+ }
+ }
+ else
+ {
+ if ( (pItem->meType != TOOLBOXITEM_BUTTON) || bWindow )
+ {
+ nLastGroupLineWidth = nLineWidth;
+ nGroupStart = mpItemList->GetCurPos();
+ if ( !bWindow )
+ nGroupStart++;
+ }
+ }
+
+ nLineWidth += nCurWidth;
+ }
+
+ pItem = mpItemList->Next();
+ }
+
+ if ( pMaxLineWidth )
+ {
+ if ( nLineWidth > nMaxLineWidth )
+ nMaxLineWidth = nLineWidth;
+ // Wegen Separatoren kann MaxLineWidth > Width werden, hat aber
+ // auf die Umbrueche keine Auswirkung
+ if ( nMaxLineWidth > nWidth )
+ nMaxLineWidth = nWidth;
+ *pMaxLineWidth = nMaxLineWidth;
+ }
+
+ return nLines;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplFormat( BOOL bResize )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ // Muss ueberhaupt neu formatiert werden
+ if ( !mbFormat )
+ return;
+
+ // Positionen/Groessen berechnen
+ Rectangle aEmptyRect;
+ ImplToolItem* pItem;
+ ImplToolItem* pTempItem;
+ long nLineSize;
+ long nLeft;
+ long nTop;
+ long nMax;
+ long nX;
+ long nY;
+ long nCurWidth;
+ long nCurHeight;
+ USHORT nFormatLine;
+ BOOL bMustFullPaint;
+ BOOL bLastSep;
+
+ // FloatSizeAry gegebenenfalls loeschen
+ if ( mpFloatSizeAry )
+ {
+ delete mpFloatSizeAry;
+ mpFloatSizeAry = NULL;
+ }
+
+ // Borderbreite berechnen
+ if ( IsFloatingMode() || !(mnWinStyle & WB_BORDER) )
+ {
+ mnLeftBorder = 0;
+ mnTopBorder = 0;
+ mnRightBorder = 0;
+ mnBottomBorder = 0;
+ }
+ else
+ ImplCalcBorder( meAlign, mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder );
+
+ // Itemgroesse gegebenenfalls neu berechnet werden
+ if ( ImplCalcItem() )
+ bMustFullPaint = TRUE;
+ else
+ bMustFullPaint = FALSE;
+
+ // Im FloatingMode die Fenstergroesse immer neu setzen oder im Resize
+ // die neue Anzahl der FloatingLines berechnen
+ if ( IsFloatingMode() )
+ {
+ if ( bResize )
+ mnFloatLines = ImplCalcLines( this, mnDY );
+ else
+ SetOutputSizePixel( ImplCalcFloatSize( this, mnFloatLines ) );
+ }
+
+ // Horizontal
+ if ( mbHorz )
+ {
+ nLineSize = mnItemHeight;
+
+ if ( mnWinHeight-2 > mnItemHeight )
+ nLineSize = mnWinHeight-2;
+
+ if ( mbScroll )
+ {
+ mnVisLines = ImplCalcLines( this, mnDY );
+ nMax = mnDX;
+ }
+ else
+ {
+ mnVisLines = mnLines;
+ nMax = TB_MAXNOSCROLL;
+ }
+
+ if ( mnWinStyle & WB_BORDER )
+ {
+ nLeft = TB_BORDER_OFFSET1 + mnLeftBorder;
+ nTop = TB_BORDER_OFFSET2 + mnTopBorder;
+ nMax -= nLeft + TB_BORDER_OFFSET1 + mnRightBorder;
+ }
+ else
+ {
+ nLeft = 0;
+ nTop = 0;
+ }
+
+ nLeft += mnBorderX;
+ nTop += mnBorderY;
+ nMax -= mnBorderX*2;
+ }
+ else
+ {
+ nLineSize = mnItemWidth;
+
+ if ( mbScroll )
+ {
+ mnVisLines = ImplCalcLines( this, mnDX );
+ nMax = mnDY;
+ }
+ else
+ {
+ mnVisLines = mnLines;
+ nMax = TB_MAXNOSCROLL;
+ }
+
+ if ( mnWinStyle & WB_BORDER )
+ {
+ nTop = TB_BORDER_OFFSET1 + mnTopBorder;
+ nLeft = TB_BORDER_OFFSET2 + mnLeftBorder;
+ nMax -= nTop + TB_BORDER_OFFSET1 + mnBottomBorder;
+ }
+ else
+ {
+ nLeft = 0;
+ nTop = 0;
+ }
+
+ nLeft += mnBorderX;
+ nTop += mnBorderY;
+ nMax -= mnBorderY*2;
+ }
+
+ // Wenn Fenster keine Groesse hat, dann nichts berechnen. Fuer alle
+ // ToolBoxen ohne Scroll muss hier schon die Groesse berechnet werden.
+ if ( (nMax <= 0) && mbScroll )
+ {
+ mnVisLines = 1;
+ mnCurLine = 1;
+ mnCurLines = 1;
+
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ pItem->maRect = aEmptyRect;
+ pItem = mpItemList->Next();
+ }
+
+ maLowerRect = aEmptyRect;
+ maUpperRect = aEmptyRect;
+ maNextToolRect = aEmptyRect;
+ }
+ else
+ {
+ // Anfangswerte setzen
+ nX = nLeft;
+ nY = nTop;
+ nFormatLine = 1;
+ bLastSep = TRUE;
+
+ // Scroll-Rectangles merken und zuruecksetzen
+ Rectangle aOldLowerRect = maLowerRect;
+ Rectangle aOldUpperRect = maUpperRect;
+ Rectangle aOldNextToolRect = maNextToolRect;
+ maUpperRect = aEmptyRect;
+ maLowerRect = aEmptyRect;
+ maNextToolRect = aEmptyRect;
+
+ if ( maNextToolBoxStr.Len() && mbScroll )
+ {
+ nMax -= TB_SPIN_SIZE-TB_SPIN_OFFSET;
+ if ( mbHorz )
+ {
+ maNextToolRect.Left() = nLeft+nMax+TB_SPIN_OFFSET;
+ maNextToolRect.Right() = maNextToolRect.Left()+TB_SPIN_SIZE-1;
+ maNextToolRect.Top() = nTop;
+ maNextToolRect.Bottom() = mnDY-mnBottomBorder-mnBorderY-TB_BORDER_OFFSET2-1;
+ }
+ else
+ {
+ maNextToolRect.Top() = nTop+nMax+TB_SPIN_OFFSET;;
+ maNextToolRect.Bottom() = maNextToolRect.Top()+TB_SPIN_SIZE-1;
+ maNextToolRect.Left() = nLeft;
+ maNextToolRect.Right() = mnDX-mnRightBorder-mnBorderX-TB_BORDER_OFFSET2-1;
+ }
+ }
+
+ // Haben wir ueberhaupt Items
+ if ( mpItemList->GetObject( 0 ) )
+ {
+ // Umbrueche und sichtbare Zeilen berechnen
+ mnCurLines = ImplCalcBreaks( nMax, NULL, mbHorz );
+ if ( (mnCurLines > mnVisLines) && mbScroll )
+ {
+ nMax -= TB_SPIN_SIZE+TB_SPIN_OFFSET;
+ mnCurLines = ImplCalcBreaks( nMax, NULL, mbHorz );
+ // Wenn wir umbrechen muessen, dann Scroll-Rectangles neu setzen
+ if ( mbHorz )
+ {
+ maUpperRect.Left() = nLeft+nMax+TB_SPIN_OFFSET;
+ maUpperRect.Right() = maUpperRect.Left()+TB_SPIN_SIZE-1;
+ maUpperRect.Top() = nTop;
+ maLowerRect.Bottom() = mnDY-mnBottomBorder-mnBorderY-TB_BORDER_OFFSET2-1;
+ maLowerRect.Left() = maUpperRect.Left();
+ maLowerRect.Right() = maUpperRect.Right();
+ maUpperRect.Bottom() = maUpperRect.Top() +
+ (maLowerRect.Bottom()-maUpperRect.Top())/2;
+ maLowerRect.Top() = maUpperRect.Bottom();
+ }
+ else
+ {
+ maUpperRect.Top() = nTop+nMax+TB_SPIN_OFFSET;;
+ maUpperRect.Bottom() = maUpperRect.Top()+TB_SPIN_SIZE-1;
+ maUpperRect.Left() = nLeft;
+ maLowerRect.Right() = mnDX-mnRightBorder-mnBorderX-TB_BORDER_OFFSET2-1;
+ maLowerRect.Top() = maUpperRect.Top();
+ maLowerRect.Bottom() = maUpperRect.Bottom();
+ maUpperRect.Right() = maUpperRect.Left() +
+ (maLowerRect.Right()-maUpperRect.Left())/2;
+ maLowerRect.Left() = maUpperRect.Right();
+ }
+ }
+ if ( mnVisLines >= mnCurLines )
+ mnCurLine = 1;
+ else if ( mnCurLine+mnVisLines-1 > mnCurLines )
+ mnCurLine = mnCurLines - (mnVisLines-1);
+
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Doppelte Separatoren hiden
+ if ( mbCustomize )
+ {
+ if ( pItem->meType == TOOLBOXITEM_SEPARATOR )
+ {
+ pItem->mbVisible = FALSE;
+ if ( !bLastSep )
+ {
+ // Feststellen ob dahinter ueberhaupt noch
+ // ein Item sichtbar ist
+ ULONG nTempPos = mpItemList->GetCurPos()+1;
+ ULONG nCount = mpItemList->Count();
+ while ( nTempPos < nCount )
+ {
+ pTempItem = mpItemList->GetObject( nTempPos );
+ if ( (pTempItem->meType == TOOLBOXITEM_SEPARATOR) ||
+ ((pTempItem->meType == TOOLBOXITEM_BUTTON) &&
+ pTempItem->mbVisible) )
+ {
+ pItem->mbVisible = TRUE;
+ break;
+ }
+ nTempPos++;
+ }
+ }
+ bLastSep = TRUE;
+ }
+ else if ( pItem->mbVisible )
+ bLastSep = FALSE;
+ }
+
+ pItem->mbShowWindow = FALSE;
+
+ if ( pItem->mbBreak )
+ {
+ nFormatLine++;
+
+ // Ab der zweiten Zeile erhoehen
+ if ( nFormatLine > mnCurLine )
+ {
+ if ( mbHorz )
+ {
+ nX = nLeft;
+ if ( mnWinStyle & WB_LINESPACING )
+ nY += nLineSize+TB_LINESPACING;
+ else
+ nY += nLineSize;
+ }
+ else
+ {
+ nY = nTop;
+ if ( mnWinStyle & WB_LINESPACING )
+ nX += nLineSize+TB_LINESPACING;
+ else
+ nX += nLineSize;
+ }
+ }
+ }
+
+ if ( !pItem->mbVisible || (nFormatLine < mnCurLine) ||
+ (nFormatLine > mnCurLine+mnVisLines-1) )
+ pItem->maCalcRect = aEmptyRect;
+ else
+ {
+ if ( (pItem->meType == TOOLBOXITEM_BUTTON) ||
+ (pItem->meType == TOOLBOXITEM_SPACE) )
+ {
+ if ( pItem->mnNonStdSize )
+ {
+ if ( mbHorz )
+ {
+ nCurWidth = pItem->mnNonStdSize;
+ nCurHeight = mnItemHeight;
+ }
+ else
+ {
+ nCurWidth = mnItemWidth;
+ nCurHeight = pItem->mnNonStdSize;
+ }
+ }
+ else
+ {
+ nCurWidth = mnItemWidth;
+ nCurHeight = mnItemHeight;
+ }
+
+ if ( pItem->mpWindow && mbHorz )
+ {
+ Size aWinSize = pItem->mpWindow->GetSizePixel();
+ if ( !mbScroll || (aWinSize.Width() <= nMax) )
+ {
+ nCurWidth = aWinSize.Width();
+ nCurHeight = aWinSize.Height();
+ pItem->mbShowWindow = TRUE;
+ }
+ else
+ {
+ if ( pItem->mbEmptyBtn )
+ {
+ nCurWidth = 0;
+ nCurHeight = 0;
+ }
+ }
+ }
+ }
+ else if ( pItem->meType == TOOLBOXITEM_SEPARATOR )
+ {
+ if ( mbHorz )
+ {
+ nCurWidth = pItem->mnSepSize;
+ nCurHeight = mnItemHeight;
+ }
+ else
+ {
+ nCurWidth = mnItemWidth;
+ nCurHeight = pItem->mnSepSize;
+ }
+ }
+ else if ( pItem->meType == TOOLBOXITEM_BREAK )
+ {
+ nCurWidth = 0;
+ nCurHeight = 0;
+ }
+
+ if ( mbHorz )
+ {
+ pItem->maCalcRect.Left() = nX;
+ pItem->maCalcRect.Top() = nY+(nLineSize-nCurHeight)/2;
+ pItem->maCalcRect.Right() = nX+nCurWidth-1;
+ pItem->maCalcRect.Bottom() = pItem->maCalcRect.Top()+nCurHeight-1;
+ nX += nCurWidth;
+ }
+ else
+ {
+ pItem->maCalcRect.Left() = nX+(nLineSize-nCurWidth)/2;;
+ pItem->maCalcRect.Top() = nY;
+ pItem->maCalcRect.Right() = pItem->maCalcRect.Left()+nCurWidth-1;
+ pItem->maCalcRect.Bottom() = nY+nCurHeight-1;
+ nY += nCurHeight;
+ }
+ }
+
+ if ( pItem->mpWindow )
+ {
+ if ( pItem->mbShowWindow )
+ {
+ Point aPos( pItem->maCalcRect.Left(), pItem->maCalcRect.Top() );
+ pItem->mpWindow->SetPosPixel( aPos );
+ if ( !mbCustomizeMode )
+ pItem->mpWindow->Show();
+ }
+ else
+ pItem->mpWindow->Hide();
+ }
+
+ pItem = mpItemList->Next();
+ }
+ }
+ else
+ mnCurLines = 1;
+
+ // Wenn ToolBox sichtbar, Paint fuer geaenderte Bereiche ausloesen
+ if ( IsVisible() && !mbFullPaint )
+ {
+ if ( bMustFullPaint )
+ {
+ maPaintRect = Rectangle( mnLeftBorder, mnTopBorder,
+ mnDX-mnRightBorder, mnDY-mnBottomBorder );
+ }
+ else
+ {
+ if ( aOldLowerRect != maLowerRect )
+ {
+ maPaintRect.Union( maLowerRect );
+ maPaintRect.Union( aOldLowerRect );
+ }
+ if ( aOldUpperRect != maUpperRect )
+ {
+ maPaintRect.Union( maUpperRect );
+ maPaintRect.Union( aOldUpperRect );
+ }
+ if ( aOldNextToolRect != maNextToolRect )
+ {
+ maPaintRect.Union( maNextToolRect );
+ maPaintRect.Union( aOldNextToolRect );
+ }
+
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->maRect != pItem->maCalcRect )
+ {
+ maPaintRect.Union( pItem->maRect );
+ maPaintRect.Union( pItem->maCalcRect );
+ }
+ pItem = mpItemList->Next();
+ }
+ }
+
+ Invalidate( maPaintRect );
+ }
+
+ // Neu berechnete Rectangles uebertragen
+ maPaintRect = aEmptyRect;
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ pItem->maRect = pItem->maCalcRect;
+ pItem = mpItemList->Next();
+ }
+ }
+
+ // Es wurde die Leiste neu durchformatiert
+ maTimer.Stop();
+ mbFormat = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ToolBox, ImplUpdateHdl, void*, EMPTYARG )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mbFormat )
+ ImplFormat();
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawToolArrow( ToolBox* pBox, long nX, long nY, BOOL bBlack,
+ BOOL bLeft = FALSE, BOOL bTop = FALSE )
+{
+ Color aOldFillColor = pBox->GetFillColor();
+ WindowAlign eAlign = pBox->meAlign;
+ if ( bLeft )
+ eAlign = WINDOWALIGN_RIGHT;
+ else if ( bTop )
+ eAlign = WINDOWALIGN_BOTTOM;
+
+ switch ( eAlign )
+ {
+ case WINDOWALIGN_LEFT:
+ if ( bBlack )
+ pBox->SetFillColor( Color( COL_BLACK ) );
+ pBox->DrawRect( Rectangle( nX+0, nY+0, nX+0, nY+6 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+1, nX+1, nY+5 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+2, nX+2, nY+4 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
+ if ( bBlack )
+ {
+ pBox->SetFillColor( aOldFillColor );
+ pBox->DrawRect( Rectangle( nX+1, nY+2, nX+1, nY+4 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+3, nX+2, nY+3 ) );
+ }
+ break;
+ case WINDOWALIGN_TOP:
+ if ( bBlack )
+ pBox->SetFillColor( Color( COL_BLACK ) );
+ pBox->DrawRect( Rectangle( nX+0, nY+0, nX+6, nY+0 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+1, nX+5, nY+1 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
+ if ( bBlack )
+ {
+ pBox->SetFillColor( aOldFillColor );
+ pBox->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+2, nX+3, nY+2 ) );
+ }
+ break;
+ case WINDOWALIGN_RIGHT:
+ if ( bBlack )
+ pBox->SetFillColor( Color( COL_BLACK ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+0, nX+3, nY+6 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+1, nX+2, nY+5 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+2, nX+1, nY+4 ) );
+ pBox->DrawRect( Rectangle( nX+0, nY+3, nX+0, nY+3 ) );
+ if ( bBlack )
+ {
+ pBox->SetFillColor( aOldFillColor );
+ pBox->DrawRect( Rectangle( nX+2, nY+2, nX+2, nY+4 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+3, nX+1, nY+3 ) );
+ }
+ break;
+ case WINDOWALIGN_BOTTOM:
+ if ( bBlack )
+ pBox->SetFillColor( Color( COL_BLACK ) );
+ pBox->DrawRect( Rectangle( nX+0, nY+3, nX+6, nY+3 ) );
+ pBox->DrawRect( Rectangle( nX+1, nY+2, nX+5, nY+2 ) );
+ pBox->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+0, nX+3, nY+0 ) );
+ if ( bBlack )
+ {
+ pBox->SetFillColor( aOldFillColor );
+ pBox->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) );
+ pBox->DrawRect( Rectangle( nX+3, nY+1, nX+3, nY+1 ) );
+ }
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplDrawSpin( BOOL bUpperIn, BOOL bLowerIn )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ BOOL bTmpUpper;
+ BOOL bTmpLower;
+
+ if ( maUpperRect.IsEmpty() || maLowerRect.IsEmpty() )
+ return;
+
+ if ( mnCurLine > 1 )
+ bTmpUpper = TRUE;
+ else
+ bTmpUpper = FALSE;
+
+ if ( mnCurLine+mnVisLines-1 < mnCurLines )
+ bTmpLower = TRUE;
+ else
+ bTmpLower = FALSE;
+
+ if ( !IsEnabled() )
+ {
+ bTmpUpper = FALSE;
+ bTmpLower = FALSE;
+ }
+
+ ImplDrawSpinButton( this, maUpperRect, maLowerRect,
+ bUpperIn, bLowerIn, bTmpUpper, bTmpLower, !mbHorz );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplDrawNext( BOOL bIn )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( maNextToolRect.IsEmpty() )
+ return;
+
+ DecorationView aDecoView( this );
+
+ // Button malen
+ long nX = SMALLBUTTON_OFF_NORMAL_X;
+ long nY = SMALLBUTTON_OFF_NORMAL_Y;
+ USHORT nStyle = 0;
+ if ( bIn == 1 )
+ {
+ nStyle |= BUTTON_DRAW_PRESSED;
+ nX = SMALLBUTTON_OFF_PRESSED_X;
+ nY = SMALLBUTTON_OFF_PRESSED_Y;
+ }
+ aDecoView.DrawButton( maNextToolRect, nStyle );
+
+ // Inhalt ausgeben
+ BOOL bLeft = FALSE;
+ BOOL bTop = FALSE;
+ if ( mbHorz )
+ {
+ bLeft = TRUE;
+ nX++;
+ nY += (maNextToolRect.GetHeight()-12)/2;
+ }
+ else
+ {
+ bTop = TRUE;
+ nY++;
+ nX += (maNextToolRect.GetWidth()-12)/2;
+ }
+
+ nX += maNextToolRect.Left();
+ nY += maNextToolRect.Top();
+ SetLineColor();
+ SetFillColor( COL_LIGHTBLUE );
+ ImplDrawToolArrow( this, nX, nY, TRUE, bLeft, bTop );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplDrawItem( USHORT nPos, BOOL bHighlight, BOOL bPaint )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+
+ // Falls Rechteck ausserhalb des sichbaren Bereichs liegt
+ if ( pItem->maRect.IsEmpty() )
+ return;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ // Im flachen Style werden auch Separatoren gezeichnet
+ if ( (mnOutStyle & TOOLBOX_STYLE_FLAT) &&
+ (pItem->meType == TOOLBOXITEM_SEPARATOR) )
+ {
+ // Strich wird nicht gemalt, wenn vor oder hinter Fenstern
+ // oder bei einem Umbruch
+ ImplToolItem* pTempItem = mpItemList->GetObject( nPos );
+ pTempItem = mpItemList->GetObject( nPos-1 );
+ if ( pTempItem && !pTempItem->mbShowWindow )
+ {
+ pTempItem = mpItemList->GetObject( nPos+1 );
+ if ( pTempItem && !pTempItem->mbShowWindow && !pTempItem->mbBreak )
+ {
+ long nCenterPos;
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ if ( IsHorizontal() )
+ {
+ nCenterPos = pItem->maRect.Center().X()-1;
+ DrawLine( Point( nCenterPos, pItem->maRect.Top() ),
+ Point( nCenterPos, pItem->maRect.Bottom() ) );
+ nCenterPos++;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( nCenterPos, pItem->maRect.Top() ),
+ Point( nCenterPos, pItem->maRect.Bottom() ) );
+ }
+ else
+ {
+ nCenterPos = pItem->maRect.Center().Y()-1;
+ DrawLine( Point( pItem->maRect.Left(), nCenterPos ),
+ Point( pItem->maRect.Right(), nCenterPos ) );
+ nCenterPos++;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( pItem->maRect.Left(), nCenterPos ),
+ Point( pItem->maRect.Right(), nCenterPos ) );
+ }
+ }
+ }
+ }
+
+ // Ist es kein Button oder wird er als Fenster dargestellt,
+ // dann mache nichts
+ if ( (pItem->meType != TOOLBOXITEM_BUTTON) ||
+ (pItem->mbShowWindow && !mbCustomizeMode) )
+ return;
+
+ // Wenn wir das Configurations-Item zeichen, brauchen wir dazu ein
+ // TBDragMananger
+ ImplTBDragMgr* pMgr;
+ if ( pItem->mnId == mnConfigItem )
+ {
+ pMgr = ImplGetTBDragMgr();
+ pMgr->HideDragRect();
+ }
+ else
+ pMgr = NULL;
+
+ // Im Konfigurationsmodus werden sichtbare Fenster durch eine andere
+ // Darstellung ersetzt
+ if ( mbCustomizeMode && pItem->mbShowWindow )
+ {
+ Font aOldFont = GetFont();
+ Color aOldTextColor = GetTextColor();
+
+ SetFont( rStyleSettings.GetAppFont() );
+ SetLineColor( Color( COL_BLACK ) );
+ SetFillColor( rStyleSettings.GetFieldColor() );
+ SetTextColor( rStyleSettings.GetFieldTextColor() );
+ DrawRect( pItem->maRect );
+
+ Size aSize( GetCtrlTextWidth( pItem->maText ), GetTextHeight() );
+ Point aPos( pItem->maRect.Left()+2, pItem->maRect.Top() );
+ aPos.Y() += (pItem->maRect.GetHeight()-aSize.Height())/2;
+ BOOL bClip;
+ if ( (aSize.Width() > pItem->maRect.GetWidth()-2) ||
+ (aSize.Height() > pItem->maRect.GetHeight()-2) )
+ {
+ bClip = TRUE;
+ Rectangle aTempRect( pItem->maRect.Left()+1, pItem->maRect.Top()+1,
+ pItem->maRect.Right()-1, pItem->maRect.Bottom()-1 );
+ Region aTempRegion( aTempRect );
+ SetClipRegion( aTempRegion );
+ }
+ else
+ bClip = FALSE;
+ DrawCtrlText( aPos, pItem->maText );
+ if ( bClip )
+ SetClipRegion();
+ SetFont( aOldFont );
+ SetTextColor( aOldTextColor );
+
+ // Gegebenenfalls noch Config-Frame zeichnen
+ if ( pMgr )
+ pMgr->UpdateDragRect();
+ return;
+ }
+
+ // Button malen
+ Point aBtnPos;
+ Size aBtnSize = pItem->maRect.GetSize();
+ long nOffX = SMALLBUTTON_OFF_NORMAL_X;
+ long nOffY = SMALLBUTTON_OFF_NORMAL_Y;
+ long nTempOffX;
+ long nTempOffY;
+ USHORT nStyle = 0;
+ if ( pItem->meState == STATE_CHECK )
+ {
+ aBtnPos.Y() = aBtnSize.Height() * 2;
+ nStyle |= BUTTON_DRAW_CHECKED;
+ nOffX = SMALLBUTTON_OFF_CHECKED_X;
+ nOffY = SMALLBUTTON_OFF_CHECKED_Y;
+ }
+ else if ( pItem->meState == STATE_DONTKNOW )
+ {
+ aBtnPos.Y() = aBtnSize.Height() * 4;
+ nStyle |= BUTTON_DRAW_DONTKNOW;
+ }
+ if ( bHighlight == 1 )
+ {
+ aBtnPos.Y() += aBtnSize.Height();
+ nStyle |= BUTTON_DRAW_PRESSED;
+ nOffX = SMALLBUTTON_OFF_PRESSED_X;
+ nOffY = SMALLBUTTON_OFF_PRESSED_Y;
+ }
+
+ if ( mnOutStyle & TOOLBOX_STYLE_OUTBUTTON )
+ {
+ nOffX = OUTBUTTON_OFF_NORMAL_X;
+ nOffY = OUTBUTTON_OFF_NORMAL_Y;
+ if ( bHighlight )
+ {
+ nOffX++;
+ nOffY++;
+ }
+ }
+
+ if ( mnOutStyle & TOOLBOX_STYLE_FLAT )
+ {
+ if ( (pItem->meState != STATE_NOCHECK) || !bPaint )
+ {
+ if ( pItem->meState != STATE_NOCHECK )
+ {
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetCheckedColor() );
+ DrawRect( pItem->maRect );
+ }
+ else
+ Erase( pItem->maRect );
+ }
+ }
+ else
+ {
+ if ( !pItem->mnNonStdSize )
+ DrawOutDev( pItem->maRect.TopLeft(), aBtnSize, aBtnPos, aBtnSize, *mpBtnDev );
+ else
+ {
+ if ( mnOutStyle & TOOLBOX_STYLE_OUTBUTTON )
+ ImplDrawOutButton( this, pItem->maRect, nStyle );
+ else
+ {
+ DecorationView aDecoView( this );
+ aDecoView.DrawButton( pItem->maRect, nStyle );
+ }
+ }
+ }
+
+ nOffX += pItem->maRect.Left();
+ nOffY += pItem->maRect.Top();
+
+ // Feststellen, was gemalt werden soll
+ BOOL bImage;
+ BOOL bText;
+ if ( meButtonType == BUTTON_SYMBOL )
+ {
+ if ( pItem->mnNonStdSize )
+ {
+ bImage = FALSE;
+ bText = TRUE;
+ }
+ else
+ {
+ bImage = TRUE;
+ bText = FALSE;
+ }
+ }
+ else if ( meButtonType == BUTTON_TEXT )
+ {
+ if ( pItem->mnNonStdSize )
+ {
+ bImage = TRUE;
+ bText = FALSE;
+ }
+ else
+ {
+ bImage = FALSE;
+ bText = TRUE;
+ }
+ }
+ else
+ {
+ bImage = TRUE;
+ bText = TRUE;
+ }
+
+ // Werte fuer die Ausgabe bestimmen
+ long nBtnWidth = aBtnSize.Width()-SMALLBUTTON_HSIZE;
+ long nBtnHeight = aBtnSize.Height()-SMALLBUTTON_VSIZE;
+ Size aImageSize;
+ Size aTxtSize;
+
+ if ( bText )
+ {
+ aTxtSize.Width() = GetCtrlTextWidth( pItem->maText );
+ aTxtSize.Height() = GetTextHeight();
+ }
+
+ if ( bImage )
+ {
+ const Image* pImage;
+ if ( bHighlight && (!(pItem->maHighImage)) == FALSE )
+ pImage = &(pItem->maHighImage);
+ else
+ pImage = &(pItem->maImage);
+
+ aImageSize = pImage->GetSizePixel();
+
+ // Ausgabeflags bestimmen
+ USHORT nImageStyle = 0;
+
+ if ( !pItem->mbEnabled || !IsEnabled() )
+ nImageStyle |= IMAGE_DRAW_DISABLE;
+
+ if ( pItem->meState == STATE_DONTKNOW )
+ nImageStyle |= IMAGE_DRAW_DISABLE;
+
+ // Image ausgeben
+ nTempOffX = nOffX;
+ nTempOffY = nOffY;
+ if ( pItem->mnBits & TIB_LEFT )
+ nTempOffY += (nBtnHeight-aImageSize.Height())/2;
+ else
+ {
+ nTempOffX += (nBtnWidth-aImageSize.Width())/2;
+ if ( bText )
+ nTempOffY += (nBtnHeight-aTxtSize.Height()-aImageSize.Height())/2;
+ else
+ nTempOffY += (nBtnHeight-aImageSize.Height())/2;
+ }
+ DrawImage( Point( nTempOffX, nTempOffY ), *pImage, nImageStyle );
+ }
+
+ // Text ausgeben
+ if ( bText )
+ {
+ nTempOffX = nOffX;
+ nTempOffY = nOffY;
+
+ // Muss Text gegebenenfalls gedreht werden
+ Font aOldFont = GetFont();
+ BOOL bRotate = FALSE;
+ if ( pItem->mnNonStdSize && !bImage && !IsFloatingMode() &&
+ ((meAlign == WINDOWALIGN_LEFT) || (meAlign == WINDOWALIGN_RIGHT)) )
+ {
+ bRotate = TRUE;
+
+ Font aRotateFont = aOldFont;
+ if ( meAlign == WINDOWALIGN_LEFT )
+ {
+ aRotateFont.SetOrientation( 900 );
+ nTempOffX += (nBtnWidth-aTxtSize.Height())/2;
+ nTempOffY += aTxtSize.Width();
+ nTempOffY += (nBtnHeight-aTxtSize.Width())/2;
+ }
+ else
+ {
+ aRotateFont.SetOrientation( 2700 );
+ nTempOffX += aTxtSize.Height();
+ nTempOffX += (nBtnWidth-aTxtSize.Height())/2;
+ nTempOffY += (nBtnHeight-aTxtSize.Width())/2;
+ }
+
+ SetFont( aRotateFont );
+ }
+ else
+ {
+ if ( pItem->mnBits & TIB_LEFT )
+ {
+ nTempOffX += aImageSize.Width();
+ nTempOffY += (nBtnHeight-aTxtSize.Height())/2;
+ }
+ else
+ {
+ nTempOffX += (nBtnWidth-aTxtSize.Width())/2;
+ if ( bImage )
+ nTempOffY += nBtnHeight-aTxtSize.Height();
+ else
+ nTempOffY += (nBtnHeight-aTxtSize.Height())/2;
+ }
+ }
+
+ USHORT nTextStyle = 0;
+ if ( !pItem->mbEnabled )
+ nTextStyle |= TEXT_DRAW_DISABLE;
+ DrawCtrlText( Point( nTempOffX, nTempOffY ), pItem->maText,
+ 0, STRING_LEN, nTextStyle );
+
+ if ( bRotate )
+ SetFont( aOldFont );
+ }
+
+ // Evt. noch Pfeil rechts/oben in der Ecke zeichnen
+ if ( pItem->mnBits & TIB_DROPDOWN )
+ {
+ Point aArrowPos( nOffX, nOffY );
+ aArrowPos.X() += nBtnWidth-6;
+
+ Color aOldLineColor = GetLineColor();
+ Color aOldFillColor = GetFillColor();
+ Rectangle aClearRect( aArrowPos.X()-1, aArrowPos.Y(),
+ aArrowPos.X()+3, aArrowPos.Y()+4 );
+ SetLineColor();
+
+ if ( (meAlign == WINDOWALIGN_LEFT) || (meAlign == WINDOWALIGN_RIGHT) )
+ {
+ aArrowPos.X() += 2;
+ aClearRect.Left() += 2;
+ aClearRect.Right() += 2;
+ aClearRect.Bottom() += 2;
+ }
+ else
+ aClearRect.Right() += 2;
+
+ Erase( aClearRect );
+ BOOL bBlack = FALSE;
+
+ if ( !pItem->mbEnabled || !IsEnabled() )
+ SetFillColor( rStyleSettings.GetShadowColor() );
+ else
+ {
+ SetFillColor( COL_LIGHTGREEN );
+ bBlack = TRUE;
+ }
+ ImplDrawToolArrow( this, aArrowPos.X(), aArrowPos.Y(), bBlack );
+ SetLineColor( aOldLineColor );
+ SetFillColor( aOldFillColor );
+ }
+
+ if ( mnOutStyle & TOOLBOX_STYLE_FLAT )
+ {
+ if ( bHighlight || (pItem->meState == STATE_CHECK) )
+ {
+ Point aPos( pItem->maRect.TopLeft() );
+ Size aSize( pItem->maRect.GetSize() );
+
+ if ( bHighlight == 2 )
+ SetLineColor( rStyleSettings.GetLightColor() );
+ else
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( aPos, Point( aPos.X()+aSize.Width()-1, aPos.Y() ) );
+ DrawLine( aPos, Point( aPos.X(), aPos.Y()+aSize.Height()-1 ) );
+ if ( bHighlight == 2 )
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ else
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( aPos.X()+aSize.Width()-1, aPos.Y() ),
+ Point( aPos.X()+aSize.Width()-1, aPos.Y()+aSize.Height()-1 ) );
+ DrawLine( Point( aPos.X(), aPos.Y()+aSize.Height()-1 ),
+ Point( aPos.X()+aSize.Width()-1, aPos.Y()+aSize.Height()-1 ) );
+ }
+ }
+
+ // Gegebenenfalls noch Config-Frame zeichnen
+ if ( pMgr )
+ pMgr->UpdateDragRect();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplStartCustomizeMode()
+{
+ mbCustomizeMode = TRUE;
+
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbShowWindow )
+ {
+ pItem->mpWindow->Hide();
+
+ if ( !(pItem->maRect.IsEmpty()) )
+ Invalidate( pItem->maRect );
+ }
+
+ pItem = mpItemList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplEndCustomizeMode()
+{
+ mbCustomizeMode = FALSE;
+
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbShowWindow )
+ {
+ if ( !(pItem->maRect.IsEmpty()) )
+ Invalidate( pItem->maRect );
+
+ pItem->mpWindow->Show();
+ }
+
+ pItem = mpItemList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplFloatControl( BOOL bStart, FloatingWindow* pFloatWindow )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( bStart )
+ {
+ mpFloatWin = pFloatWindow;
+
+ // Wenn Button nicht gedrueckt dargestellt wird, dann den
+ // Button neu malen
+ if ( mnCurItemId != mnDownItemId )
+ ImplDrawItem( mnCurPos, TRUE );
+ mbDrag = FALSE;
+ EndTracking();
+ ReleaseMouse();
+ }
+ else
+ {
+ mpFloatWin = NULL;
+
+ if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
+ ImplDrawItem( mnCurPos );
+ Deactivate();
+ mnCurPos = TOOLBOX_ITEM_NOTFOUND;
+ mnCurItemId = 0;
+ mnDownItemId = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ShowLine( BOOL bNext )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ mbFormat = TRUE;
+ if ( bNext )
+ mnCurLine++;
+ else
+ mnCurLine--;
+ ImplFormat();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ToolBox::ImplHandleMouseMove( const MouseEvent& rMEvt, BOOL bRepeat )
+{
+ Point aMousePos = rMEvt.GetPosPixel();
+
+ // Ist ToolBox aktiv
+ if ( mbDrag )
+ {
+ // Befindet sich Maus ueber dem Item
+ ImplToolItem* pItem = mpItemList->GetObject( mnCurPos );
+ if ( pItem->maRect.IsInside( aMousePos ) )
+ {
+ if ( !mnCurItemId )
+ {
+ ImplDrawItem( mnCurPos, TRUE );
+ mnCurItemId = pItem->mnId;
+ Highlight();
+ }
+
+ if ( (pItem->mnBits & TIB_REPEAT) && bRepeat )
+ Select();
+ }
+ else
+ {
+ if ( mnCurItemId )
+ {
+ ImplDrawItem( mnCurPos );
+ mnCurItemId = 0;
+ ImplDrawItem( mnCurPos );
+ Highlight();
+ }
+ }
+
+ return TRUE;
+ }
+
+ if ( mbUpper )
+ {
+ BOOL bNewIn = maUpperRect.IsInside( aMousePos );
+ if ( bNewIn != mbIn )
+ {
+ mbIn = bNewIn;
+ ImplDrawSpin( mbIn, FALSE );
+ }
+ return TRUE;
+ }
+
+ if ( mbLower )
+ {
+ BOOL bNewIn = maLowerRect.IsInside( aMousePos );
+ if ( bNewIn != mbIn )
+ {
+ mbIn = bNewIn;
+ ImplDrawSpin( FALSE, mbIn );
+ }
+ return TRUE;
+ }
+
+ if ( mbNextTool )
+ {
+ BOOL bNewIn = maNextToolRect.IsInside( aMousePos );
+ if ( bNewIn != mbIn )
+ {
+ mbIn = bNewIn;
+ ImplDrawNext( mbIn );
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ToolBox::ImplHandleMouseButtonUp( const MouseEvent& rMEvt, BOOL bCancel )
+{
+ if ( mbDrag || mbSelection )
+ {
+ // Hier die MouseDaten setzen, wenn Selection-Modus, da dann kein
+ // MouseButtonDown-Handler gerufen wird
+ if ( mbSelection )
+ {
+ mnMouseClicks = rMEvt.GetClicks();
+ mnMouseModifier = rMEvt.GetModifier();
+ }
+
+ Deactivate();
+
+ if ( mbDrag )
+ mbDrag = FALSE;
+ else
+ {
+ mbSelection = FALSE;
+ if ( mnCurPos == TOOLBOX_ITEM_NOTFOUND )
+ return TRUE;
+ }
+
+ // Wurde Maus ueber dem Item losgelassen
+ ImplToolItem* pItem = mpItemList->GetObject( mnCurPos );
+ if ( pItem->maRect.IsInside( rMEvt.GetPosPixel() ) )
+ {
+ mnCurItemId = pItem->mnId;
+ if ( !bCancel )
+ {
+ // Gegebenenfalls ein AutoCheck durchfuehren
+ if ( pItem->mnBits & TIB_AUTOCHECK )
+ {
+ if ( pItem->mnBits & TIB_RADIOCHECK )
+ {
+ if ( pItem->meState != STATE_CHECK )
+ SetItemState( pItem->mnId, STATE_CHECK );
+ }
+ else
+ {
+ if ( pItem->meState != STATE_CHECK )
+ pItem->meState = STATE_CHECK;
+ else
+ pItem->meState = STATE_NOCHECK;
+ }
+ }
+
+ // Select nicht bei Repeat ausloesen, da dies schon im
+ // MouseButtonDown ausgeloest wurde
+ if ( !(pItem->mnBits & TIB_REPEAT) )
+ {
+ // Gegen zerstoeren im Select-Handler sichern
+ ImplDelData aDelData;
+ ImplAddDel( &aDelData );
+ Select();
+ if ( aDelData.IsDelete() )
+ return TRUE;
+ ImplRemoveDel( &aDelData );
+ }
+ }
+
+ {
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ // Items nicht geloescht, im Select-Handler
+ if ( mnCurItemId )
+ {
+ BOOL bHighlight;
+ if ( (mnCurItemId == mnHighItemId) && (mnOutStyle & TOOLBOX_STYLE_FLAT) )
+ bHighlight = 2;
+ else
+ bHighlight = FALSE;
+ ImplDrawItem( mnCurPos, bHighlight );
+ }
+ }
+
+ mnCurPos = TOOLBOX_ITEM_NOTFOUND;
+ mnCurItemId = 0;
+ mnDownItemId = 0;
+ mnMouseClicks = 0;
+ mnMouseModifier = 0;
+ return TRUE;
+ }
+ else if ( mbUpper || mbLower )
+ {
+ if ( mbIn )
+ ShowLine( !mbUpper );
+ mbUpper = FALSE;
+ mbLower = FALSE;
+ mbIn = FALSE;
+ ImplDrawSpin( FALSE, FALSE );
+ return TRUE;
+ }
+ else if ( mbNextTool )
+ {
+ mbNextTool = FALSE;
+ mbIn = FALSE;
+ ImplDrawNext( FALSE );
+ NextToolBox();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( ImplHandleMouseMove( rMEvt ) )
+ return;
+
+ Point aMousePos = rMEvt.GetPosPixel();
+
+ if ( mbSelection )
+ {
+ USHORT i = 0;
+ USHORT nNewPos = TOOLBOX_ITEM_NOTFOUND;
+
+ // Item suchen, das geklickt wurde
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Wenn Mausposition in diesem Item vorhanden, kann die
+ // Suche abgebrochen werden
+ if ( pItem->maRect.IsInside( aMousePos ) )
+ {
+ // Wenn es ein Button ist, dann wird er selektiert
+ if ( pItem->meType == TOOLBOXITEM_BUTTON )
+ {
+ // Wenn er disablet ist, findet keine Aenderung
+ // statt
+ if ( !pItem->mbEnabled || pItem->mbShowWindow )
+ nNewPos = mnCurPos;
+ else
+ nNewPos = i;
+ }
+
+ break;
+ }
+
+ i++;
+ pItem = mpItemList->Next();
+ }
+
+ // Wurde ein neuer Eintrag selektiert
+ if ( nNewPos != mnCurPos )
+ {
+ if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
+ ImplDrawItem( mnCurPos );
+
+ mnCurPos = nNewPos;
+ if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ mnCurItemId = pItem->mnId;
+ ImplDrawItem( mnCurPos, TRUE );
+ }
+ else
+ mnCurItemId = 0;
+
+ Highlight();
+ }
+ return;
+ }
+
+ if ( mbDragging )
+ {
+ ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
+ pMgr->Dragging( aMousePos );
+ return;
+ }
+
+ PointerStyle eStyle = POINTER_ARROW;
+ if ( (mnWinStyle & TB_WBLINESIZING) == TB_WBLINESIZING )
+ {
+ if ( rMEvt.GetMode() & MOUSE_SIMPLEMOVE )
+ {
+ USHORT nLinePtr = ImplTestLineSize( this, rMEvt.GetPosPixel() );
+ if ( nLinePtr & DOCK_LINEHSIZE )
+ {
+ if ( meAlign == WINDOWALIGN_LEFT )
+ eStyle = POINTER_WINDOW_ESIZE;
+ else
+ eStyle = POINTER_WINDOW_WSIZE;
+ }
+ else if ( nLinePtr & DOCK_LINEVSIZE )
+ {
+ if ( meAlign == WINDOWALIGN_TOP )
+ eStyle = POINTER_WINDOW_SSIZE;
+ else
+ eStyle = POINTER_WINDOW_NSIZE;
+ }
+ }
+ }
+
+ if ( (eStyle == POINTER_ARROW) && mbCustomizeMode )
+ {
+ // Item suchen, das geklickt wurde
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Wenn es ein Customize-Window ist, gegebenenfalls den
+ // Resize-Pointer anzeigen
+ if ( pItem->mbShowWindow )
+ {
+ if ( pItem->maRect.IsInside( aMousePos ) )
+ {
+ if ( pItem->maRect.Right()-TB_RESIZE_OFFSET <= aMousePos.X() )
+ eStyle = POINTER_HSIZEBAR;
+ break;
+ }
+ }
+
+ pItem = mpItemList->Next();
+ }
+ }
+
+ if ( ((eStyle == POINTER_ARROW) && (mnOutStyle & TOOLBOX_STYLE_HANDPOINTER)) ||
+ (mnOutStyle & TOOLBOX_STYLE_FLAT) )
+ {
+ BOOL bClearHigh = TRUE;
+ if ( !rMEvt.IsLeaveWindow() && (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
+ {
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->maRect.IsInside( aMousePos ) )
+ {
+ if ( (pItem->meType == TOOLBOXITEM_BUTTON) && pItem->mbEnabled )
+ {
+ if ( mnOutStyle & TOOLBOX_STYLE_FLAT )
+ {
+ bClearHigh = FALSE;
+ if ( mnHighItemId != pItem->mnId )
+ {
+ USHORT nTempPos = (USHORT)mpItemList->GetCurPos();
+ if ( mnHighItemId )
+ ImplDrawItem( GetItemPos( mnHighItemId ) );
+ mnHighItemId = pItem->mnId;
+ ImplDrawItem( nTempPos, 2 );
+ }
+ }
+ if ( mnOutStyle & TOOLBOX_STYLE_HANDPOINTER )
+ eStyle = POINTER_REFHAND;
+ }
+ break;
+ }
+
+ pItem = mpItemList->Next();
+ }
+ }
+
+ if ( bClearHigh && mnHighItemId )
+ {
+ USHORT nClearPos = GetItemPos( mnHighItemId );
+ if ( nClearPos != TOOLBOX_ITEM_NOTFOUND )
+ ImplDrawItem( nClearPos, (nClearPos == mnCurPos) ? TRUE : FALSE );
+ mnHighItemId = 0;
+ }
+ }
+
+ if ( meLastStyle != eStyle )
+ {
+ meLastStyle = eStyle;
+ Pointer aPtr( eStyle );
+ SetPointer( aPtr );
+ }
+
+ DockingWindow::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ // Nur bei linker Maustaste ToolBox ausloesen und wenn wir uns nicht
+ // noch in der normalen Bearbeitung befinden
+ if ( rMEvt.IsLeft() && !mbDrag && (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
+ {
+ // Activate schon hier rufen, da gegebenenfalls noch Items
+ // ausgetauscht werden
+ Activate();
+
+ // ToolBox hier updaten, damit der Anwender weiss, was Sache ist
+ if ( mbFormat )
+ {
+ ImplFormat();
+ Update();
+ }
+
+ Point aMousePos = rMEvt.GetPosPixel();
+ USHORT i = 0;
+ USHORT nNewPos = TOOLBOX_ITEM_NOTFOUND;
+
+ // Item suchen, das geklickt wurde
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Ist es dieses Item
+ if ( pItem->maRect.IsInside( aMousePos ) )
+ {
+ // Ist es ein Separator oder ist das Item disabled,
+ // dann mache nichts
+ if ( (pItem->meType == TOOLBOXITEM_BUTTON) &&
+ (!pItem->mbShowWindow || mbCustomizeMode) )
+ nNewPos = i;
+
+ break;
+ }
+
+ i++;
+ pItem = mpItemList->Next();
+ }
+
+ // Item gefunden
+ if ( nNewPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ if ( mbCustomize )
+ {
+ if ( rMEvt.IsMod2() || mbCustomizeMode )
+ {
+ Deactivate();
+
+ ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
+ Rectangle aItemRect = GetItemRect( pItem->mnId );
+ mnConfigItem = pItem->mnId;
+
+ BOOL bResizeItem;
+ if ( mbCustomizeMode && pItem->mbShowWindow &&
+ (pItem->maRect.Right()-TB_RESIZE_OFFSET <= aMousePos.X()) )
+ bResizeItem = TRUE;
+ else
+ bResizeItem = FALSE;
+ pMgr->StartDragging( this, aMousePos, aItemRect, 0, bResizeItem );
+ return;
+ }
+ }
+
+ if ( !pItem->mbEnabled )
+ {
+ Sound::Beep( SOUND_DISABLE, this );
+ Deactivate();
+ return;
+ }
+
+ // Aktuelle Daten setzen
+ USHORT nTrackFlags = 0;
+ mnCurPos = i;
+ mnCurItemId = pItem->mnId;
+ mnDownItemId = mnCurItemId;
+ mnMouseClicks = rMEvt.GetClicks();
+ mnMouseModifier = rMEvt.GetModifier();
+ if ( pItem->mnBits & TIB_REPEAT )
+ nTrackFlags |= STARTTRACK_BUTTONREPEAT;
+
+ if ( mbSelection )
+ {
+ ImplDrawItem( mnCurPos, TRUE );
+ Highlight();
+ }
+ else
+ {
+ // Hier schon bDrag setzen, da in EndSelection ausgewertet wird
+ mbDrag = TRUE;
+
+ // Bei Doppelklick nur den Handler rufen, aber bevor der
+ // Button gehiltet wird, da evt. in diesem Handler der
+ // Drag-Vorgang abgebrochen wird
+ if ( rMEvt.GetClicks() == 2 )
+ DoubleClick();
+
+ if ( mbDrag )
+ {
+ ImplDrawItem( mnCurPos, TRUE );
+ Highlight();
+ }
+
+ // Click-Handler aufrufen
+ if ( rMEvt.GetClicks() != 2 )
+ Click();
+
+ // Bei Repeat auch den Select-Handler rufen
+ if ( nTrackFlags & STARTTRACK_BUTTONREPEAT )
+ Select();
+
+ // Wenn die Aktion nicht im Click-Handler abgebrochen wurde
+ if ( mbDrag )
+ StartTracking( nTrackFlags );
+ }
+
+ // Wenn Maus ueber einem Item gedrueckt wurde, koennen wir
+ // die Bearbeitung abbrechen
+ return;
+ }
+
+ Deactivate();
+
+ // Gegebenenfalls noch Scroll- und Next-Buttons ueberpruefen
+ if ( maUpperRect.IsInside( aMousePos ) )
+ {
+ if ( mnCurLine > 1 )
+ {
+ StartTracking();
+ mbUpper = TRUE;
+ mbIn = TRUE;
+ ImplDrawSpin( TRUE, FALSE );
+ }
+ return;
+ }
+ if ( maLowerRect.IsInside( aMousePos ) )
+ {
+ if ( mnCurLine+mnVisLines-1 < mnCurLines )
+ {
+ StartTracking();
+ mbLower = TRUE;
+ mbIn = TRUE;
+ ImplDrawSpin( FALSE, TRUE );
+ }
+ return;
+ }
+ if ( maNextToolRect.IsInside( aMousePos ) )
+ {
+ StartTracking();
+ mbNextTool = TRUE;
+ mbIn = TRUE;
+ ImplDrawNext( TRUE );
+ return;
+ }
+
+ // Linesizing testen
+ if ( (mnWinStyle & TB_WBLINESIZING) == TB_WBLINESIZING )
+ {
+ USHORT nLineMode = ImplTestLineSize( this, aMousePos );
+ if ( nLineMode )
+ {
+ ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
+
+ // Handler rufen, damit die Dock-Rectangles gesetzt werden
+ // koenen
+ StartDocking();
+
+ Point aPos = GetParent()->OutputToScreenPixel( GetPosPixel() );
+ Size aSize = GetSizePixel();
+ aPos = ScreenToOutputPixel( aPos );
+
+ // Dragging starten
+ pMgr->StartDragging( this, aMousePos, Rectangle( aPos, aSize ),
+ nLineMode, FALSE );
+ return;
+ }
+ }
+
+ // Kein Item, dann nur Click oder DoubleClick
+ if ( rMEvt.GetClicks() == 2 )
+ DoubleClick();
+ else
+ Click();
+ }
+
+ if ( !mbDrag && !mbSelection )
+ DockingWindow::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( ImplHandleMouseButtonUp( rMEvt ) )
+ return;
+
+ if ( mbDragging && (rMEvt.IsLeft() || mbCommandDrag) )
+ {
+ ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
+ pMgr->EndDragging();
+ return;
+ }
+ mbCommandDrag = FALSE;
+
+ DockingWindow::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ ImplHandleMouseButtonUp( rTEvt.GetMouseEvent(), rTEvt.IsTrackingCanceled() );
+ else
+ ImplHandleMouseMove( rTEvt.GetMouseEvent(), rTEvt.IsTrackingRepeat() );
+
+ DockingWindow::Tracking( rTEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Paint( const Rectangle& rPaintRect )
+{
+ if ( rPaintRect == Rectangle( 0, 0, mnDX-1, mnDY-1 ) )
+ mbFullPaint = TRUE;
+ ImplFormat();
+ mbFullPaint = FALSE;
+
+ if ( (mnWinStyle & WB_BORDER) && !IsFloatingMode() )
+ ImplDrawBorder( this );
+
+ // SpinButtons zeichnen
+ if ( mnWinStyle & WB_SCROLL )
+ {
+ if ( mnCurLines > mnLines )
+ ImplDrawSpin( FALSE, FALSE );
+ }
+
+ // NextButton zeichnen
+ ImplDrawNext( FALSE );
+
+ // Buttons zeichnen
+ USHORT nHighPos;
+ if ( mnHighItemId )
+ nHighPos = GetItemPos( mnHighItemId );
+ else
+ nHighPos = TOOLBOX_ITEM_NOTFOUND;
+ USHORT nCount = (USHORT)mpItemList->Count();
+ for( USHORT i = 0; i < nCount; i++ )
+ {
+ ImplToolItem* pItem = mpItemList->GetObject( i );
+
+ // Nur malen, wenn Rechteck im PaintRectangle liegt
+ if ( !pItem->maRect.IsEmpty() && rPaintRect.IsOver( pItem->maRect ) )
+ {
+ BOOL bHighlight = FALSE;
+ if ( i == mnCurPos )
+ bHighlight = 1;
+ else if ( i == nHighPos )
+ bHighlight = 2;
+ ImplDrawItem( i, bHighlight );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Move()
+{
+ DockingWindow::Move();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Resize()
+{
+ long nOldDX = mnDX;
+ long nOldDY = mnDY;
+ Size aSize = GetOutputSizePixel();
+ mnDX = aSize.Width();
+ mnDY = aSize.Height();
+ mnLastResizeDY = 0;
+
+ // Evt. neu formatieren oder neu painten
+ if ( mbScroll )
+ {
+ if ( !mbFormat )
+ {
+ mbFormat = TRUE;
+ if ( IsReallyVisible() )
+ ImplFormat( TRUE );
+ }
+ }
+
+ // Border muss neu ausgegeben werden
+ if ( mnWinStyle & WB_BORDER )
+ {
+ // Da wir sonst beim Paint denken, das alles neu gepaintet wird
+ if ( mbFormat && IsReallyVisible() )
+ Invalidate();
+ else
+ {
+ if ( mnRightBorder )
+ {
+ if ( nOldDX > mnDX )
+ Invalidate( Rectangle( mnDX-mnRightBorder-1, 0, mnDX, mnDY ) );
+ else
+ Invalidate( Rectangle( nOldDX-mnRightBorder-1, 0, nOldDX, nOldDY ) );
+ }
+
+ if ( mnBottomBorder )
+ {
+ if ( nOldDY > mnDY )
+ Invalidate( Rectangle( 0, mnDY-mnBottomBorder-1, mnDX, mnDY ) );
+ else
+ Invalidate( Rectangle( 0, nOldDY-mnBottomBorder-1, nOldDX, nOldDY ) );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::RequestHelp( const HelpEvent& rHEvt )
+{
+ USHORT nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+
+ if ( nItemId )
+ {
+ if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
+ {
+ // Rechteck ermitteln
+ Rectangle aTempRect = GetItemRect( nItemId );
+ Point aPt = OutputToScreenPixel( aTempRect.TopLeft() );
+ aTempRect.Left() = aPt.X();
+ aTempRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aTempRect.BottomRight() );
+ aTempRect.Right() = aPt.X();
+ aTempRect.Bottom() = aPt.Y();
+
+ // Text ermitteln und anzeigen
+ XubString aStr = GetQuickHelpText( nItemId );
+ const XubString& rHelpStr = GetHelpText( nItemId );
+ if ( !aStr.Len() )
+ aStr = GetItemText( nItemId );
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ {
+ if ( rHelpStr.Len() )
+ aStr = rHelpStr;
+ else
+ aStr.EraseAllChars( '~' );
+ Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aTempRect, aStr );
+ }
+ else
+ Help::ShowQuickHelp( this, aTempRect, aStr, rHelpStr, QUICKHELP_CTRLTEXT );
+ return;
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
+ {
+ ULONG nHelpId = GetHelpId( nItemId );
+ if ( nHelpId )
+ {
+ // Wenn eine Hilfe existiert, dann ausloesen
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nHelpId );
+ return;
+ }
+ }
+ }
+ else if ( maNextToolRect.IsInside( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) ) )
+ {
+ if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
+ {
+ // Rechteck ermitteln
+ Rectangle aTempRect = maNextToolRect;
+ Point aPt = OutputToScreenPixel( aTempRect.TopLeft() );
+ aTempRect.Left() = aPt.X();
+ aTempRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aTempRect.BottomRight() );
+ aTempRect.Right() = aPt.X();
+ aTempRect.Bottom() = aPt.Y();
+
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aTempRect.Center(), aTempRect, maNextToolBoxStr );
+ else
+ Help::ShowQuickHelp( this, aTempRect, maNextToolBoxStr );
+ return;
+ }
+ }
+
+ DockingWindow::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long ToolBox::Notify( NotifyEvent& rNEvt )
+{
+ return DockingWindow::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Command( const CommandEvent& rCEvt )
+{
+ // StartDrag auf MouseButton/Left/Alt abbilden
+ if ( (rCEvt.GetCommand() == COMMAND_STARTDRAG) && rCEvt.IsMouseEvent() &&
+ mbCustomize && !mbDragging && !mbDrag && !mbSelection &&
+ (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
+ {
+ // Wir erlauben nur das Draggen von Items. Deshalb muessen wir
+ // testen, ob auch ein Item angeklickt wurde, ansonsten wuerden
+ // wir evt. das Fenster verschieben, was nicht gewollt waere.
+ // Wir machen dieses jedoch nur im Customize-Mode, da ansonsten
+ // Items zuhaeufig ausversehen verschoben werden.
+ if ( mbCustomizeMode )
+ {
+ Point aMousePos = rCEvt.GetMousePosPixel();
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Ist es dieses Item
+ if ( pItem->maRect.IsInside( aMousePos ) )
+ {
+ // Ist es ein Separator oder ist das Item disabled,
+ // dann mache nichts
+ if ( (pItem->meType == TOOLBOXITEM_BUTTON) &&
+ !pItem->mbShowWindow )
+ mbCommandDrag = TRUE;
+ break;
+ }
+
+ pItem = mpItemList->Next();
+ }
+
+ if ( mbCommandDrag )
+ {
+ MouseEvent aMEvt( aMousePos, 1, MOUSE_SIMPLECLICK,
+ MOUSE_LEFT, KEY_MOD2 );
+ ToolBox::MouseButtonDown( aMEvt );
+ return;
+ }
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ if ( (mnCurLine > 1) || (mnCurLine+mnVisLines-1 < mnCurLines) )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
+ {
+ if ( (mnCurLine > 1) && (pData->GetDelta() > 0) )
+ ShowLine( FALSE );
+ else if ( (mnCurLine+mnVisLines-1 < mnCurLines) && (pData->GetDelta() < 0) )
+ ShowLine( TRUE );
+ ImplDrawSpin( FALSE, FALSE );
+ return;
+ }
+ }
+ }
+
+ DockingWindow::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::StateChanged( StateChangedType nType )
+{
+ DockingWindow::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ImplFormat();
+ else if ( nType == STATE_CHANGE_ENABLE )
+ ImplUpdateItem();
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ DockingWindow::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ if ( mpBtnDev )
+ ImplButtonSysChange( this, mpBtnDev, mnOutStyle );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ToolBox::PrepareToggleFloatingMode()
+{
+ return DockingWindow::PrepareToggleFloatingMode();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ToggleFloatingMode()
+{
+ DockingWindow::ToggleFloatingMode();
+
+ if ( IsFloatingMode() )
+ {
+ mbHorz = TRUE;
+ mbScroll = TRUE;
+ SetOutputSizePixel( ImplCalcFloatSize( this, mnFloatLines ) );
+ }
+ else
+ {
+ mbScroll = (mnWinStyle & WB_SCROLL) ? TRUE : FALSE;
+ if ( (meAlign == WINDOWALIGN_TOP) || (meAlign == WINDOWALIGN_BOTTOM) )
+ mbHorz = TRUE;
+ else
+ mbHorz = FALSE;
+ }
+
+ mbFormat = TRUE;
+ ImplFormat();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::StartDocking()
+{
+ meDockAlign = meAlign;
+ mnDockLines = mnLines;
+ mbLastFloatMode = IsFloatingMode();
+ DockingWindow::StartDocking();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ToolBox::Docking( const Point& rPos, Rectangle& rRect )
+{
+ // Wenn Dragging, dann nicht machen, da vorher schon berechnet
+ if ( mbDragging )
+ return FALSE;
+
+ BOOL bFloatMode = FALSE;
+
+ DockingWindow::Docking( rPos, rRect );
+
+ // Befindet sich die Maus ausserhalb des Bereichs befindet, kann es nur ein
+ // FloatWindow werden
+ if ( maOutDockRect.IsInside( rPos ) && !IsDockingPrevented() )
+ {
+ Rectangle aInRect = maInDockRect;
+ Size aDockSize;
+ aDockSize.Width() = ImplCalcSize( this, mnLines, TB_CALCMODE_VERT ).Width();
+ aDockSize.Height() = ImplCalcSize( this, mnLines, TB_CALCMODE_HORZ ).Height();
+ aInRect.Left() += aDockSize.Width()/2;
+ aInRect.Top() += aDockSize.Height()/2;
+ aInRect.Right() -= aDockSize.Width()/2;
+ aInRect.Bottom() -= aDockSize.Height()/2;
+
+ // Auf den Dockbereich eine halbe Breite der ToolBox dazurechnen
+ if ( !IsFloatingMode() )
+ {
+ if ( meAlign == WINDOWALIGN_LEFT )
+ aInRect.Left() -= aDockSize.Width()/2;
+ else if ( meAlign == WINDOWALIGN_TOP )
+ aInRect.Top() -= aDockSize.Height()/2;
+ else if ( meAlign == WINDOWALIGN_RIGHT )
+ aInRect.Right() += aDockSize.Width()/2;
+ else
+ aInRect.Bottom() += aDockSize.Height()/2;
+ }
+
+ // Wenn Fenster zu klein, wird das gesammte InDock-Rect genommen
+ if ( aInRect.Left() >= aInRect.Right() )
+ {
+ aInRect.Left() = maInDockRect.Left();
+ aInRect.Right() = maInDockRect.Right();
+ }
+ if ( aInRect.Top() >= aInRect.Bottom() )
+ {
+ aInRect.Top() = maInDockRect.Top();
+ aInRect.Bottom() = maInDockRect.Bottom();
+ }
+
+ // Wenn Maus nicht im Dock-Bereich, dann kann es nur zum
+ // FloatWindow werden
+ if ( aInRect.IsInside( rPos ) )
+ bFloatMode = TRUE;
+ else
+ {
+ // Wird befinden uns im Dock-Bereich. Jetzt muessen wir
+ // feststellen, an welcher Kante angedockt werden soll
+ Point aInPos( rPos.X()-aInRect.Left(), rPos.Y()-aInRect.Top() );
+ Size aInSize = aInRect.GetSize();
+ Size aOutSize = maOutDockRect.GetSize();
+ USHORT nQuadrant = 0;
+
+ if ( aInPos.Y() > aInSize.Height()/2 )
+ nQuadrant += 2;
+ if ( aInPos.X() > aInSize.Width()/2 )
+ nQuadrant++;
+
+ if ( nQuadrant == 0 )
+ {
+ if ( aInPos.X() >= aInPos.Y() )
+ meDockAlign = WINDOWALIGN_TOP;
+ else
+ meDockAlign = WINDOWALIGN_LEFT;
+ }
+ else if ( nQuadrant == 1 )
+ {
+ if ( aInSize.Width()-aInPos.X() >= aInPos.Y() )
+ meDockAlign = WINDOWALIGN_TOP;
+ else
+ meDockAlign = WINDOWALIGN_RIGHT;
+ }
+ else if ( nQuadrant == 2 )
+ {
+ if ( aInPos.X() <= aInSize.Height()-aInPos.Y() )
+ meDockAlign = WINDOWALIGN_LEFT;
+ else
+ meDockAlign = WINDOWALIGN_BOTTOM;
+ }
+ else
+ {
+ if ( (rPos.X() >= aInRect.Right()) &&
+ (rPos.Y() >= aInRect.Bottom()) )
+ {
+ if ( aInSize.Height()-aInPos.Y() <
+ aInSize.Width()-aInPos.X() )
+ meDockAlign = WINDOWALIGN_RIGHT;
+ else
+ meDockAlign = WINDOWALIGN_BOTTOM;
+ }
+ else
+ {
+ if ( rPos.X() >= aInRect.Right() )
+ meDockAlign = WINDOWALIGN_RIGHT;
+ else
+ meDockAlign = WINDOWALIGN_BOTTOM;
+ }
+ }
+
+ // Wenn sich Dock-Align geaendert hat, muessen wir die
+ // neue Dock-Groesse setzen
+ if ( (meDockAlign == WINDOWALIGN_TOP) || (meDockAlign == WINDOWALIGN_BOTTOM) )
+ aDockSize.Width() = aOutSize.Width();
+ else
+ aDockSize.Height() = aOutSize.Height();
+ rRect.SetSize( aDockSize );
+ }
+ }
+ else
+ bFloatMode = TRUE;
+
+ if ( bFloatMode )
+ {
+ meDockAlign = meAlign;
+ if ( !mbLastFloatMode )
+ {
+ USHORT nTemp = 0;
+ rRect.SetSize( ImplCalcFloatSize( this, nTemp ) );
+ }
+ }
+
+ // Ist Pointer nicht mehr im Rechteck
+ if ( !rRect.IsInside( rPos ) )
+ {
+ Point aMouseOff;
+ aMouseOff.X() = rRect.Left() - rPos.X();
+ aMouseOff.Y() = rRect.Top() - rPos.Y();
+
+ if ( (rPos.X() < rRect.Left()) || (rPos.X() > rRect.Right()) )
+ {
+ rRect.SetPos( rPos );
+ rRect.Move( -5, aMouseOff.Y() );
+ }
+ if ( (rPos.Y() < rRect.Top()) || (rPos.Y() > rRect.Bottom()) )
+ {
+ rRect.SetPos( rPos );
+ rRect.Move( aMouseOff.X(), -5 );
+ }
+ }
+
+ mbLastFloatMode = bFloatMode;
+
+ return bFloatMode;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::EndDocking( const Rectangle& rRect, BOOL bFloatMode )
+{
+ if ( !IsDockingCanceled() )
+ {
+ if ( mnLines != mnDockLines )
+ SetLineCount( mnDockLines );
+ if ( meAlign != meDockAlign )
+ SetAlign( meDockAlign );
+ }
+
+ if ( bFloatMode || (bFloatMode != IsFloatingMode()) )
+ DockingWindow::EndDocking( rRect, bFloatMode );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Resizing( Size& rSize )
+{
+ USHORT nCalcLines;
+ USHORT nTemp;
+
+ // Alle Floatinggroessen berechnen
+ ImplCalcFloatSizes( this );
+
+ if ( !mnLastResizeDY )
+ mnLastResizeDY = mnDY;
+
+ // Ist vertikales Resizing angesagt
+ if ( (mnLastResizeDY != rSize.Height()) && (mnDY != rSize.Height()) )
+ {
+ nCalcLines = ImplCalcLines( this, rSize.Height() );
+ if ( nCalcLines < 1 )
+ nCalcLines = 1;
+ rSize = ImplCalcFloatSize( this, nCalcLines );
+ }
+ else
+ {
+ nCalcLines = 1;
+ nTemp = nCalcLines;
+ Size aTempSize = ImplCalcFloatSize( this, nTemp );
+ while ( (aTempSize.Width() > rSize.Width()) &&
+ (nCalcLines <= mpFloatSizeAry[0].mnLines) )
+ {
+ nCalcLines++;
+ nTemp = nCalcLines;
+ aTempSize = ImplCalcFloatSize( this, nTemp );
+ }
+ rSize = aTempSize;
+ }
+
+ mnLastResizeDY = rSize.Height();
+}
+
+// -----------------------------------------------------------------------
+
+Size ToolBox::CalcWindowSizePixel( USHORT nCalcLines ) const
+{
+ return ImplCalcSize( this, nCalcLines );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::EnableCustomize( BOOL bEnable )
+{
+ if ( bEnable != mbCustomize )
+ {
+ mbCustomize = bEnable;
+
+ ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
+ if ( bEnable )
+ pMgr->Insert( this );
+ else
+ pMgr->Remove( this );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::StartCustomize( const Rectangle& rRect, void* pData )
+{
+ DBG_ASSERT( mbCustomize,
+ "ToolBox::StartCustomize(): ToolBox must be customized" );
+
+ ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
+ Point aMousePos = GetPointerPosPixel();
+ Point aPos = ScreenToOutputPixel( rRect.TopLeft() );
+ Rectangle aRect( aPos.X(), aPos.Y(),
+ aPos.X()+rRect.GetWidth()+SMALLBUTTON_HSIZE,
+ aPos.Y()+rRect.GetHeight()+SMALLBUTTON_VSIZE );
+ aMousePos = ScreenToOutputPixel( aPos );
+ Pointer aPtr;
+ SetPointer( aPtr );
+ pMgr->StartDragging( this, aMousePos, aRect, 0, FALSE, pData );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::StartCustomizeMode()
+{
+ ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
+ pMgr->StartCustomizeMode();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::EndCustomizeMode()
+{
+ ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
+ pMgr->EndCustomizeMode();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ToolBox::IsCustomizeMode()
+{
+ ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
+ return pMgr->IsCustomizeMode();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::GetAccessObject( AccessObjectRef& rAcc ) const
+{
+ rAcc = new AccessObject( (void*) this, ACCESS_TYPE_TOOLBOX );
+}
diff --git a/vcl/source/window/toolbox2.cxx b/vcl/source/window/toolbox2.cxx
new file mode 100644
index 000000000000..c55da3f278ad
--- /dev/null
+++ b/vcl/source/window/toolbox2.cxx
@@ -0,0 +1,1401 @@
+/*************************************************************************
+ *
+ * $RCSfile: toolbox2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_TOOLBOX_CXX
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#define private public
+#ifndef _SV_TOOLBOX_HXX
+#include <toolbox.hxx>
+#endif
+#undef private
+#ifndef _SV_TOOLBOX_H
+#include <toolbox.h>
+#endif
+
+// =======================================================================
+
+#define TB_SEP_SIZE 8
+
+// -----------------------------------------------------------------------
+
+ImplToolItem::ImplToolItem()
+{
+ mnId = 0;
+ mpWindow = NULL;
+ mpUserData = NULL;
+ mnHelpId = 0;
+ meType = TOOLBOXITEM_BUTTON;
+ mnBits = 0;
+ meState = STATE_NOCHECK;
+ mbEnabled = TRUE;
+ mbVisible = TRUE;
+ mbEmptyBtn = TRUE;
+ mbShowWindow = FALSE;
+ mbBreak = FALSE;
+ mnNonStdSize = 0;
+ mnSepSize = TB_SEP_SIZE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplToolItem::ImplToolItem( USHORT nItemId, const Image& rImage,
+ ToolBoxItemBits nItemBits ) :
+ maImage( rImage )
+{
+ mnId = nItemId;
+ mpWindow = NULL;
+ mpUserData = NULL;
+ mnHelpId = 0;
+ meType = TOOLBOXITEM_BUTTON;
+ mnBits = nItemBits;
+ meState = STATE_NOCHECK;
+ mbEnabled = TRUE;
+ mbVisible = TRUE;
+ mbEmptyBtn = FALSE;
+ mbShowWindow = FALSE;
+ mbBreak = FALSE;
+ mnNonStdSize = 0;
+ mnSepSize = TB_SEP_SIZE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplToolItem::ImplToolItem( USHORT nItemId, const XubString& rText,
+ ToolBoxItemBits nItemBits ) :
+ maText( rText )
+{
+ mnId = nItemId;
+ mpWindow = NULL;
+ mpUserData = NULL;
+ mnHelpId = 0;
+ meType = TOOLBOXITEM_BUTTON;
+ mnBits = nItemBits;
+ meState = STATE_NOCHECK;
+ mbEnabled = TRUE;
+ mbVisible = TRUE;
+ mbEmptyBtn = FALSE;
+ mbShowWindow = FALSE;
+ mbBreak = FALSE;
+ mnNonStdSize = 0;
+ mnSepSize = TB_SEP_SIZE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplToolItem::ImplToolItem( USHORT nItemId, const Image& rImage,
+ const XubString& rText, ToolBoxItemBits nItemBits ) :
+ maImage( rImage ),
+ maText( rText )
+{
+ mnId = nItemId;
+ mpWindow = NULL;
+ mpUserData = NULL;
+ mnHelpId = 0;
+ meType = TOOLBOXITEM_BUTTON;
+ mnBits = nItemBits;
+ meState = STATE_NOCHECK;
+ mbEnabled = TRUE;
+ mbVisible = TRUE;
+ mbEmptyBtn = FALSE;
+ mbShowWindow = FALSE;
+ mbBreak = FALSE;
+ mnNonStdSize = 0;
+ mnSepSize = TB_SEP_SIZE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplToolItem::~ImplToolItem()
+{
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& ToolBox::ImplConvertMenuString( const XubString& rStr )
+{
+ if ( mbMenuStrings )
+ {
+ maCvtStr = rStr;
+ maCvtStr.EraseTrailingChars( '.' );
+ maCvtStr.EraseAllChars( '~' );
+ return maCvtStr;
+ }
+ else
+ return rStr;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplInvalidate( BOOL bNewCalc, BOOL bFullPaint )
+{
+ if ( bNewCalc )
+ mbCalc = TRUE;
+
+ if ( bFullPaint )
+ {
+ mbFormat = TRUE;
+
+ // Muss ueberhaupt eine neue Ausgabe erfolgen
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ Invalidate( Rectangle( mnLeftBorder, mnTopBorder,
+ mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) );
+ maTimer.Stop();
+ }
+ }
+ else
+ {
+ if ( !mbFormat )
+ {
+ mbFormat = TRUE;
+
+ // Muss ueberhaupt eine neue Ausgabe erfolgen
+ if ( IsReallyVisible() && IsUpdateMode() )
+ maTimer.Start();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ImplUpdateItem( USHORT nIndex )
+{
+ // Muss ueberhaupt eine neue Ausgabe erfolgen
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ if ( nIndex == 0xFFFF )
+ {
+ // Nur direkt neu ausgeben, wenn nicht neu formatiert
+ // werden muss
+ if ( !mbFormat )
+ {
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ for ( USHORT i = 0; i < nItemCount; i++ )
+ ImplDrawItem( i, (i == mnCurPos) ? TRUE : FALSE );
+ }
+ else
+ {
+ Invalidate( Rectangle( mnLeftBorder, mnTopBorder,
+ mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) );
+ }
+ }
+ else
+ {
+ // Nur direkt neu ausgeben, wenn nicht neu formatiert
+ // werden muss
+ if ( !mbFormat )
+ ImplDrawItem( nIndex, (nIndex == mnCurPos) ? TRUE : FALSE );
+ else
+ maPaintRect.Union( mpItemList->GetObject( nIndex )->maRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Click()
+{
+ maClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Activate()
+{
+ maActivateHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Deactivate()
+{
+ maDeactivateHdl.Call( this );
+
+ if ( mbHideStatusText )
+ {
+ GetpApp()->HideHelpStatusText();
+ mbHideStatusText = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Highlight()
+{
+ maHighlightHdl.Call( this );
+
+ XubString aStr = GetHelpText( mnCurItemId );
+ if ( aStr.Len() || mbHideStatusText )
+ {
+ GetpApp()->ShowHelpStatusText( aStr );
+ mbHideStatusText = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::NextToolBox()
+{
+ maNextToolBoxHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Customize( const ToolBoxCustomizeEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::UserDraw( const UserDrawEvent& rUDEvt )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::InsertItem( const ResId& rResId, USHORT nPos )
+{
+ USHORT nObjMask;
+ BOOL bImage = FALSE; // Wurde Image gesetzt
+
+ // Item anlegen
+ ImplToolItem* pItem = new ImplToolItem;
+
+ GetRes( rResId.SetRT( RSC_TOOLBOXITEM ) );
+ nObjMask = ReadShortRes();
+
+ if ( nObjMask & RSC_TOOLBOXITEM_ID )
+ pItem->mnId = ReadShortRes();
+ else
+ pItem->mnId = 1;
+
+ if ( nObjMask & RSC_TOOLBOXITEM_TYPE )
+ pItem->meType = (ToolBoxItemType)ReadShortRes();
+
+ if ( nObjMask & RSC_TOOLBOXITEM_STATUS )
+ pItem->mnBits = (ToolBoxItemBits)ReadShortRes();
+
+ if( nObjMask & RSC_TOOLBOXITEM_HELPID )
+ pItem->mnHelpId = ReadLongRes();
+
+ if ( nObjMask & RSC_TOOLBOXITEM_TEXT )
+ {
+ pItem->maText = ReadStringRes();
+ pItem->maText = ImplConvertMenuString( pItem->maText );
+ }
+ if ( nObjMask & RSC_TOOLBOXITEM_HELPTEXT )
+ pItem->maHelpText = ReadStringRes();
+
+/*
+#ifndef WIN
+ static
+#endif
+ short nHelpMode = -1;
+ if( nHelpMode == -1 ) {
+ SvHelpSettings aHelpSettings;
+
+ GetpApp()->Property( aHelpSettings );
+ nHelpMode = aHelpSettings.nHelpMode;
+ }
+
+ if( (nHelpMode & HELPTEXTMODE_EXTERN) && pItem->aHelpText.Len() )
+ pItem->aHelpText.Erase();
+ if( (nHelpMode & HELPTEXTMODE_DEBUG) && !pItem->nHelpId )
+ pItem->aHelpText = "??? !pItem->nHelpId MP/W.P. ???";
+*/
+
+ if ( nObjMask & RSC_TOOLBOXITEM_BITMAP )
+ {
+ Bitmap aBmp = Bitmap( ResId( (RSHEADER_TYPE*)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ pItem->maImage = Image( aBmp, IMAGE_STDBTN_COLOR );
+ bImage = TRUE;
+ }
+ if ( nObjMask & RSC_TOOLBOXITEM_IMAGE )
+ {
+ pItem->maImage = Image( ResId( (RSHEADER_TYPE*)GetClassRes() ) );
+ IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
+ bImage = TRUE;
+ }
+ if ( nObjMask & RSC_TOOLBOXITEM_DISABLE )
+ pItem->mbEnabled = !(BOOL)ReadShortRes();
+
+ if ( nObjMask & RSC_TOOLBOXITEM_STATE )
+ pItem->meState = (TriState)ReadShortRes();
+
+ if ( nObjMask & RSC_TOOLBOXITEM_HIDE )
+ pItem->mbVisible = !((BOOL)ReadShortRes());
+
+ if ( nObjMask & RSC_TOOLBOXITEM_COMMAND )
+ pItem->maCommandStr = ReadStringRes();
+
+ // Wenn kein Image geladen wurde, versuchen wir das Image aus der
+ // Image-Liste zu holen
+ if ( !bImage && pItem->mnId )
+ pItem->maImage = maImageList.GetImage( pItem->mnId );
+
+ // Wenn es sich um ein ButtonItem handelt, die ID ueberpruefen
+ BOOL bNewCalc;
+ if ( pItem->meType != TOOLBOXITEM_BUTTON )
+ {
+ bNewCalc = FALSE;
+ pItem->mnId = 0;
+ }
+ else
+ {
+ bNewCalc = TRUE;
+
+ DBG_ASSERT( pItem->mnId, "ToolBox::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( pItem->mnId ) == TOOLBOX_ITEM_NOTFOUND,
+ "ToolBox::InsertItem(): ItemId already exists" );
+ }
+
+ // Item anlegen und in die Liste einfuegen
+ mpItemList->Insert( pItem, nPos );
+
+ // ToolBox neu brechnen und neu ausgeben
+ ImplInvalidate( bNewCalc );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::InsertItem( USHORT nItemId, const Image& rImage,
+ ToolBoxItemBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
+ "ToolBox::InsertItem(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ mpItemList->Insert( new ImplToolItem( nItemId, rImage, nBits ), nPos );
+
+ ImplInvalidate( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::InsertItem( USHORT nItemId, const Image& rImage,
+ const XubString& rText,
+ ToolBoxItemBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
+ "ToolBox::InsertItem(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ mpItemList->Insert( new ImplToolItem( nItemId, rImage, ImplConvertMenuString( rText ), nBits ), nPos );
+
+ ImplInvalidate( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::InsertItem( USHORT nItemId, const XubString& rText,
+ ToolBoxItemBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
+ "ToolBox::InsertItem(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ mpItemList->Insert( new ImplToolItem( nItemId, ImplConvertMenuString( rText ), nBits ), nPos );
+
+ ImplInvalidate( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::InsertWindow( USHORT nItemId, Window* pWindow,
+ ToolBoxItemBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ToolBox::InsertWindow(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
+ "ToolBox::InsertWindow(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ ImplToolItem* pItem = new ImplToolItem;
+ pItem->mnId = nItemId;
+ pItem->meType = TOOLBOXITEM_BUTTON;
+ pItem->mnBits = nBits;
+ pItem->mpWindow = pWindow;
+ mpItemList->Insert( pItem, nPos );
+
+ if ( pWindow )
+ pWindow->Hide();
+
+ ImplInvalidate( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::InsertSpace( USHORT nPos )
+{
+ // Item anlegen und in die Liste einfuegen
+ ImplToolItem* pItem = new ImplToolItem;
+ pItem->meType = TOOLBOXITEM_SPACE;
+ pItem->mbEnabled = FALSE;
+ mpItemList->Insert( pItem, nPos );
+
+ ImplInvalidate( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::InsertSeparator( USHORT nPos, USHORT nPixSize )
+{
+ // Item anlegen und in die Liste einfuegen
+ ImplToolItem* pItem = new ImplToolItem;
+ pItem->meType = TOOLBOXITEM_SEPARATOR;
+ pItem->mbEnabled = FALSE;
+ if ( nPixSize )
+ pItem->mnSepSize = nPixSize;
+ mpItemList->Insert( pItem, nPos );
+
+ ImplInvalidate( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::InsertBreak( USHORT nPos )
+{
+ // Item anlegen und in die Liste einfuegen
+ ImplToolItem* pItem = new ImplToolItem;
+ pItem->meType = TOOLBOXITEM_BREAK;
+ pItem->mbEnabled = FALSE;
+ mpItemList->Insert( pItem, nPos );
+
+ ImplInvalidate( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::RemoveItem( USHORT nPos )
+{
+ ImplToolItem* pItem = mpItemList->Remove( nPos );
+
+ // Item entfernen
+ if ( pItem )
+ {
+ BOOL bMustCalc;
+ if ( pItem->meType == TOOLBOXITEM_BUTTON )
+ bMustCalc = TRUE;
+ else
+ bMustCalc = FALSE;
+
+ if ( pItem->mpWindow )
+ pItem->mpWindow->Hide();
+
+ // PaintRect um das removete Item erweitern
+ maPaintRect.Union( pItem->maRect );
+
+ // Absichern gegen das Loeschen im Select-Handler
+ if ( pItem->mnId == mnCurItemId )
+ mnCurItemId = 0;
+ if ( pItem->mnId == mnHighItemId )
+ mnHighItemId = 0;
+
+ ImplInvalidate( bMustCalc );
+
+ delete pItem;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::MoveItem( USHORT nItemId, USHORT nNewPos )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos < nNewPos )
+ nNewPos--;
+
+ if ( nPos == nNewPos )
+ return;
+
+ // Existiert Item
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ // ToolBox-Item in der Liste verschieben
+ ImplToolItem* pItem = mpItemList->Remove( nPos );
+ mpItemList->Insert( pItem, nNewPos );
+
+ // ToolBox neu ausgeben
+ ImplInvalidate( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::CopyItem( const ToolBox& rToolBox, USHORT nItemId,
+ USHORT nNewPos )
+{
+ DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
+ "ToolBox::CopyItem(): ItemId already exists" );
+
+ USHORT nPos = rToolBox.GetItemPos( nItemId );
+
+ // Existiert Item
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ // ToolBox-Item in der Liste verschieben
+ ImplToolItem* pItem = rToolBox.mpItemList->GetObject( nPos );
+ ImplToolItem* pNewItem = new ImplToolItem( *pItem );
+ mpItemList->Insert( pNewItem, nNewPos );
+ // Bestimme Daten zuruecksetzen
+ pNewItem->mpWindow = NULL;
+ pNewItem->mbShowWindow = FALSE;
+
+ // ToolBox neu ausgeben
+ ImplInvalidate( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::CopyItems( const ToolBox& rToolBox )
+{
+ ImplToolItem* pItem;
+
+ // Alle Items entfernen
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Items aus der Liste loeschen
+ mpItemList->Clear();
+
+ // Absichern gegen das Loeschen im Select-Handler
+ mnCurItemId = 0;
+ mnHighItemId = 0;
+
+ // Items kopieren
+ ULONG i = 0;
+ pItem = rToolBox.mpItemList->GetObject( i );
+ while ( pItem )
+ {
+ ImplToolItem* pNewItem = new ImplToolItem( *pItem );
+ mpItemList->Insert( pNewItem, LIST_APPEND );
+ // Bestimme Daten zuruecksetzen
+ pNewItem->mpWindow = NULL;
+ pNewItem->mbShowWindow = FALSE;
+ i++;
+ pItem = rToolBox.mpItemList->GetObject( i );
+ }
+
+ ImplInvalidate( TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::Clear()
+{
+ ImplToolItem* pItem;
+
+ // Alle Item loeschen
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Items aus der Liste loeschen
+ mpItemList->Clear();
+
+ // Absichern gegen das Loeschen im Select-Handler
+ mnCurItemId = 0;
+ mnHighItemId = 0;
+
+ ImplInvalidate( TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetButtonType( ButtonType eNewType )
+{
+ if ( meButtonType != eNewType )
+ {
+ meButtonType = eNewType;
+
+ // Hier besser alles neu ausgeben, da es ansonsten zu Problemen
+ // mit den per CopyBits kopierten Bereichen geben kann
+ ImplInvalidate( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetAlign( WindowAlign eNewAlign )
+{
+ if ( meAlign != eNewAlign )
+ {
+ meAlign = eNewAlign;
+
+ if ( !IsFloatingMode() )
+ {
+ // Setzen, ob Items horizontal oder vertikal angeordnet werden sollen
+ if ( (eNewAlign == WINDOWALIGN_LEFT) || (eNewAlign == WINDOWALIGN_RIGHT) )
+ mbHorz = FALSE;
+ else
+ mbHorz = TRUE;
+
+ // Hier alles neu ausgeben, da sich Border auch aendert
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetLineCount( USHORT nNewLines )
+{
+ if ( !nNewLines )
+ nNewLines = 1;
+
+ if ( mnLines != nNewLines )
+ {
+ mnLines = nNewLines;
+
+ // Hier besser alles neu ausgeben, da es ansonsten zu Problemen
+ // mit den per CopyBits kopierten Bereichen geben kann
+ ImplInvalidate( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetNextToolBox( const XubString& rStr )
+{
+ BOOL bCalcNew = (!maNextToolBoxStr.Len() != !rStr.Len());
+ maNextToolBoxStr = rStr;
+ if ( bCalcNew )
+ ImplInvalidate( TRUE, FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ToolBox::GetItemCount() const
+{
+ return (USHORT)mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+ToolBoxItemType ToolBox::GetItemType( USHORT nPos ) const
+{
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem )
+ return pItem->meType;
+ else
+ return TOOLBOXITEM_DONTKNOW;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ToolBox::GetItemPos( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nItemId )
+ return (USHORT)mpItemList->GetCurPos();
+
+ pItem = mpItemList->Next();
+ }
+
+ return TOOLBOX_ITEM_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ToolBox::GetItemId( USHORT nPos ) const
+{
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem )
+ return pItem->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ToolBox::GetItemId( const Point& rPos ) const
+{
+ // Item suchen, das geklickt wurde
+ ImplToolItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Ist es dieses Item
+ if ( pItem->maRect.IsInside( rPos ) )
+ {
+ if ( pItem->meType == TOOLBOXITEM_BUTTON )
+ return pItem->mnId;
+ else
+ return 0;
+ }
+
+ pItem = mpItemList->Next();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle ToolBox::GetItemRect( USHORT nItemId ) const
+{
+ if ( mbCalc || mbFormat )
+ ((ToolBox*)this)->ImplFormat();
+
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maRect;
+ else
+ return Rectangle();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetItemBits( USHORT nItemId, ToolBoxItemBits nBits )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+ ToolBoxItemBits nOldBits = pItem->mnBits;
+ pItem->mnBits = nBits;
+ nBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN;
+ nOldBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN;
+ if ( nBits != nOldBits )
+ ImplInvalidate( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ToolBoxItemBits ToolBox::GetItemBits( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->mnBits;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetItemData( USHORT nItemId, void* pNewData )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+ pItem->mpUserData = pNewData;
+ ImplUpdateItem( nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void* ToolBox::GetItemData( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->mpUserData;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetItemImage( USHORT nItemId, const Image& rImage )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+ // Nur wenn alles berechnet ist, mehr Aufwand treiben
+ if ( !mbCalc )
+ {
+ Size aOldSize = pItem->maImage.GetSizePixel();
+ pItem->maImage = rImage;
+ if ( aOldSize != pItem->maImage.GetSizePixel() )
+ ImplInvalidate( TRUE );
+ else
+ ImplUpdateItem( nPos );
+ }
+ else
+ pItem->maImage = rImage;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image ToolBox::GetItemImage( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->maImage;
+ else
+ return Image();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetItemHighImage( USHORT nItemId, const Image& rImage )
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+ if ( pItem )
+ {
+ DBG_ASSERT( (pItem->maImage.GetSizePixel() == rImage.GetSizePixel()) ||
+ ((!rImage) == TRUE), "ToolBox::SetItemHighImage() - ImageSize != HighImageSize" );
+ pItem->maHighImage = rImage;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image ToolBox::GetItemHighImage( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->maHighImage;
+ else
+ return Image();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetItemText( USHORT nItemId, const XubString& rText )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+ // Nur wenn alles berechnet ist, mehr Aufwand treiben
+ if ( !mbCalc &&
+ ((meButtonType != BUTTON_SYMBOL) || !pItem->maImage) )
+ {
+ long nOldWidth = GetCtrlTextWidth( pItem->maText );
+ pItem->maText = ImplConvertMenuString( rText );
+ if ( nOldWidth != GetCtrlTextWidth( pItem->maText ) )
+ ImplInvalidate( TRUE );
+ else
+ ImplUpdateItem( nPos );
+ }
+ else
+ pItem->maText = ImplConvertMenuString( rText );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& ToolBox::GetItemText( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->maText;
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetItemWindow( USHORT nItemId, Window* pNewWindow )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+ pItem->mpWindow = pNewWindow;
+ if ( pNewWindow )
+ pNewWindow->Hide();
+ ImplInvalidate( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Window* ToolBox::GetItemWindow( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->mpWindow;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::StartSelection()
+{
+ if ( mbDrag )
+ EndSelection();
+
+ if ( !mbSelection )
+ {
+ mbSelection = TRUE;
+ mnCurPos = TOOLBOX_ITEM_NOTFOUND;
+ mnCurItemId = 0;
+ Activate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::EndSelection()
+{
+ mbCommandDrag = FALSE;
+
+ if ( mbDrag || mbSelection )
+ {
+ // Daten zuruecksetzen
+ mbDrag = FALSE;
+ mbSelection = FALSE;
+ if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
+ ImplDrawItem( mnCurPos );
+ EndTracking();
+ ReleaseMouse();
+ Deactivate();
+ }
+
+ mnCurPos = TOOLBOX_ITEM_NOTFOUND;
+ mnCurItemId = 0;
+ mnDownItemId = 0;
+ mnMouseClicks = 0;
+ mnMouseModifier = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetItemDown( USHORT nItemId, BOOL bDown, BOOL bRelease )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ if ( bDown )
+ {
+ if ( nPos != mnCurPos )
+ {
+ mnCurPos = nPos;
+ ImplDrawItem( mnCurPos );
+ }
+ }
+ else
+ {
+ if ( nPos == mnCurPos )
+ {
+ ImplDrawItem( mnCurPos );
+ mnCurPos = TOOLBOX_ITEM_NOTFOUND;
+ }
+ }
+
+ if ( bRelease )
+ {
+ if ( mbDrag || mbSelection )
+ {
+ mbDrag = FALSE;
+ mbSelection = FALSE;
+ EndTracking();
+ ReleaseMouse();
+ Deactivate();
+ }
+
+ mnCurItemId = 0;
+ mnDownItemId = 0;
+ mnMouseClicks = 0;
+ mnMouseModifier = 0;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ToolBox::IsItemDown( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ return (nPos == mnCurPos);
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetItemState( USHORT nItemId, TriState eState )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+
+ // Hat sich der Status geaendert
+ if ( pItem->meState != eState )
+ {
+ // Wenn RadioCheck, dann vorherigen unchecken
+ if ( (eState == STATE_CHECK) && (pItem->mnBits & TIB_AUTOCHECK) &&
+ (pItem->mnBits & TIB_RADIOCHECK) )
+ {
+ ImplToolItem* pGroupItem;
+ USHORT nGroupPos;
+ USHORT nItemCount = GetItemCount();
+
+ nGroupPos = nPos;
+ while ( nGroupPos )
+ {
+ pGroupItem = mpItemList->GetObject( nGroupPos-1 );
+ if ( pGroupItem->mnBits & TIB_RADIOCHECK )
+ {
+ if ( pGroupItem->meState != STATE_NOCHECK )
+ SetItemState( pGroupItem->mnId, STATE_NOCHECK );
+ }
+ else
+ break;
+ nGroupPos--;
+ }
+
+ nGroupPos = nPos+1;
+ while ( nGroupPos < nItemCount )
+ {
+ pGroupItem = mpItemList->GetObject( nGroupPos );
+ if ( pGroupItem->mnBits & TIB_RADIOCHECK )
+ {
+ if ( pGroupItem->meState != STATE_NOCHECK )
+ SetItemState( pGroupItem->mnId, STATE_NOCHECK );
+ }
+ else
+ break;
+ nGroupPos++;
+ }
+ }
+
+ pItem->meState = eState;
+ ImplUpdateItem( nPos );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+TriState ToolBox::GetItemState( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->meState;
+ else
+ return STATE_NOCHECK;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::EnableItem( USHORT nItemId, BOOL bEnable )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+ if ( bEnable )
+ bEnable = TRUE;
+ if ( pItem->mbEnabled != bEnable )
+ {
+ pItem->mbEnabled = bEnable;
+
+ // Gegebenenfalls das Fenster mit updaten
+ if ( pItem->mpWindow )
+ pItem->mpWindow->Enable( pItem->mbEnabled );
+
+ // Item updaten
+ ImplUpdateItem( nPos );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ToolBox::IsItemEnabled( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->mbEnabled;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::ShowItem( USHORT nItemId, BOOL bVisible )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != TOOLBOX_ITEM_NOTFOUND )
+ {
+ ImplToolItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem->mbVisible != bVisible )
+ {
+ pItem->mbVisible = bVisible;
+ ImplInvalidate( FALSE );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ToolBox::IsItemVisible( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->mbVisible;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetItemCommand( USHORT nItemId, const XubString& rCommand )
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ pItem->maCommandStr = rCommand;
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& ToolBox::GetItemCommand( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->maCommandStr;
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetQuickHelpText( USHORT nItemId, const XubString& rText )
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ pItem->maQuickHelpText = rText;
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& ToolBox::GetQuickHelpText( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->maQuickHelpText;
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetHelpText( USHORT nItemId, const XubString& rText )
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ pItem->maHelpText = rText;
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& ToolBox::GetHelpText( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ {
+ if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId );
+ }
+
+ return pItem->maHelpText;
+ }
+ else
+ return ImplGetSVEmptyStr();
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetHelpId( USHORT nItemId, ULONG nHelpId )
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ pItem->mnHelpId = nHelpId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG ToolBox::GetHelpId( USHORT nItemId ) const
+{
+ ImplToolItem* pItem = ImplGetItem( nItemId );
+
+ if ( pItem )
+ return pItem->mnHelpId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetBorder( long nX, long nY )
+{
+ mnBorderX = nX;
+ mnBorderY = nY;
+
+ ImplInvalidate( TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::SetOutStyle( USHORT nNewStyle )
+{
+ if ( mnOutStyle != nNewStyle )
+ {
+ mnOutStyle = nNewStyle;
+
+ // Damit das ButtonDevice neu angelegt wird
+ if ( !(mnOutStyle & TOOLBOX_STYLE_FLAT) )
+ {
+ mnItemWidth = 1;
+ mnItemHeight = 1;
+ }
+
+ ImplInvalidate( TRUE, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ToolBox::RecalcItems()
+{
+ ImplInvalidate( TRUE );
+}
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
new file mode 100644
index 000000000000..af07c5df38c1
--- /dev/null
+++ b/vcl/source/window/window.cxx
@@ -0,0 +1,6539 @@
+/*************************************************************************
+ *
+ * $RCSfile: window.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_WINDOW_CXX
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGTYPE_HXX
+#include <salgtype.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_WINDATA_HXX
+#include <windata.hxx>
+#endif
+#ifndef _SV_DBGGUI_HXX
+#include <dbggui.hxx>
+#endif
+#ifndef _SV_ACCESS_HXX
+#include <access.hxx>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_REGION_H
+#include <region.h>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_CURSOR_HXX
+#include <cursor.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_SYSWIN_HXX
+#include <syswin.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+#ifndef _SV_HELPWIN_HXX
+#include <helpwin.hxx>
+#endif
+#ifndef _SV_MENU_HXX
+#include <menu.hxx>
+#endif
+#ifndef _SV_DRAG_HXX
+#include <drag.hxx>
+#endif
+
+#define SYSDATA_ONLY_BASETYPE
+#include <sysdata.hxx>
+
+#include <com/sun/star/awt/XWindowPeer.hpp>
+
+#ifdef REMOTE_APPSERVER
+#include "rmwindow.hxx"
+#include "xevthdl.hxx"
+#include "rmevents.hxx"
+#include "rmoutdev.hxx"
+#endif
+
+#include <unowrap.hxx>
+
+#pragma hdrstop
+
+// =======================================================================
+
+DBG_NAME( Window );
+
+// =======================================================================
+
+#define IMPL_PAINT_PAINT ((USHORT)0x0001)
+#define IMPL_PAINT_PAINTALL ((USHORT)0x0002)
+#define IMPL_PAINT_PAINTALLCHILDS ((USHORT)0x0004)
+#define IMPL_PAINT_PAINTCHILDS ((USHORT)0x0008)
+#define IMPL_PAINT_ERASE ((USHORT)0x0010)
+
+// -----------------------------------------------------------------------
+
+typedef Window* PWINDOW;
+
+// -----------------------------------------------------------------------
+
+struct ImplCalcToTopData
+{
+ ImplCalcToTopData* mpNext;
+ Window* mpWindow;
+ Region* mpInvalidateRegion;
+};
+
+// -----------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+const char* ImplDbgCheckWindow( const void* pObj )
+{
+ DBG_TESTSOLARMUTEX();
+
+ const Window* pWindow = (Window*)pObj;
+
+ if ( (pWindow->GetType() < WINDOW_FIRST) || (pWindow->GetType() > WINDOW_LAST) )
+ return "Window data overwrite";
+
+ // Fenster-Verkettung ueberpruefen
+ Window* pChild = pWindow->mpFirstChild;
+ while ( pChild )
+ {
+ if ( pChild->mpParent != pWindow )
+ return "Child-Window-Parent wrong";
+ pChild = pChild->mpNext;
+ }
+
+ return NULL;
+}
+#endif
+
+// =======================================================================
+
+static void ImplInitAppFontData( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ long nTextHeight = pWindow->GetTextHeight();
+ long nTextWidth = pWindow->GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "aemnnxEM" ) ) );
+ long nSymHeight = nTextHeight*4;
+ // Falls Font zu schmal ist, machen wir die Basis breiter,
+ // damit die Dialoge symetrisch aussehen und nicht zu schmal
+ // werden. Wenn der Dialog die gleiche breite hat, geben wir
+ // noch etwas Spielraum dazu, da etwas mehr Platz besser ist.
+ if ( nSymHeight > nTextWidth )
+ nTextWidth = nSymHeight;
+ else if ( nSymHeight+5 > nTextWidth )
+ nTextWidth = nSymHeight+5;
+ pSVData->maGDIData.mnAppFontX = nTextWidth * 10 / 8;
+ pSVData->maGDIData.mnAppFontY = nTextHeight * 10;
+
+ pSVData->maGDIData.mnRealAppFontX = pSVData->maGDIData.mnAppFontX;
+ if ( pSVData->maAppData.mnDialogScaleX )
+ pSVData->maGDIData.mnAppFontX += (pSVData->maGDIData.mnAppFontX*pSVData->maAppData.mnDialogScaleX)/100;
+}
+
+// -----------------------------------------------------------------------
+
+MouseEvent ImplTranslateMouseEvent( const MouseEvent& rE, Window* pSource, Window* pDest )
+{
+ Point aPos = pSource->OutputToScreenPixel( rE.GetPosPixel() );
+ aPos = pDest->ScreenToOutputPixel( aPos );
+ return MouseEvent( aPos, rE.GetClicks(), rE.GetMode(), rE.GetButtons(), rE.GetModifier() );
+}
+
+// =======================================================================
+
+void Window::ImplInitData( WindowType nType )
+{
+ meOutDevType = OUTDEV_WINDOW;
+
+ mpWinData = NULL; // Extra Window Data, that we dont need for all windows
+ mpOverlapData = NULL; // Overlap Data
+ mpFrameData = NULL; // Frame Data
+ mpFrame = NULL; // Pointer to frame window
+ mpSysObj = NULL;
+ mpFrameWindow = NULL; // window to top level parent (same as frame window)
+ mpOverlapWindow = NULL; // first overlap parent
+ mpBorderWindow = NULL; // Border-Window
+ mpClientWindow = NULL; // Client-Window of a FrameWindow
+ mpParent = NULL; // parent (inkl. BorderWindow)
+ mpRealParent = NULL; // real parent (exkl. BorderWindow)
+ mpFirstChild = NULL; // first child window
+ mpLastChild = NULL; // last child window
+ mpFirstOverlap = NULL; // first overlap window (only set in overlap windows)
+ mpLastOverlap = NULL; // last overlap window (only set in overlap windows)
+ mpPrev = NULL; // prev window
+ mpNext = NULL; // next window
+ mpNextOverlap = NULL; // next overlap window of frame
+ mpLastFocusWindow = NULL; // window for focus restore
+ mpDlgCtrlDownWindow = NULL; // window for dialog control
+ mpFirstDel = NULL; // Dtor notification list
+ mpUserData = NULL; // user data
+ mpCursor = NULL; // cursor
+ mpControlFont = NULL; // font propertie
+ mpVCLXWindow = NULL;
+ maControlForeground = Color( COL_TRANSPARENT ); // kein Foreground gesetzt
+ maControlBackground = Color( COL_TRANSPARENT ); // kein Background gesetzt
+ mnLeftBorder = 0; // left border
+ mnTopBorder = 0; // top border
+ mnRightBorder = 0; // right border
+ mnBottomBorder = 0; // bottom border
+ mnX = 0; // X-Position to Parent
+ mnY = 0; // Y-Position to Parent
+ mnHelpId = 0; // help id
+ mnUniqId = 0; // unique id
+ mpChildClipRegion = NULL; // Child-Clip-Region when ClipChildren
+ mpPaintRegion = NULL; // Paint-ClipRegion
+ mnStyle = 0; // style (init in ImplInitWindow)
+ mnPrevStyle = 0; // prevstyle (set in SetStyle)
+ mnExtendedStyle = 0; // extended style (init in ImplInitWindow)
+ mnPrevExtendedStyle = 0; // prevstyle (set in SetExtendedStyle)
+ mnType = nType; // type
+ mnGetFocusFlags = 0; // Flags fuer GetFocus()-Aufruf
+ mnWaitCount = 0; // Wait-Count (>1 == Warte-MousePointer)
+ mnPaintFlags = 0; // Flags for ImplCallPaint
+ mnParentClipMode = 0; // Flags for Parent-ClipChildren-Mode
+ mnActivateMode = 0; // Wird bei System/Overlap-Windows umgesetzt
+ mnDlgCtrlFlags = 0; // DialogControl-Flags
+ mbFrame = FALSE; // TRUE: Window is a frame window
+ mbBorderWin = FALSE; // TRUE: Window is a border window
+ mbOverlapWin = FALSE; // TRUE: Window is a overlap window
+ mbSysWin = FALSE; // TRUE: SystemWindow is the base class
+ mbDialog = FALSE; // TRUE: Dialog is the base class
+ mbDockWin = FALSE; // TRUE: DockingWindow is the base class
+ mbFloatWin = FALSE; // TRUE: FloatingWindow is the base class
+ mbPushButton = FALSE; // TRUE: PushButton is the base class
+ mbVisible = FALSE; // TRUE: Show( TRUE ) called
+ mbOverlapVisible = FALSE; // TRUE: Hide called for visible window from ImplHideAllOverlapWindow()
+ mbDisabled = FALSE; // TRUE: Enable( FALSE ) called
+ mbInputDisabled = FALSE; // TRUE: EnableInput( FALSE ) called
+ mbAlwaysEnableInput = FALSE; // TRUE: AlwaysEnableInput( TRUE ) called
+ mbDropDisabled = FALSE; // TRUE: Drop is enabled
+ mbNoUpdate = FALSE; // TRUE: SetUpdateMode( FALSE ) called
+ mbNoParentUpdate = FALSE; // TRUE: SetParentUpdateMode( FALSE ) called
+ mbActive = FALSE; // TRUE: Window Active
+ mbParentActive = FALSE; // TRUE: OverlapActive from Parent
+ mbReallyVisible = FALSE; // TRUE: this and all parents to an overlaped window are visible
+ mbReallyShown = FALSE; // TRUE: this and all parents to an overlaped window are shown
+ mbInInitShow = FALSE; // TRUE: we are in InitShow
+ mbChildNotify = FALSE; // TRUE: ChildNotify
+ mbChildPtrOverwrite = FALSE; // TRUE: PointerStyle overwrites Child-Pointer
+ mbNoPtrVisible = FALSE; // TRUE: ShowPointer( FALSE ) called
+ mbMouseMove = FALSE; // TRUE: BaseMouseMove called
+ mbPaintFrame = FALSE; // TRUE: Paint is visible, but not painted
+ mbInPaint = FALSE; // TRUE: Inside PaintHdl
+ mbMouseButtonDown = FALSE; // TRUE: BaseMouseButtonDown called
+ mbMouseButtonUp = FALSE; // TRUE: BaseMouseButtonUp called
+ mbKeyInput = FALSE; // TRUE: BaseKeyInput called
+ mbKeyUp = FALSE; // TRUE: BaseKeyUp called
+ mbCommand = FALSE; // TRUE: BaseCommand called
+ mbDefPos = TRUE; // TRUE: Position is not Set
+ mbDefSize = TRUE; // TRUE: Size is not Set
+ mbCallMove = TRUE; // TRUE: Move must be called by Show
+ mbCallResize = TRUE; // TRUE: Resize must be called by Show
+ mbWaitSystemResize = TRUE; // TRUE: Wait for System-Resize
+ mbInitWinClipRegion = TRUE; // TRUE: Calc Window Clip Region
+ mbInitChildRegion = FALSE; // TRUE: InitChildClipRegion
+ mbWinRegion = FALSE; // TRUE: Window Region
+ mbClipChildren = FALSE; // TRUE: Child-Fenster muessen evt. geclippt werden
+ mbClipSiblings = FALSE; // TRUE: Nebeneinanderliegende Child-Fenster muessen evt. geclippt werden
+ mbChildTransparent = FALSE; // TRUE: Child-Fenster duerfen transparent einschalten (inkl. Parent-CLIPCHILDREN)
+ mbPaintTransparent = FALSE; // TRUE: Paints muessen auf Parent ausgeloest werden
+ mbMouseTransparent = FALSE; // TRUE: Window is transparent for Mouse
+ mbDlgCtrlStart = FALSE; // TRUE: Ab hier eigenes Dialog-Control
+ mbFocusVisible = FALSE; // TRUE: Focus Visible
+ mbTrackVisible = FALSE; // TRUE: Tracking Visible
+ mbControlForeground = FALSE; // TRUE: Foreground-Property set
+ mbControlBackground = FALSE; // TRUE: Background-Property set
+ mbAlwaysOnTop = FALSE; // TRUE: immer vor allen anderen normalen Fenstern sichtbar
+ mbCompoundControl = FALSE; // TRUE: Zusammengesetztes Control => Listener...
+ mbCompoundControlHasFocus = FALSE; // TRUE: Zusammengesetztes Control hat irgendwo den Focus
+ mbPaintDisabled = FALSE; // TRUE: Paint soll nicht ausgefuehrt werden
+ mbAllResize = FALSE; // TRUE: Auch ResizeEvents mit 0,0 schicken
+ mbInDtor = FALSE; // TRUE: Wir befinden uns im Window-Dtor
+ mbExtTextInput = FALSE; // TRUE: ExtTextInput-Mode is active
+ mbInFocusHdl = FALSE; // TRUE: Innerhalb vom GetFocus-Handler
+ mbCreatedWithToolkit = FALSE;
+
+#ifdef REMOTE_APPSERVER
+ mpRmEvents = NULL;
+
+ Font aFont = maInputContext.GetFont();
+ aFont.SetCharSet( gsl_getSystemTextEncoding() );
+ maInputContext.SetFont( aFont );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef REMOTE_APPSERVER
+void Window::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
+{
+ static ::com::sun::star::uno::Any aVoid;
+ ImplInit( pParent, nStyle, aVoid );
+}
+#else
+void Window::ImplInit( Window* pParent, WinBits nStyle, const ::com::sun::star::uno::Any& aSystemWorkWindowToken )
+{
+ ImplInit( pParent, nStyle, NULL );
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+#ifndef REMOTE_APPSERVER
+void Window::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
+#else
+void Window::ImplInit( Window* pParent, WinBits nStyle, const ::com::sun::star::uno::Any& aSystemWorkWindowToken )
+#endif
+{
+ DBG_ASSERT( mbFrame || pParent, "Window::Window(): pParent == NULL" );
+
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pRealParent = pParent;
+
+ // 3D-Look vererben
+ if ( !mbOverlapWin && (pParent->GetStyle() & WB_3DLOOK) )
+ nStyle |= WB_3DLOOK;
+
+ // Wenn wir einen Border haben, muessen wir ein BorderWindow anlegen
+ if ( !mbFrame && !mbBorderWin && !mpBorderWindow && (nStyle & WB_BORDER) )
+ {
+ ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL) );
+ ((Window*)pBorderWin)->mpClientWindow = this;
+ pBorderWin->GetBorder( mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder );
+ mpBorderWindow = pBorderWin;
+ pParent = mpBorderWindow;
+ }
+
+ // insert window in list
+ ImplInsertWindow( pParent );
+ mnStyle = nStyle;
+
+ // Overlap-Window-Daten
+ if ( mbOverlapWin )
+ {
+ mpOverlapData = new ImplOverlapData;
+ mpOverlapData->mpSaveBackDev = NULL;
+ mpOverlapData->mpSaveBackRgn = NULL;
+ mpOverlapData->mpNextBackWin = NULL;
+ mpOverlapData->mnSaveBackSize = 0;
+ mpOverlapData->mbSaveBack = FALSE;
+ mpOverlapData->mnTopLevel = 1;
+ }
+
+ // test for frame creation
+ if ( mbFrame )
+ {
+ // create frame
+#ifndef REMOTE_APPSERVER
+ ULONG nFrameStyle = 0;
+
+ if ( nStyle & WB_MOVEABLE )
+ nFrameStyle |= SAL_FRAME_STYLE_MOVEABLE;
+ if ( nStyle & WB_SIZEABLE )
+ {
+ nFrameStyle |= SAL_FRAME_STYLE_SIZEABLE |
+ SAL_FRAME_STYLE_MINABLE |
+ SAL_FRAME_STYLE_MAXABLE;
+ }
+ if ( nStyle & WB_CLOSEABLE )
+ nFrameStyle |= SAL_FRAME_STYLE_CLOSEABLE;
+ if ( nStyle & WB_APP )
+ nFrameStyle |= SAL_FRAME_STYLE_DEFAULT;
+
+ SalFrame* pParentFrame = NULL;
+ if ( pParent )
+ pParentFrame = pParent->mpFrame;
+ SalFrame* pFrame;
+ if ( pSystemParentData )
+ pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SAL_FRAME_STYLE_CHILD );
+ else
+ pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle );
+ if ( !pFrame )
+ GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
+ pFrame->SetCallback( this, ImplWindowFrameProc );
+
+ // initialize system-Drag&Drop-interface
+ DragManager::SystemEnableDrop( pFrame, TRUE );
+#else
+ RmFrameWindow* pParentFrame = pParent ? pParent->mpFrame : NULL;;
+ RmFrameWindow* pFrame = new RmFrameWindow( this );
+ if ( !pFrame->IsValid() )
+ {
+ delete pFrame, pFrame = NULL;
+ GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
+ }
+ else
+ {
+ pFrame->Create( nStyle, pFrame->GetEventHdlInterface(),
+ aSystemWorkWindowToken,
+ pParentFrame ? pParentFrame->GetFrameInterface() : REF( NMSP_CLIENT::XRmFrameWindow )() );
+ }
+#endif
+
+ // set window frame data
+ mpFrameData = new ImplFrameData;
+ mpFrame = pFrame;
+ mpFrameWindow = this;
+ mpOverlapWindow = this;
+
+ // set frame data
+ mpFrameData->mpNextFrame = pSVData->maWinData.mpFirstFrame;
+ pSVData->maWinData.mpFirstFrame = this;
+ mpFrameData->mpFirstOverlap = NULL;
+ mpFrameData->mpFocusWin = NULL;
+ mpFrameData->mpMouseMoveWin = NULL;
+ mpFrameData->mpMouseDownWin = NULL;
+ mpFrameData->mpFirstBackWin = NULL;
+ mpFrameData->mpFontList = pSVData->maGDIData.mpScreenFontList;
+ mpFrameData->mpFontCache = pSVData->maGDIData.mpScreenFontCache;
+ mpFrameData->mnAllSaveBackSize = 0;
+ mpFrameData->mnFocusId = 0;
+ mpFrameData->mnMouseMoveId = 0;
+ mpFrameData->mnLastMouseX = -1;
+ mpFrameData->mnLastMouseY = -1;
+ mpFrameData->mnFirstMouseX = -1;
+ mpFrameData->mnFirstMouseY = -1;
+ mpFrameData->mnLastMouseWinX = -1;
+ mpFrameData->mnLastMouseWinY = -1;
+ mpFrameData->mnMouseDownTime = 0;
+ mpFrameData->mnClickCount = 0;
+ mpFrameData->mnFirstMouseCode = 0;
+ mpFrameData->mnMouseCode = 0;
+ mpFrameData->mnMouseMode = 0;
+ mpFrameData->meMapUnit = MAP_PIXEL;
+ mpFrameData->mbHasFocus = FALSE;
+ mpFrameData->mbInMouseMove = FALSE;
+ mpFrameData->mbMouseIn = FALSE;
+ mpFrameData->mbStartDragCalled = FALSE;
+ mpFrameData->mbNeedSysWindow = FALSE;
+ mpFrameData->mbMinimized = FALSE;
+ mpFrameData->mbStartFocusState = FALSE;
+ mpFrameData->mbInSysObjFocusHdl = FALSE;
+ mpFrameData->mbInSysObjToTopHdl = FALSE;
+ mpFrameData->mbSysObjFocus = FALSE;
+
+ mpFrameData->mpDragTimer = NULL;
+ mpFrameData->maPaintTimer.SetTimeout( 30 );
+ mpFrameData->maPaintTimer.SetTimeoutHdl( LINK( this, Window, ImplHandlePaintHdl ) );
+
+#ifndef REMOTE_APPSERVER
+ // Muessen Application-Settings noch upgedatet werden
+ if ( !pSVData->maAppData.mbSettingsInit )
+ {
+ mpFrame->UpdateSettings( *pSVData->maAppData.mpSettings );
+ GetpApp()->SystemSettingsChanging( *pSVData->maAppData.mpSettings, this );
+#ifdef DBG_UTIL
+ // Evt. AppFont auf Fett schalten, damit man feststellen kann,
+ // ob fuer die Texte auf anderen Systemen genuegend Platz
+ // vorhanden ist
+ if ( DbgIsBoldAppFont() )
+ {
+ StyleSettings aStyleSettings = pSVData->maAppData.mpSettings->GetStyleSettings();
+ Font aFont = aStyleSettings.GetAppFont();
+ aFont.SetWeight( WEIGHT_BOLD );
+ aStyleSettings.SetAppFont( aFont );
+ aFont = aStyleSettings.GetGroupFont();
+ aFont.SetWeight( WEIGHT_BOLD );
+ aStyleSettings.SetGroupFont( aFont );
+ aFont = aStyleSettings.GetLabelFont();
+ aFont.SetWeight( WEIGHT_BOLD );
+ aStyleSettings.SetLabelFont( aFont );
+ aFont = aStyleSettings.GetRadioCheckFont();
+ aFont.SetWeight( WEIGHT_BOLD );
+ aStyleSettings.SetRadioCheckFont( aFont );
+ aFont = aStyleSettings.GetPushButtonFont();
+ aFont.SetWeight( WEIGHT_BOLD );
+ aStyleSettings.SetPushButtonFont( aFont );
+ aFont = aStyleSettings.GetFieldFont();
+ aFont.SetWeight( WEIGHT_BOLD );
+ aStyleSettings.SetFieldFont( aFont );
+ aFont = aStyleSettings.GetIconFont();
+ aFont.SetWeight( WEIGHT_BOLD );
+ aStyleSettings.SetIconFont( aFont );
+ pSVData->maAppData.mpSettings->SetStyleSettings( aStyleSettings );
+ }
+#endif
+ OutputDevice::SetSettings( *pSVData->maAppData.mpSettings );
+ pSVData->maAppData.mbSettingsInit = TRUE;
+ }
+#endif
+ }
+
+ // init data
+ mpRealParent = pRealParent;
+
+ if ( mbFrame )
+ {
+#ifndef REMOTE_APPSERVER
+ if ( pParent )
+ {
+ mpFrameData->mnDPIX = pParent->mpFrameData->mnDPIX;
+ mpFrameData->mnDPIY = pParent->mpFrameData->mnDPIY;
+ mpFrameData->mnFontDPIX = pParent->mpFrameData->mnFontDPIX;
+ mpFrameData->mnFontDPIY = pParent->mpFrameData->mnFontDPIY;
+ }
+ else
+ {
+ if ( ImplGetGraphics() )
+ {
+ mpGraphics->GetResolution( mpFrameData->mnDPIX, mpFrameData->mnDPIY );
+ mpGraphics->GetScreenFontResolution( mpFrameData->mnFontDPIX, mpFrameData->mnFontDPIY );
+ if ( !mpFrameData->mpFontList->Count() )
+ {
+ mpGraphics->GetDevFontList( mpFrameData->mpFontList );
+ mpFrameData->mpFontList->InitStdFonts();
+ }
+ }
+ }
+#else
+ const REF( NMSP_CLIENT::XRmFrameWindow )& rxWindow = mpFrame->GetFrameInterface();
+ REF( NMSP_CLIENT::XRmOutputDevice ) xOutDev( mpFrame->GetOutdevInterface() );
+
+ if ( rxWindow.is() && xOutDev.is() )
+ {
+ mpGraphics = new ImplServerGraphics;
+ mpGraphics->SetInterface( xOutDev );
+ if ( pParent )
+ {
+ mpFrameData->mnDPIX = pParent->mpFrameData->mnDPIX;
+ mpFrameData->mnDPIY = pParent->mpFrameData->mnDPIY;
+ mpFrameData->mnFontDPIX = pParent->mpFrameData->mnFontDPIX;
+ mpFrameData->mnFontDPIY = pParent->mpFrameData->mnFontDPIY;
+ }
+ else
+ {
+ // We currently assume, that we have only one display
+ static NMSP_CLIENT::RmFrameResolutions aResl = mpFrame->GetFrameResolutions();
+ mpFrameData->mnDPIX = aResl.DPIx;
+ mpFrameData->mnDPIY = aResl.DPIy;
+ mpFrameData->mnFontDPIX = aResl.FontDPIx;
+ mpFrameData->mnFontDPIY = aResl.FontDPIy;
+ mpGraphics->SetWindowResolution( aResl.DPIx, aResl.DPIy, aResl.Depth );
+ if ( !mpFrameData->mpFontList->Count() )
+ {
+ mpGraphics->GetDevFontList( mpFrameData->mpFontList );
+ mpFrameData->mpFontList->InitStdFonts();
+ }
+ }
+ }
+#endif
+
+ // If we create a Window with default size, query this
+ // size directly, because we want resize all Controls to
+ // the correct size before we display the window
+ if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) )
+ mpFrame->GetClientSize( mnOutWidth, mnOutHeight );
+ }
+ else
+ {
+ if ( pParent )
+ {
+ if ( !ImplIsOverlapWindow() )
+ {
+ mbDisabled = pParent->mbDisabled;
+ mbInputDisabled = pParent->mbInputDisabled;
+ mbAlwaysEnableInput = pParent->mbAlwaysEnableInput;
+ }
+
+ OutputDevice::SetSettings( pParent->GetSettings() );
+ }
+ }
+
+ const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
+ USHORT nScreenZoom = rStyleSettings.GetScreenZoom();
+ mnDPIX = (mpFrameData->mnDPIX*nScreenZoom)/100;
+ mnDPIY = (mpFrameData->mnDPIY*nScreenZoom)/100;
+ mpFontList = mpFrameData->mpFontList;
+ mpFontCache = mpFrameData->mpFontCache;
+ maFont = rStyleSettings.GetAppFont();
+ ImplPointToLogic( maFont );
+
+ if ( nStyle & WB_3DLOOK )
+ {
+ SetTextColor( rStyleSettings.GetButtonTextColor() );
+ SetBackground( Wallpaper( rStyleSettings.GetFaceColor() ) );
+ }
+ else
+ {
+ SetTextColor( rStyleSettings.GetWindowTextColor() );
+ SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
+ }
+
+ ImplUpdatePos();
+
+ // AppFont-Aufloesung berechnen
+ if ( mbFrame && !pSVData->maGDIData.mnAppFontX )
+ ImplInitAppFontData( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInsertWindow( Window* pParent )
+{
+ mpParent = pParent;
+ mpRealParent = pParent;
+
+ if ( pParent && !mbFrame )
+ {
+ // search frame window and set window frame data
+ Window* pFrameParent = pParent->mpFrameWindow;
+ mpFrameData = pFrameParent->mpFrameData;
+ mpFrame = pFrameParent->mpFrame;
+ mpFrameWindow = pFrameParent;
+ mbFrame = FALSE;
+#ifdef REMOTE_APPSERVER
+ mpGraphics = mpFrameWindow->mpGraphics;
+#endif
+
+ // search overlap window and insert window in list
+ if ( ImplIsOverlapWindow() )
+ {
+ Window* pFirstOverlapParent = pParent;
+ while ( !pFirstOverlapParent->ImplIsOverlapWindow() )
+ pFirstOverlapParent = pFirstOverlapParent->ImplGetParent();
+ mpOverlapWindow = pFirstOverlapParent;
+
+ mpNextOverlap = mpFrameData->mpFirstOverlap;
+ mpFrameData->mpFirstOverlap = this;
+
+ // Overlap-Windows sind per default die obersten
+ mpNext = pFirstOverlapParent->mpFirstOverlap;
+ pFirstOverlapParent->mpFirstOverlap = this;
+ if ( !pFirstOverlapParent->mpLastOverlap )
+ pFirstOverlapParent->mpLastOverlap = this;
+ else
+ mpNext->mpPrev = this;
+ }
+ else
+ {
+ if ( pParent->ImplIsOverlapWindow() )
+ mpOverlapWindow = pParent;
+ else
+ mpOverlapWindow = pParent->mpOverlapWindow;
+ mpPrev = pParent->mpLastChild;
+ pParent->mpLastChild = this;
+ if ( !pParent->mpFirstChild )
+ pParent->mpFirstChild = this;
+ else
+ mpPrev->mpNext = this;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplRemoveWindow( BOOL bRemoveFrameData )
+{
+ // Fenster aus den Listen austragen
+ if ( !mbFrame )
+ {
+ if ( ImplIsOverlapWindow() )
+ {
+ if ( mpFrameData->mpFirstOverlap == this )
+ mpFrameData->mpFirstOverlap = mpNextOverlap;
+ else
+ {
+ Window* pTempWin = mpFrameData->mpFirstOverlap;
+ while ( pTempWin->mpNextOverlap != this )
+ pTempWin = pTempWin->mpNextOverlap;
+ pTempWin->mpNextOverlap = mpNextOverlap;
+ }
+
+ if ( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ mpOverlapWindow->mpFirstOverlap = mpNext;
+ if ( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ mpOverlapWindow->mpLastOverlap = mpPrev;
+ }
+ else
+ {
+ if ( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ mpParent->mpFirstChild = mpNext;
+ if ( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ mpParent->mpLastChild = mpPrev;
+ }
+
+ mpPrev = NULL;
+ mpNext = NULL;
+ }
+
+ if ( bRemoveFrameData )
+ {
+ // Graphic freigeben
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+#else
+ ImplReleaseServerGraphics();
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static ULONG ImplAutoHelpID()
+{
+ if ( !Application::IsAutoHelpIdEnabled() )
+ return 0;
+
+ ULONG nHID = 0;
+
+ ResMgr *pResMgr = Resource::GetResManager();
+
+ DBG_ASSERT( pResMgr, "MM hat gesagt, dass wir immer einen haben" );
+ DBG_ASSERT( pResMgr->nTopRes, "MM hat gesagt, dass der Stack nie leer ist" );
+ if( !pResMgr || pResMgr->nTopRes < 1 || pResMgr->nTopRes > 2 )
+ return 0;
+
+ const ImpRCStack *pRC = pResMgr->StackTop( pResMgr->nTopRes==1 ? 0 : 1 );
+
+ DBG_ASSERT( pRC->pResource, "MM hat gesagt, dass der immer einen hat" );
+ ULONG nGID = pRC->pResource->GetId();
+
+ if( !nGID || nGID > 32767 )
+ return 0;
+
+ // GGGg gggg::gggg gggg::ggLL LLLl::llll llll
+ switch( pRC->pResource->GetRT() ) { // maximal 7
+ case RSC_DOCKINGWINDOW:
+ nHID += 0x20000000L;
+ case RSC_WORKWIN:
+ nHID += 0x20000000L;
+ case RSC_MODELESSDIALOG:
+ nHID += 0x20000000L;
+ case RSC_FLOATINGWINDOW:
+ nHID += 0x20000000L;
+ case RSC_MODALDIALOG:
+ nHID += 0x20000000L;
+ case RSC_TABPAGE:
+ nHID += 0x20000000L;
+
+ if( pResMgr->nTopRes == 2 ) {
+ pRC = pResMgr->StackTop();
+ ULONG nLID = pRC->pResource->GetId();
+
+ if( !nLID || nLID > 511 )
+ return 0;
+
+ switch( pRC->pResource->GetRT() ) { // maximal 32
+ case RSC_TABCONTROL: nHID |= 0x0000; break;
+ case RSC_RADIOBUTTON: nHID |= 0x0200; break;
+ case RSC_CHECKBOX: nHID |= 0x0400; break;
+ case RSC_TRISTATEBOX: nHID |= 0x0600; break;
+ case RSC_EDIT: nHID |= 0x0800; break;
+ case RSC_MULTILINEEDIT: nHID |= 0x0A00; break;
+ case RSC_MULTILISTBOX: nHID |= 0x0C00; break;
+ case RSC_LISTBOX: nHID |= 0x0E00; break;
+ case RSC_COMBOBOX: nHID |= 0x1000; break;
+ case RSC_PUSHBUTTON: nHID |= 0x1200; break;
+ case RSC_SPINFIELD: nHID |= 0x1400; break;
+ case RSC_PATTERNFIELD: nHID |= 0x1600; break;
+ case RSC_NUMERICFIELD: nHID |= 0x1800; break;
+ case RSC_METRICFIELD: nHID |= 0x1A00; break;
+ case RSC_CURRENCYFIELD: nHID |= 0x1C00; break;
+ case RSC_DATEFIELD: nHID |= 0x1E00; break;
+ case RSC_TIMEFIELD: nHID |= 0x2000; break;
+ case RSC_IMAGERADIOBUTTON: nHID |= 0x2200; break;
+ case RSC_NUMERICBOX: nHID |= 0x2400; break;
+ case RSC_METRICBOX: nHID |= 0x2600; break;
+ case RSC_CURRENCYBOX: nHID |= 0x2800; break;
+ case RSC_DATEBOX: nHID |= 0x2A00; break;
+ case RSC_TIMEBOX: nHID |= 0x2C00; break;
+ case RSC_IMAGEBUTTON: nHID |= 0x2E00; break;
+ case RSC_MENUBUTTON: nHID |= 0x3000; break;
+ case RSC_MOREBUTTON: nHID |= 0x3200; break;
+ default:
+ return 0;
+ } // of switch
+ nHID |= nLID;
+ } // of if
+ break;
+ default:
+ return 0;
+ } // of switch
+ nHID |= nGID << 14;
+ return nHID;
+}
+
+// -----------------------------------------------------------------------
+
+WinBits Window::ImplInitRes( const ResId& rResId )
+{
+ GetRes( rResId );
+
+ char* pRes = (char*)GetClassRes();
+ pRes += 4;
+ ULONG nStyle = GetLongRes( (void*)pRes );
+ ((ResId&)rResId).aWinBits = nStyle;
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplLoadRes( const ResId& rResId )
+{
+ // newer move this line after IncrementRes
+ char* pRes = (char*)GetClassRes();
+ pRes += 8;
+ ULONG nHelpId = (ULONG)GetLongRes( (void*)pRes );
+ if ( !nHelpId )
+ nHelpId = ImplAutoHelpID();
+ SetHelpId( nHelpId );
+
+ USHORT nObjMask = (USHORT)ReadShortRes();
+
+ // ResourceStyle
+ USHORT nRSStyle = ReadShortRes();
+ // WinBits
+ ReadLongRes();
+ // HelpId
+ ReadLongRes();
+
+ BOOL bPos = FALSE;
+ BOOL bSize = FALSE;
+ Point aPos;
+ Size aSize;
+
+ if ( nObjMask & (WINDOW_XYMAPMODE | WINDOW_X | WINDOW_Y) )
+ {
+ // Groessenangabe aus der Resource verwenden
+ MapUnit ePosMap = MAP_PIXEL;
+
+ bPos = TRUE;
+
+ if ( nObjMask & WINDOW_XYMAPMODE )
+ ePosMap = (MapUnit)(USHORT)ReadShortRes();
+ if ( nObjMask & WINDOW_X )
+ aPos.X() = ImplLogicUnitToPixelX( ReadLongRes(), ePosMap );
+ if ( nObjMask & WINDOW_Y )
+ aPos.Y() = ImplLogicUnitToPixelY( ReadLongRes(), ePosMap );
+ }
+
+ if ( nObjMask & (WINDOW_WHMAPMODE | WINDOW_WIDTH | WINDOW_HEIGHT) )
+ {
+ // Groessenangabe aus der Resource verwenden
+ MapUnit eSizeMap = MAP_PIXEL;
+
+ bSize = TRUE;
+
+ if ( nObjMask & WINDOW_WHMAPMODE )
+ eSizeMap = (MapUnit)(USHORT)ReadShortRes();
+ if ( nObjMask & WINDOW_WIDTH )
+ aSize.Width() = ImplLogicUnitToPixelX( ReadLongRes(), eSizeMap );
+ if ( nObjMask & WINDOW_HEIGHT )
+ aSize.Height() = ImplLogicUnitToPixelY( ReadLongRes(), eSizeMap );
+ }
+
+ // Wegen Optimierung so schlimm aussehend
+ if ( nRSStyle & RSWND_CLIENTSIZE )
+ {
+ if ( bPos )
+ SetPosPixel( aPos );
+ if ( bSize )
+ SetOutputSizePixel( aSize );
+ }
+ else if ( bPos && bSize )
+ SetPosSizePixel( aPos, aSize );
+ else if ( bPos )
+ SetPosPixel( aPos );
+ else if ( bSize )
+ SetSizePixel( aSize );
+
+ if ( nRSStyle & RSWND_DISABLED )
+ Enable( FALSE );
+
+ if ( nObjMask & WINDOW_TEXT )
+ SetText( ReadStringRes() );
+ if ( nObjMask & WINDOW_HELPTEXT )
+ SetHelpText( ReadStringRes() );
+ if ( nObjMask & WINDOW_QUICKTEXT )
+ SetQuickHelpText( ReadStringRes() );
+ if ( nObjMask & WINDOW_EXTRALONG )
+ SetData( (void*)ReadLongRes() );
+ if ( nObjMask & WINDOW_UNIQUEID )
+ SetUniqueId( (ULONG)ReadLongRes() );
+}
+
+// -----------------------------------------------------------------------
+
+ImplWinData* Window::ImplGetWinData() const
+{
+ if ( !mpWinData )
+ {
+ ((Window*)this)->mpWinData = new ImplWinData;
+ mpWinData->mpExtPosAry = NULL;
+ mpWinData->mnExtPosStart = 0;
+ mpWinData->mnExtPosCount = 0;
+ mpWinData->mnExtOldTextLen = 0;
+ mpWinData->mpFocusRect = NULL;
+ mpWinData->mpTrackRect = NULL;
+ mpWinData->mnTrackFlags = 0;
+ }
+
+ return mpWinData;
+}
+
+// -----------------------------------------------------------------------
+
+#ifndef REMOTE_APPSERVER
+SalGraphics* Window::ImplGetFrameGraphics() const
+{
+ if ( mpFrameWindow->mpGraphics )
+ mpFrameWindow->mbInitClipRegion = TRUE;
+ else
+ mpFrameWindow->ImplGetGraphics();
+ mpFrameWindow->mpGraphics->ResetClipRegion();
+ return mpFrameWindow->mpGraphics;
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+Window* Window::ImplFindWindow( const Point& rFramePos )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Window* pTempWindow;
+ Window* pFindWindow;
+
+ // Zuerst alle ueberlappenden Fenster ueberpruefen
+ pTempWindow = mpFirstOverlap;
+ while ( pTempWindow )
+ {
+ pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
+ if ( pFindWindow )
+ return pFindWindow;
+ pTempWindow = pTempWindow->mpNext;
+ }
+
+ // dann testen wir unser Fenster
+ if ( !mbVisible )
+ return NULL;
+
+ USHORT nHitTest = ImplHitTest( rFramePos );
+ if ( nHitTest & WINDOW_HITTEST_INSIDE )
+ {
+ // und danach gehen wir noch alle Child-Fenster durch
+ pTempWindow = mpFirstChild;
+ while ( pTempWindow )
+ {
+ pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
+ if ( pFindWindow )
+ return pFindWindow;
+ pTempWindow = pTempWindow->mpNext;
+ }
+
+ if ( nHitTest & WINDOW_HITTEST_TRANSPARENT )
+ return NULL;
+ else
+ return this;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Window::ImplHitTest( const Point& rFramePos )
+{
+ Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ if ( !aRect.IsInside( rFramePos ) )
+ return 0;
+ if ( mbWinRegion )
+ {
+ Point aTempPos = rFramePos;
+ aTempPos.X() -= mnOutOffX;
+ aTempPos.Y() -= mnOutOffY;
+ if ( !maWinRegion.IsInside( aTempPos ) )
+ return 0;
+ }
+
+ USHORT nHitTest = WINDOW_HITTEST_INSIDE;
+ if ( mbMouseTransparent )
+ nHitTest |= WINDOW_HITTEST_TRANSPARENT;
+ return nHitTest;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplIsRealParentPath( const Window* pWindow ) const
+{
+ pWindow = pWindow->GetParent();
+ while ( pWindow )
+ {
+ if ( pWindow == this )
+ return TRUE;
+ pWindow = pWindow->GetParent();
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplIsChild( const Window* pWindow, BOOL bSystemWindow ) const
+{
+ do
+ {
+ if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
+ break;
+
+ pWindow = pWindow->ImplGetParent();
+
+ if ( pWindow == this )
+ return TRUE;
+ }
+ while ( pWindow );
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplIsWindowOrChild( const Window* pWindow, BOOL bSystemWindow ) const
+{
+ if ( this == pWindow )
+ return TRUE;
+ return ImplIsChild( pWindow, bSystemWindow );
+}
+
+// -----------------------------------------------------------------------
+
+Window* Window::ImplGetSameParent( const Window* pWindow ) const
+{
+ if ( mpFrameWindow != pWindow->mpFrameWindow )
+ return NULL;
+ else
+ {
+ if ( pWindow->ImplIsChild( this ) )
+ return (Window*)pWindow;
+ else
+ {
+ Window* pTestWindow = (Window*)this;
+ while ( (pTestWindow == pWindow) || pTestWindow->ImplIsChild( pWindow ) )
+ pTestWindow = pTestWindow->ImplGetParent();
+ return pTestWindow;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+int Window::ImplTestMousePointerSet()
+{
+ // Wenn Mouse gecaptured ist, dann soll MousePointer umgeschaltet werden
+ if ( IsMouseCaptured() )
+ return TRUE;
+
+ // Wenn sich Mouse ueber dem Fenster befindet, dann soll MousePointer
+ // umgeschaltet werden
+ Rectangle aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
+ if ( aClientRect.IsInside( GetPointerPosPixel() ) )
+ return TRUE;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+PointerStyle Window::ImplGetMousePointer() const
+{
+ PointerStyle ePointerStyle;
+ BOOL bWait = FALSE;
+
+ if ( IsEnabled() && IsInputEnabled() )
+ ePointerStyle = GetPointer().GetStyle();
+ else
+ ePointerStyle = POINTER_ARROW;
+
+ const Window* pWindow = this;
+ do
+ {
+ // Wenn Pointer nicht sichtbar, dann wird suche abgebrochen, da
+ // dieser Status nicht ueberschrieben werden darf
+ if ( pWindow->mbNoPtrVisible )
+ return POINTER_NULL;
+
+ if ( !bWait )
+ {
+ if ( pWindow->mnWaitCount )
+ {
+ ePointerStyle = POINTER_WAIT;
+ bWait = TRUE;
+ }
+ else
+ {
+ if ( pWindow->mbChildPtrOverwrite )
+ ePointerStyle = pWindow->GetPointer().GetStyle();
+ }
+ }
+
+ if ( pWindow->ImplIsOverlapWindow() )
+ break;
+
+ pWindow = pWindow->ImplGetParent();
+ }
+ while ( pWindow );
+
+ return ePointerStyle;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplResetReallyVisible()
+{
+ mbDevOutput = FALSE;
+ mbReallyVisible = FALSE;
+ mbReallyShown = FALSE;
+
+ Window* pWindow = mpFirstOverlap;
+ while ( pWindow )
+ {
+ if ( pWindow->mbReallyVisible )
+ pWindow->ImplResetReallyVisible();
+ pWindow = pWindow->mpNext;
+ }
+
+ pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ if ( pWindow->mbReallyVisible )
+ pWindow->ImplResetReallyVisible();
+ pWindow = pWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplSetReallyVisible()
+{
+ mbDevOutput = TRUE;
+ mbReallyVisible = TRUE;
+ mbReallyShown = TRUE;
+
+ Window* pWindow = mpFirstOverlap;
+ while ( pWindow )
+ {
+ if ( pWindow->mbVisible )
+ pWindow->ImplSetReallyVisible();
+ pWindow = pWindow->mpNext;
+ }
+
+ pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ if ( pWindow->mbVisible )
+ pWindow->ImplSetReallyVisible();
+ pWindow = pWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCallInitShow()
+{
+ mbReallyShown = TRUE;
+ mbInInitShow = TRUE;
+ StateChanged( STATE_CHANGE_INITSHOW );
+ mbInInitShow = FALSE;
+
+ Window* pWindow = mpFirstOverlap;
+ while ( pWindow )
+ {
+ if ( pWindow->mbVisible )
+ pWindow->ImplCallInitShow();
+ pWindow = pWindow->mpNext;
+ }
+
+ pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ if ( pWindow->mbVisible )
+ pWindow->ImplCallInitShow();
+ pWindow = pWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplAddDel( ImplDelData* pDel )
+{
+ pDel->mpNext = mpFirstDel;
+ mpFirstDel = pDel;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplRemoveDel( ImplDelData* pDel )
+{
+ if ( mpFirstDel == pDel )
+ mpFirstDel = pDel->mpNext;
+ else
+ {
+ ImplDelData* pData = mpFirstDel;
+ while ( pData->mpNext != pDel )
+ pData = pData->mpNext;
+ pData->mpNext = pDel->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInitResolutionSettings()
+{
+ // AppFont-Aufloesung und DPI-Aufloesung neu berechnen
+ if ( mbFrame )
+ {
+ const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
+ USHORT nScreenZoom = rStyleSettings.GetScreenZoom();
+ mnDPIX = (mpFrameData->mnDPIX*nScreenZoom)/100;
+ mnDPIY = (mpFrameData->mnDPIY*nScreenZoom)/100;
+ SetPointFont( rStyleSettings.GetAppFont() );
+
+ if ( !ImplGetSVData()->maGDIData.mnAppFontX )
+ ImplInitAppFontData( this );
+ }
+ else if ( mpParent )
+ {
+ mnDPIX = mpParent->mnDPIX;
+ mnDPIY = mpParent->mnDPIY;
+ }
+
+ // Vorberechnete Werte fuer logische Einheiten updaten und auch
+ // die entsprechenden Tools dazu
+ if ( IsMapMode() )
+ {
+ MapMode aMapMode = GetMapMode();
+ SetMapMode();
+ SetMapMode( aMapMode );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplPointToLogic( Font& rFont ) const
+{
+ Size aSize = rFont.GetSize();
+ USHORT nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom();
+
+ if ( aSize.Width() )
+ {
+ aSize.Width() *= mpFrameData->mnFontDPIX;
+ aSize.Width() += 72/2;
+ aSize.Width() /= 72;
+ aSize.Width() *= nScreenFontZoom;
+ aSize.Width() /= 100;
+ }
+ aSize.Height() *= mpFrameData->mnFontDPIY;
+ aSize.Height() += 72/2;
+ aSize.Height() /= 72;
+ aSize.Height() *= nScreenFontZoom;
+ aSize.Height() /= 100;
+
+ if ( IsMapModeEnabled() )
+ aSize = PixelToLogic( aSize );
+
+ rFont.SetSize( aSize );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplLogicToPoint( Font& rFont ) const
+{
+ Size aSize = rFont.GetSize();
+ USHORT nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom();
+
+ if ( IsMapModeEnabled() )
+ aSize = LogicToPixel( aSize );
+
+ if ( aSize.Width() )
+ {
+ aSize.Width() *= 100;
+ aSize.Width() /= nScreenFontZoom;
+ aSize.Width() *= 72;
+ aSize.Width() += mpFrameData->mnFontDPIX/2;
+ aSize.Width() /= mpFrameData->mnFontDPIX;
+ }
+ aSize.Height() *= 100;
+ aSize.Height() /= nScreenFontZoom;
+ aSize.Height() *= 72;
+ aSize.Height() += mpFrameData->mnFontDPIY/2;
+ aSize.Height() /= mpFrameData->mnFontDPIY;
+
+ rFont.SetSize( aSize );
+}
+
+// -----------------------------------------------------------------------
+
+#ifndef REMOTE_APPSERVER
+BOOL Window::ImplSysObjClip( const Region* pOldRegion )
+{
+ BOOL bUpdate = TRUE;
+
+ if ( mpSysObj )
+ {
+ BOOL bVisibleState = mbReallyVisible;
+
+ if ( bVisibleState )
+ {
+ Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
+
+ if ( !pWinChildClipRegion->IsEmpty() )
+ {
+ if ( pOldRegion )
+ {
+ Region aNewRegion = *pWinChildClipRegion;
+ pWinChildClipRegion->Intersect( *pOldRegion );
+ bUpdate = aNewRegion == *pWinChildClipRegion;
+ }
+
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+
+ Region aRegion = *pWinChildClipRegion;
+ Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ Region aWinRectRegion( aWinRect );
+ USHORT nClipFlags = mpSysObj->GetClipRegionType();
+
+ if ( aRegion == aWinRectRegion )
+ mpSysObj->ResetClipRegion();
+ else
+ {
+ if ( nClipFlags & SAL_OBJECT_CLIP_EXCLUDERECTS )
+ {
+ aWinRectRegion.Exclude( aRegion );
+ aRegion = aWinRectRegion;
+ }
+ if ( !(nClipFlags & SAL_OBJECT_CLIP_ABSOLUTE) )
+ aRegion.Move( -mnOutOffX, -mnOutOffY );
+
+ // ClipRegion setzen/updaten
+ long nX;
+ long nY;
+ long nWidth;
+ long nHeight;
+ ULONG nRectCount;
+ ImplRegionInfo aInfo;
+ BOOL bRegionRect;
+
+ nRectCount = aRegion.GetRectCount();
+ mpSysObj->BeginSetClipRegion( nRectCount );
+ bRegionRect = aRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+ while ( bRegionRect )
+ {
+ mpSysObj->UnionClipRegion( nX, nY, nWidth, nHeight );
+ bRegionRect = aRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+ }
+ mpSysObj->EndSetClipRegion();
+ }
+ }
+ else
+ bVisibleState = FALSE;
+ }
+
+ // Visible-Status updaten
+ mpSysObj->Show( bVisibleState );
+ }
+
+ return bUpdate;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplUpdateSysObjChildsClip()
+{
+ if ( mpSysObj && mbInitWinClipRegion )
+ ImplSysObjClip( NULL );
+
+ Window* pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ pWindow->ImplUpdateSysObjChildsClip();
+ pWindow = pWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplUpdateSysObjOverlapsClip()
+{
+ ImplUpdateSysObjChildsClip();
+
+ Window* pWindow = mpFirstOverlap;
+ while ( pWindow )
+ {
+ pWindow->ImplUpdateSysObjOverlapsClip();
+ pWindow = pWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplUpdateSysObjClip()
+{
+ if ( !ImplIsOverlapWindow() )
+ {
+ ImplUpdateSysObjChildsClip();
+
+ // Schwestern muessen ihre ClipRegion auch neu berechnen
+ if ( mbClipSiblings )
+ {
+ Window* pWindow = mpNext;
+ while ( pWindow )
+ {
+ pWindow->ImplUpdateSysObjChildsClip();
+ pWindow = pWindow->mpNext;
+ }
+ }
+ }
+ else
+ mpFrameWindow->ImplUpdateSysObjOverlapsClip();
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplSetClipFlagChilds( BOOL bSysObjOnlySmaller )
+{
+ BOOL bUpdate = TRUE;
+#ifndef REMOTE_APPSERVER
+ if ( mpSysObj )
+ {
+ Region* pOldRegion = NULL;
+ if ( bSysObjOnlySmaller && !mbInitWinClipRegion )
+ pOldRegion = new Region( maWinClipRegion );
+
+ mbInitClipRegion = TRUE;
+ mbInitWinClipRegion = TRUE;
+
+ Window* pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
+ bUpdate = FALSE;
+ pWindow = pWindow->mpNext;
+ }
+
+ if ( !ImplSysObjClip( pOldRegion ) )
+ {
+ mbInitClipRegion = TRUE;
+ mbInitWinClipRegion = TRUE;
+ bUpdate = FALSE;
+ }
+
+ if ( pOldRegion )
+ delete pOldRegion;
+ }
+ else
+#endif
+ {
+ mbInitClipRegion = TRUE;
+ mbInitWinClipRegion = TRUE;
+
+ Window* pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
+ bUpdate = FALSE;
+ pWindow = pWindow->mpNext;
+ }
+ }
+ return bUpdate;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplSetClipFlagOverlapWindows( BOOL bSysObjOnlySmaller )
+{
+ BOOL bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller );
+
+ Window* pWindow = mpFirstOverlap;
+ while ( pWindow )
+ {
+ if ( !pWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ) )
+ bUpdate = FALSE;
+ pWindow = pWindow->mpNext;
+ }
+
+ return bUpdate;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplSetClipFlag( BOOL bSysObjOnlySmaller )
+{
+ if ( !ImplIsOverlapWindow() )
+ {
+ BOOL bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller );
+
+ Window* pParent = ImplGetParent();
+ if ( pParent &&
+ ((pParent->GetStyle() & WB_CLIPCHILDREN) || (mnParentClipMode & PARENTCLIPMODE_CLIP)) )
+ {
+ pParent->mbInitClipRegion = TRUE;
+ pParent->mbInitChildRegion = TRUE;
+ }
+
+ // Schwestern muessen ihre ClipRegion auch neu berechnen
+ if ( mbClipSiblings )
+ {
+ Window* pWindow = mpNext;
+ while ( pWindow )
+ {
+ if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
+ bUpdate = FALSE;
+ pWindow = pWindow->mpNext;
+ }
+ }
+
+ return bUpdate;
+ }
+ else
+ return mpFrameWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplIntersectWindowClipRegion( Region& rRegion )
+{
+ if ( mbInitWinClipRegion )
+ ImplInitWinClipRegion();
+
+ rRegion.Intersect( maWinClipRegion );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplIntersectWindowRegion( Region& rRegion )
+{
+ rRegion.Intersect( Rectangle( Point( mnOutOffX, mnOutOffY ),
+ Size( mnOutWidth, mnOutHeight ) ) );
+ if ( mbWinRegion )
+ rRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplExcludeWindowRegion( Region& rRegion )
+{
+ if ( mbWinRegion )
+ {
+ Point aPoint( mnOutOffX, mnOutOffY );
+ Region aRegion( Rectangle( aPoint,
+ Size( mnOutWidth, mnOutHeight ) ) );
+ aRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) );
+ rRegion.Exclude( aRegion );
+ }
+ else
+ {
+ Point aPoint( mnOutOffX, mnOutOffY );
+ rRegion.Exclude( Rectangle( aPoint,
+ Size( mnOutWidth, mnOutHeight ) ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplExcludeOverlapWindows( Region& rRegion )
+{
+ Window* pWindow = mpFirstOverlap;
+ while ( pWindow )
+ {
+ if ( pWindow->mbReallyVisible )
+ {
+ pWindow->ImplExcludeWindowRegion( rRegion );
+ pWindow->ImplExcludeOverlapWindows( rRegion );
+ }
+
+ pWindow = pWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplExcludeOverlapWindows2( Region& rRegion )
+{
+ if ( mbReallyVisible )
+ ImplExcludeWindowRegion( rRegion );
+
+ ImplExcludeOverlapWindows( rRegion );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplClipBoundaries( Region& rRegion, BOOL bThis, BOOL bOverlaps )
+{
+ if ( bThis )
+ ImplIntersectWindowClipRegion( rRegion );
+ else if ( ImplIsOverlapWindow() )
+ {
+ // Evt. noch am Frame clippen
+ if ( !mbFrame )
+ rRegion.Intersect( Rectangle( Point( 0, 0 ), Size( mpFrameWindow->mnOutWidth, mpFrameWindow->mnOutHeight ) ) );
+
+ if ( bOverlaps && !rRegion.IsEmpty() )
+ {
+ // Clip Overlap Siblings
+ Window* pStartOverlapWindow = this;
+ while ( !pStartOverlapWindow->mbFrame )
+ {
+ Window* pOverlapWindow = pStartOverlapWindow->mpOverlapWindow->mpFirstOverlap;
+ while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
+ {
+ pOverlapWindow->ImplExcludeOverlapWindows2( rRegion );
+ pOverlapWindow = pOverlapWindow->mpNext;
+ }
+ pStartOverlapWindow = pStartOverlapWindow->mpOverlapWindow;
+ }
+
+ // Clip Child Overlap Windows
+ ImplExcludeOverlapWindows( rRegion );
+ }
+ }
+ else
+ ImplGetParent()->ImplIntersectWindowClipRegion( rRegion );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplClipChilds( Region& rRegion )
+{
+ BOOL bOtherClip = FALSE;
+ Window* pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ if ( pWindow->mbReallyVisible )
+ {
+ // ParentClipMode-Flags auswerten
+ USHORT nClipMode = pWindow->GetParentClipMode();
+ if ( !(nClipMode & PARENTCLIPMODE_NOCLIP) &&
+ ((nClipMode & PARENTCLIPMODE_CLIP) || (GetStyle() & WB_CLIPCHILDREN)) )
+ pWindow->ImplExcludeWindowRegion( rRegion );
+ else
+ bOtherClip = TRUE;
+ }
+
+ pWindow = pWindow->mpNext;
+ }
+
+ return bOtherClip;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplClipAllChilds( Region& rRegion )
+{
+ Window* pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ if ( pWindow->mbReallyVisible )
+ pWindow->ImplExcludeWindowRegion( rRegion );
+ pWindow = pWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplClipSiblings( Region& rRegion )
+{
+ Window* pWindow = ImplGetParent()->mpFirstChild;
+ while ( pWindow )
+ {
+ if ( pWindow == this )
+ break;
+
+ if ( pWindow->mbReallyVisible )
+ pWindow->ImplExcludeWindowRegion( rRegion );
+
+ pWindow = pWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInitWinClipRegion()
+{
+ // Build Window Region
+ maWinClipRegion = Rectangle( Point( mnOutOffX, mnOutOffY ),
+ Size( mnOutWidth, mnOutHeight ) );
+ if ( mbWinRegion )
+ maWinClipRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) );
+
+ // ClipSiblings
+ if ( mbClipSiblings && !ImplIsOverlapWindow() )
+ ImplClipSiblings( maWinClipRegion );
+
+ // Clip Parent Boundaries
+ ImplClipBoundaries( maWinClipRegion, FALSE, TRUE );
+
+ // Clip Children
+ if ( (GetStyle() & WB_CLIPCHILDREN) || mbClipChildren )
+ mbInitChildRegion = TRUE;
+
+ mbInitWinClipRegion = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInitWinChildClipRegion()
+{
+ if ( !mpFirstChild )
+ {
+ if ( mpChildClipRegion )
+ {
+ delete mpChildClipRegion;
+ mpChildClipRegion = NULL;
+ }
+ }
+ else
+ {
+ if ( !mpChildClipRegion )
+ mpChildClipRegion = new Region( maWinClipRegion );
+ else
+ *mpChildClipRegion = maWinClipRegion;
+
+ ImplClipChilds( *mpChildClipRegion );
+ }
+
+ mbInitChildRegion = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Region* Window::ImplGetWinChildClipRegion()
+{
+ if ( mbInitWinClipRegion )
+ ImplInitWinClipRegion();
+ if ( mbInitChildRegion )
+ ImplInitWinChildClipRegion();
+ if ( mpChildClipRegion )
+ return mpChildClipRegion;
+ else
+ return &maWinClipRegion;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplIntersectAndUnionOverlapWindows( const Region& rInterRegion, Region& rRegion )
+{
+ Window* pWindow = mpFirstOverlap;
+ while ( pWindow )
+ {
+ if ( pWindow->mbReallyVisible )
+ {
+ Region aTempRegion( rInterRegion );
+ pWindow->ImplIntersectWindowRegion( aTempRegion );
+ rRegion.Union( aTempRegion );
+ pWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
+ }
+
+ pWindow = pWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplIntersectAndUnionOverlapWindows2( const Region& rInterRegion, Region& rRegion )
+{
+ if ( mbReallyVisible )
+ {
+ Region aTempRegion( rInterRegion );
+ ImplIntersectWindowRegion( aTempRegion );
+ rRegion.Union( aTempRegion );
+ }
+
+ ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCalcOverlapRegionOverlaps( const Region& rInterRegion, Region& rRegion )
+{
+ // Clip Overlap Siblings
+ Window* pStartOverlapWindow;
+ if ( !ImplIsOverlapWindow() )
+ pStartOverlapWindow = mpOverlapWindow;
+ else
+ pStartOverlapWindow = this;
+ while ( !pStartOverlapWindow->mbFrame )
+ {
+ Window* pOverlapWindow = pStartOverlapWindow->mpOverlapWindow->mpFirstOverlap;
+ while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
+ {
+ pOverlapWindow->ImplIntersectAndUnionOverlapWindows2( rInterRegion, rRegion );
+ pOverlapWindow = pOverlapWindow->mpNext;
+ }
+ pStartOverlapWindow = pStartOverlapWindow->mpOverlapWindow;
+ }
+
+ // Clip Child Overlap Windows
+ if ( !ImplIsOverlapWindow() )
+ mpOverlapWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
+ else
+ ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCalcOverlapRegion( const Rectangle& rSourceRect, Region& rRegion,
+ BOOL bChilds, BOOL bParent, BOOL bSiblings )
+{
+ Region aRegion( rSourceRect );
+ if ( mbWinRegion )
+ rRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) );
+ Region aTempRegion;
+ Window* pWindow;
+
+ ImplCalcOverlapRegionOverlaps( aRegion, rRegion );
+
+ // Parent-Boundaries
+ if ( bParent )
+ {
+ pWindow = this;
+ if ( !ImplIsOverlapWindow() )
+ {
+ pWindow = ImplGetParent();
+ do
+ {
+ aTempRegion = aRegion;
+ pWindow->ImplExcludeWindowRegion( aTempRegion );
+ rRegion.Union( aTempRegion );
+ if ( pWindow->ImplIsOverlapWindow() )
+ break;
+ pWindow = pWindow->ImplGetParent();
+ }
+ while ( pWindow );
+ }
+ if ( !pWindow->mbFrame )
+ {
+ aTempRegion = aRegion;
+ aTempRegion.Exclude( Rectangle( Point( 0, 0 ), Size( mpFrameWindow->mnOutWidth, mpFrameWindow->mnOutHeight ) ) );
+ rRegion.Union( aTempRegion );
+ }
+ }
+
+ // Siblings
+ if ( bSiblings && !ImplIsOverlapWindow() )
+ {
+ pWindow = mpParent->mpFirstChild;
+ do
+ {
+ if ( pWindow->mbReallyVisible && (pWindow != this) )
+ {
+ aTempRegion = aRegion;
+ pWindow->ImplIntersectWindowRegion( aTempRegion );
+ rRegion.Union( aTempRegion );
+ }
+ pWindow = pWindow->mpNext;
+ }
+ while ( pWindow );
+ }
+
+ // Childs
+ if ( bChilds )
+ {
+ pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ if ( pWindow->mbReallyVisible )
+ {
+ aTempRegion = aRegion;
+ pWindow->ImplIntersectWindowRegion( aTempRegion );
+ rRegion.Union( aTempRegion );
+ }
+ pWindow = pWindow->mpNext;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCallPaint( const Region* pRegion, USHORT nPaintFlags )
+{
+ mbPaintFrame = FALSE;
+
+ if ( nPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
+ mnPaintFlags |= IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALLCHILDS | (nPaintFlags & IMPL_PAINT_PAINTALL);
+ if ( nPaintFlags & IMPL_PAINT_PAINTCHILDS )
+ mnPaintFlags |= IMPL_PAINT_PAINTCHILDS;
+ if ( nPaintFlags & IMPL_PAINT_ERASE )
+ mnPaintFlags |= IMPL_PAINT_ERASE;
+ if ( !mpFirstChild )
+ mnPaintFlags &= ~IMPL_PAINT_PAINTALLCHILDS;
+
+ if ( mbPaintDisabled )
+ {
+ if ( mnPaintFlags & IMPL_PAINT_PAINTALL )
+ Invalidate( INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
+ else if ( pRegion )
+ Invalidate( *pRegion, INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
+ return;
+ }
+
+ nPaintFlags = mnPaintFlags & ~(IMPL_PAINT_PAINT);
+
+ Region* pChildRegion = NULL;
+ if ( mnPaintFlags & IMPL_PAINT_PAINT )
+ {
+ Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
+ if ( mnPaintFlags & IMPL_PAINT_PAINTALL )
+ maInvalidateRegion = *pWinChildClipRegion;
+ else
+ {
+ if ( pRegion )
+ maInvalidateRegion.Union( *pRegion );
+ if ( mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
+ pChildRegion = new Region( maInvalidateRegion );
+ maInvalidateRegion.Intersect( *pWinChildClipRegion );
+ }
+ mnPaintFlags = 0;
+ if ( !maInvalidateRegion.IsEmpty() )
+ {
+ if ( mpCursor )
+ mpCursor->ImplHide();
+
+ mbInitClipRegion = TRUE;
+ mbInPaint = TRUE;
+
+ // Paint-Region zuruecksetzen
+ Region aPaintRegion( maInvalidateRegion );
+ Rectangle aPaintRect = ImplDevicePixelToLogic( aPaintRegion.GetBoundRect() );
+ mpPaintRegion = &aPaintRegion;
+ maInvalidateRegion.SetEmpty();
+
+ if ( (nPaintFlags & IMPL_PAINT_ERASE) && IsBackground() )
+ {
+ if ( IsClipRegion() )
+ {
+ Region aOldRegion = GetClipRegion();
+ SetClipRegion();
+ Erase();
+ SetClipRegion( aOldRegion );
+ }
+ else
+ Erase();
+ }
+ Paint( aPaintRect );
+
+ if ( mpWinData )
+ {
+ if ( mbFocusVisible )
+ ImplInvertFocus( *(mpWinData->mpFocusRect) );
+ if ( mbTrackVisible && (mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
+ InvertTracking( *(mpWinData->mpTrackRect), mpWinData->mnTrackFlags );
+ }
+ mbInPaint = FALSE;
+ mbInitClipRegion = TRUE;
+ mpPaintRegion = NULL;
+ if ( mpCursor )
+ mpCursor->ImplShow( FALSE );
+ }
+ }
+ else
+ mnPaintFlags = 0;
+
+ if ( nPaintFlags & (IMPL_PAINT_PAINTALLCHILDS | IMPL_PAINT_PAINTCHILDS) )
+ {
+ // die Childfenster ausgeben
+ Window* pTempWindow = mpFirstChild;
+ while ( pTempWindow )
+ {
+ if ( pTempWindow->mbVisible )
+ pTempWindow->ImplCallPaint( pChildRegion, nPaintFlags );
+ pTempWindow = pTempWindow->mpNext;
+ }
+ }
+
+ if ( pChildRegion )
+ delete pChildRegion;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCallOverlapPaint()
+{
+ // Zuerst geben wir die ueberlappenden Fenster aus
+ Window* pTempWindow = mpFirstOverlap;
+ while ( pTempWindow )
+ {
+ if ( pTempWindow->mbReallyVisible )
+ pTempWindow->ImplCallOverlapPaint();
+ pTempWindow = pTempWindow->mpNext;
+ }
+
+ // und dann erst uns selber
+ if ( mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
+ ImplCallPaint( NULL, mnPaintFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplPostPaint()
+{
+ if ( !mpFrameData->maPaintTimer.IsActive() )
+ mpFrameData->maPaintTimer.Start();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Window, ImplHandlePaintHdl, void*, EMPTYARG )
+{
+ if ( mbReallyVisible )
+ ImplCallOverlapPaint();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInvalidateFrameRegion( const Region* pRegion, USHORT nFlags )
+{
+ // PAINTCHILDS bei allen Parent-Fenster bis zum ersten OverlapWindow
+ // setzen
+ if ( !ImplIsOverlapWindow() )
+ {
+ Window* pTempWindow = this;
+ do
+ {
+ pTempWindow = pTempWindow->ImplGetParent();
+ if ( pTempWindow->mnPaintFlags & IMPL_PAINT_PAINTCHILDS )
+ break;
+ pTempWindow->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS;
+ }
+ while ( !pTempWindow->ImplIsOverlapWindow() );
+ }
+
+ // Paint-Flags setzen
+ mnPaintFlags |= IMPL_PAINT_PAINT;
+ if ( nFlags & INVALIDATE_CHILDREN )
+ mnPaintFlags |= IMPL_PAINT_PAINTALLCHILDS;
+ if ( !(nFlags & INVALIDATE_NOERASE) )
+ mnPaintFlags |= IMPL_PAINT_ERASE;
+ if ( !pRegion )
+ mnPaintFlags |= IMPL_PAINT_PAINTALL;
+
+ // Wenn nicht alles neu ausgegeben werden muss, dann die Region
+ // dazupacken
+ if ( !(mnPaintFlags & IMPL_PAINT_PAINTALL) )
+ maInvalidateRegion.Union( *pRegion );
+
+ ImplPostPaint();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInvalidateOverlapFrameRegion( const Region& rRegion )
+{
+ Region aRegion = rRegion;
+ ImplClipBoundaries( aRegion, TRUE, TRUE );
+ if ( !aRegion.IsEmpty() )
+ ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN );
+
+ // Dann invalidieren wir die ueberlappenden Fenster
+ Window* pTempWindow = mpFirstOverlap;
+ while ( pTempWindow )
+ {
+ if ( pTempWindow->IsVisible() )
+ pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
+
+ pTempWindow = pTempWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInvalidateParentFrameRegion( Region& rRegion )
+{
+ if ( mbOverlapWin )
+ mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
+ else
+ ImplGetParent()->ImplInvalidateFrameRegion( &rRegion, INVALIDATE_CHILDREN );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInvalidate( const Region* pRegion, USHORT nFlags )
+{
+ // Hintergrund-Sicherung zuruecksetzen
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+
+ // Feststellen, was neu ausgegeben werden muss
+ BOOL bInvalidateAll = !pRegion;
+
+ // Transparent-Invalidate beruecksichtigen
+ Window* pWindow = this;
+ if ( (mbPaintTransparent && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
+ {
+ Window* pTempWindow = pWindow->ImplGetParent();
+ while ( pTempWindow )
+ {
+ if ( !pTempWindow->IsPaintTransparent() )
+ {
+ pWindow = pTempWindow;
+ nFlags |= INVALIDATE_CHILDREN;
+ bInvalidateAll = FALSE;
+ break;
+ }
+
+ if ( pTempWindow->ImplIsOverlapWindow() )
+ break;
+
+ pTempWindow = pTempWindow->ImplGetParent();
+ }
+ }
+
+ // Region zusammenbauen
+ USHORT nOrgFlags = nFlags;
+ if ( !(nFlags & (INVALIDATE_CHILDREN | INVALIDATE_NOCHILDREN)) )
+ {
+ if ( pWindow->GetStyle() & WB_CLIPCHILDREN )
+ nFlags |= INVALIDATE_NOCHILDREN;
+ else
+ nFlags |= INVALIDATE_CHILDREN;
+ }
+ if ( (nFlags & INVALIDATE_NOCHILDREN) && pWindow->mpFirstChild )
+ bInvalidateAll = FALSE;
+ if ( bInvalidateAll )
+ pWindow->ImplInvalidateFrameRegion( NULL, nFlags );
+ else
+ {
+ Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ Region aRegion( aRect );
+ if ( pRegion )
+ aRegion.Intersect( *pRegion );
+ pWindow->ImplClipBoundaries( aRegion, TRUE, TRUE );
+ if ( nFlags & INVALIDATE_NOCHILDREN )
+ {
+ nFlags &= ~INVALIDATE_CHILDREN;
+ if ( !(nFlags & INVALIDATE_NOCLIPCHILDREN) )
+ {
+ if ( nOrgFlags & INVALIDATE_NOCHILDREN )
+ pWindow->ImplClipAllChilds( aRegion );
+ else
+ {
+ if ( pWindow->ImplClipChilds( aRegion ) )
+ nFlags |= INVALIDATE_CHILDREN;
+ }
+ }
+ }
+ if ( !aRegion.IsEmpty() )
+ pWindow->ImplInvalidateFrameRegion( &aRegion, nFlags );
+ }
+
+ if ( nFlags & INVALIDATE_UPDATE )
+ pWindow->Update();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplMoveInvalidateRegion( const Rectangle& rRect,
+ long nHorzScroll, long nVertScroll,
+ BOOL bChilds )
+{
+ if ( (mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALL)) == IMPL_PAINT_PAINT )
+ {
+ Region aTempRegion = maInvalidateRegion;
+ aTempRegion.Intersect( rRect );
+ aTempRegion.Move( nHorzScroll, nVertScroll );
+ maInvalidateRegion.Union( aTempRegion );
+ }
+
+ if ( bChilds && (mnPaintFlags & IMPL_PAINT_PAINTCHILDS) )
+ {
+ Window* pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, TRUE );
+ pWindow = pWindow->mpNext;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplMoveAllInvalidateRegions( const Rectangle& rRect,
+ long nHorzScroll, long nVertScroll,
+ BOOL bChilds )
+{
+ // Paint-Region auch verschieben, wenn noch Paints anstehen
+ ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChilds );
+ // Paint-Region muss bei uns verschoben gesetzt werden, die durch
+ // die Parents gezeichnet werden
+ if ( !ImplIsOverlapWindow() )
+ {
+ Region aPaintAllRegion;
+ Window* pPaintAllWindow = this;
+ do
+ {
+ pPaintAllWindow = pPaintAllWindow->ImplGetParent();
+ if ( pPaintAllWindow->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
+ {
+ if ( pPaintAllWindow->mnPaintFlags & IMPL_PAINT_PAINTALL )
+ {
+ aPaintAllRegion.SetEmpty();
+ break;
+ }
+ else
+ aPaintAllRegion.Union( pPaintAllWindow->maInvalidateRegion );
+ }
+ }
+ while ( !pPaintAllWindow->ImplIsOverlapWindow() );
+ if ( !aPaintAllRegion.IsEmpty() )
+ {
+ aPaintAllRegion.Move( nHorzScroll, nVertScroll );
+ USHORT nPaintFlags = 0;
+ if ( bChilds )
+ mnPaintFlags |= INVALIDATE_CHILDREN;
+ ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplValidateFrameRegion( const Region* pRegion, USHORT nFlags )
+{
+ if ( !pRegion )
+ maInvalidateRegion.SetEmpty();
+ else
+ {
+ // Wenn alle Childfenster neu ausgegeben werden muessen,
+ // dann invalidieren wir diese vorher
+ if ( (mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS) && mpFirstChild )
+ {
+ Region aChildRegion = maInvalidateRegion;
+ if ( mnPaintFlags & IMPL_PAINT_PAINTALL )
+ {
+ Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ aChildRegion = aRect;
+ }
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->Invalidate( aChildRegion, INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
+ pChild = pChild->mpNext;
+ }
+ }
+ if ( mnPaintFlags & IMPL_PAINT_PAINTALL )
+ {
+ Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ maInvalidateRegion = aRect;
+ }
+ maInvalidateRegion.Exclude( *pRegion );
+ }
+ mnPaintFlags &= ~IMPL_PAINT_PAINTALL;
+
+ if ( nFlags & VALIDATE_CHILDREN )
+ {
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->ImplValidateFrameRegion( pRegion, nFlags );
+ pChild = pChild->mpNext;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplValidate( const Region* pRegion, USHORT nFlags )
+{
+ // Region zusammenbauen
+ BOOL bValidateAll = !pRegion;
+ USHORT nOrgFlags = nFlags;
+ if ( !(nFlags & (VALIDATE_CHILDREN | VALIDATE_NOCHILDREN)) )
+ {
+ if ( GetStyle() & WB_CLIPCHILDREN )
+ nFlags |= VALIDATE_NOCHILDREN;
+ else
+ nFlags |= VALIDATE_CHILDREN;
+ }
+ if ( (nFlags & VALIDATE_NOCHILDREN) && mpFirstChild )
+ bValidateAll = FALSE;
+ if ( bValidateAll )
+ ImplValidateFrameRegion( NULL, nFlags );
+ else
+ {
+ Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ Region aRegion( aRect );
+ if ( pRegion )
+ aRegion.Intersect( *pRegion );
+ ImplClipBoundaries( aRegion, TRUE, TRUE );
+ if ( nFlags & VALIDATE_NOCHILDREN )
+ {
+ nFlags &= ~VALIDATE_CHILDREN;
+ if ( nOrgFlags & VALIDATE_NOCHILDREN )
+ ImplClipAllChilds( aRegion );
+ else
+ {
+ if ( ImplClipChilds( aRegion ) )
+ nFlags |= VALIDATE_CHILDREN;
+ }
+ }
+ if ( !aRegion.IsEmpty() )
+ ImplValidateFrameRegion( &aRegion, nFlags );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplScroll( const Rectangle& rRect,
+ long nHorzScroll, long nVertScroll, USHORT nFlags )
+{
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ nHorzScroll = ImplLogicWidthToDevicePixel( nHorzScroll );
+ nVertScroll = ImplLogicHeightToDevicePixel( nVertScroll );
+
+ if ( !nHorzScroll && !nVertScroll )
+ return;
+
+ // Hintergrund-Sicherung zuruecksetzen
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+
+ if ( mpCursor )
+ mpCursor->ImplHide();
+
+ USHORT nOrgFlags = nFlags;
+ if ( !(nFlags & (SCROLL_CHILDREN | SCROLL_NOCHILDREN)) )
+ {
+ if ( GetStyle() & WB_CLIPCHILDREN )
+ nFlags |= SCROLL_NOCHILDREN;
+ else
+ nFlags |= SCROLL_CHILDREN;
+ }
+
+ Region aInvalidateRegion;
+ BOOL bScrollChilds = (nFlags & SCROLL_CHILDREN) != 0;
+ BOOL bErase = (nFlags & SCROLL_NOERASE) == 0;
+
+ if ( !mpFirstChild )
+ bScrollChilds = FALSE;
+
+ // Paint-Bereiche anpassen
+ ImplMoveAllInvalidateRegions( rRect, nHorzScroll, nVertScroll, bScrollChilds );
+
+ if ( !(nFlags & SCROLL_NOINVALIDATE) )
+ {
+ ImplCalcOverlapRegion( rRect, aInvalidateRegion, !bScrollChilds, TRUE, FALSE );
+ if ( !aInvalidateRegion.IsEmpty() )
+ {
+ aInvalidateRegion.Move( nHorzScroll, nVertScroll );
+ bErase = TRUE;
+ }
+ if ( !(nFlags & SCROLL_NOWINDOWINVALIDATE) )
+ {
+ Rectangle aDestRect( rRect );
+ aDestRect.Move( nHorzScroll, nVertScroll );
+ Region aWinInvalidateRegion( rRect );
+ aWinInvalidateRegion.Exclude( aDestRect );
+ aInvalidateRegion.Union( aWinInvalidateRegion );
+ }
+ }
+
+ Point aPoint( mnOutOffX, mnOutOffY );
+ Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
+ if ( nFlags & SCROLL_CLIP )
+ aRegion.Intersect( rRect );
+ if ( mbWinRegion )
+ aRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) );
+ aRegion.Exclude( aInvalidateRegion );
+ ImplClipBoundaries( aRegion, FALSE, TRUE );
+ if ( !bScrollChilds )
+ {
+ if ( nOrgFlags & SCROLL_NOCHILDREN )
+ ImplClipAllChilds( aRegion );
+ else
+ ImplClipChilds( aRegion );
+ }
+ if ( mbClipRegion && (nFlags & SCROLL_USECLIPREGION) )
+ aRegion.Intersect( maRegion );
+ if ( !aRegion.IsEmpty() )
+ {
+ if ( mpWinData )
+ {
+ if ( mbFocusVisible )
+ ImplInvertFocus( *(mpWinData->mpFocusRect) );
+ if ( mbTrackVisible && (mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
+ InvertTracking( *(mpWinData->mpTrackRect), mpWinData->mnTrackFlags );
+ }
+
+#ifndef REMOTE_APPSERVER
+ SalGraphics* pGraphics = ImplGetFrameGraphics();
+ if ( pGraphics )
+ {
+ ImplSelectClipRegion( pGraphics, aRegion );
+ pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
+ rRect.Left(), rRect.Top(),
+ rRect.GetWidth(), rRect.GetHeight(),
+ SAL_COPYAREA_WINDOWINVALIDATE );
+ }
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics( TRUE );
+ if ( pGraphics )
+ {
+ pGraphics->SetClipRegion( aRegion );
+ pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
+ rRect.Left(), rRect.Top(),
+ rRect.GetWidth(), rRect.GetHeight(),
+ COPYAREA_WINDOWINVALIDATE );
+ }
+#endif
+
+ if ( mpWinData )
+ {
+ if ( mbFocusVisible )
+ ImplInvertFocus( *(mpWinData->mpFocusRect) );
+ if ( mbTrackVisible && (mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
+ InvertTracking( *(mpWinData->mpTrackRect), mpWinData->mnTrackFlags );
+ }
+ }
+
+ if ( !aInvalidateRegion.IsEmpty() )
+ {
+ USHORT nPaintFlags = INVALIDATE_CHILDREN;
+ if ( !bErase )
+ nPaintFlags |= INVALIDATE_NOERASE;
+ if ( !bScrollChilds )
+ {
+ if ( nOrgFlags & SCROLL_NOCHILDREN )
+ ImplClipAllChilds( aInvalidateRegion );
+ else
+ ImplClipChilds( aInvalidateRegion );
+ }
+ ImplInvalidateFrameRegion( &aInvalidateRegion, nPaintFlags );
+ }
+
+ if ( bScrollChilds )
+ {
+ Rectangle aDestRect( rRect );
+ Window* pWindow = mpFirstChild;
+ while ( pWindow )
+ {
+ Rectangle aWinRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
+ Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
+ if ( aDestRect.IsOver( aWinRect ) )
+ {
+ pWindow->mnX += nHorzScroll;
+ pWindow->maPos.X() += nHorzScroll;
+ pWindow->mnY += nVertScroll;
+ pWindow->maPos.Y() += nVertScroll;
+#ifndef REMOTE_APPSERVER
+ if ( pWindow->ImplUpdatePos() )
+ pWindow->ImplUpdateSysObjPos();
+#else
+ pWindow->ImplUpdatePos();
+#endif
+ if ( pWindow->IsReallyVisible() )
+ pWindow->ImplSetClipFlag();
+ if ( pWindow->mpClientWindow )
+ pWindow->mpClientWindow->maPos = pWindow->maPos;
+ if ( pWindow->IsVisible() )
+ {
+ pWindow->mbCallMove = FALSE;
+ pWindow->Move();
+ }
+ else
+ pWindow->mbCallMove = TRUE;
+ }
+ pWindow = pWindow->mpNext;
+ }
+ }
+
+ if ( nFlags & SCROLL_UPDATE )
+ Update();
+
+ if ( mpCursor )
+ mpCursor->ImplShow( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplUpdateAll( BOOL bOverlapWindows )
+{
+ if ( !mbReallyVisible )
+ return;
+
+ BOOL bFlush = FALSE;
+ if ( mpFrameWindow->mbPaintFrame )
+ {
+ Point aPoint( 0, 0 );
+ Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
+ ImplInvalidateOverlapFrameRegion( aRegion );
+ if ( mbFrame || (mpBorderWindow && mpBorderWindow->mbFrame) )
+ bFlush = TRUE;
+ }
+
+ // Ein Update wirkt immer auf das OverlapWindow, damit bei spaeteren
+ // Paints nicht zuviel gemalt wird, wenn dort ALLCHILDREN usw. gesetzt
+ // ist
+ Window* pWindow = ImplGetFirstOverlapWindow();
+ if ( bOverlapWindows )
+ pWindow->ImplCallOverlapPaint();
+ else
+ {
+ if ( pWindow->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
+ pWindow->ImplCallPaint( NULL, pWindow->mnPaintFlags );
+ }
+
+ if ( bFlush )
+ Flush();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplUpdateWindowPtr( Window* pWindow )
+{
+ if ( mpFrameWindow != pWindow->mpFrameWindow )
+ {
+ // Graphic freigeben
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+#else
+ ImplReleaseServerGraphics();
+ mpGraphics = pWindow->mpFrameWindow->mpGraphics;
+#endif
+ }
+
+ mpFrameData = pWindow->mpFrameData;
+ mpFrame = pWindow->mpFrame;
+ mpFrameWindow = pWindow->mpFrameWindow;
+ if ( pWindow->ImplIsOverlapWindow() )
+ mpOverlapWindow = pWindow;
+ else
+ mpOverlapWindow = pWindow->mpOverlapWindow;
+
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->ImplUpdateWindowPtr( pWindow );
+ pChild = pChild->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplUpdateWindowPtr()
+{
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->ImplUpdateWindowPtr( this );
+ pChild = pChild->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplUpdateOverlapWindowPtr( BOOL bNewFrame )
+{
+ BOOL bVisible = IsVisible();
+ Show( FALSE );
+ ImplRemoveWindow( bNewFrame );
+ Window* pRealParent = mpRealParent;
+ ImplInsertWindow( ImplGetParent() );
+ mpRealParent = pRealParent;
+ ImplUpdateWindowPtr();
+#ifndef REMOTE_APPSERVER
+ if ( ImplUpdatePos() )
+ ImplUpdateSysObjPos();
+#else
+ ImplUpdatePos();
+#endif
+
+ if ( bNewFrame )
+ {
+ Window* pOverlapWindow = mpFirstOverlap;
+ while ( pOverlapWindow )
+ {
+ Window* pNextOverlapWindow = pOverlapWindow->mpNext;
+ pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
+ pOverlapWindow = pNextOverlapWindow;
+ }
+ }
+
+ if ( bVisible )
+ Show( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplUpdatePos()
+{
+ BOOL bSysChild = FALSE;
+
+ if ( ImplIsOverlapWindow() )
+ {
+ mnOutOffX = mnX;
+ mnOutOffY = mnY;
+ }
+ else
+ {
+ Window* pParent = ImplGetParent();
+ mnOutOffX = mnX+pParent->mnOutOffX;
+ mnOutOffY = mnY+pParent->mnOutOffY;
+ }
+
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ if ( pChild->ImplUpdatePos() )
+ bSysChild = TRUE;
+ pChild = pChild->mpNext;
+ }
+
+#ifndef REMOTE_APPSERVER
+ if ( mpSysObj )
+ bSysChild = TRUE;
+#endif
+
+ return bSysChild;
+}
+
+// -----------------------------------------------------------------------
+
+#ifndef REMOTE_APPSERVER
+void Window::ImplUpdateSysObjPos()
+{
+ if ( mpSysObj )
+ mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
+
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->ImplUpdateSysObjPos();
+ pChild = pChild->mpNext;
+ }
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+/* --- RTL ---
+void Window::ImplAlignChilds()
+{
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->ImplPosSizeWindow( pChild->maPos.X(), 0, 0, 0, WINDOW_POSSIZE_X );
+ pChild = pChild->mpNext;
+ }
+}
+*/
+
+// -----------------------------------------------------------------------
+
+void Window::ImplPosSizeWindow( long nX, long nY,
+ long nWidth, long nHeight, USHORT nFlags )
+{
+ BOOL bNewPos = FALSE;
+ BOOL bNewSize = FALSE;
+ BOOL bNewWidth = FALSE;
+ BOOL bCopyBits = FALSE;
+ long nOldOutOffX = mnOutOffX;
+ long nOldOutOffY = mnOutOffY;
+ long nOldOutWidth = mnOutWidth;
+ long nOldOutHeight = mnOutHeight;
+ Region* pOverlapRegion = NULL;
+ Region* pOldRegion = NULL;
+
+ if ( IsReallyVisible() )
+ {
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+
+ Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ),
+ Size( nOldOutWidth, nOldOutHeight ) );
+ pOldRegion = new Region( aOldWinRect );
+ if ( mbWinRegion )
+ pOldRegion->Intersect( ImplPixelToDevicePixel( maWinRegion ) );
+
+ if ( mnOutWidth && mnOutHeight && !mbPaintTransparent &&
+ !mbInitWinClipRegion && !maWinClipRegion.IsEmpty() &&
+ !HasPaintEvent() )
+ bCopyBits = TRUE;
+ }
+
+ if ( nFlags & WINDOW_POSSIZE_WIDTH )
+ {
+ if ( nWidth < 0 )
+ nWidth = 0;
+ if ( nWidth != mnOutWidth )
+ {
+/* --- RTL ---
+ if ( !ImplIsOverlapWindow() )
+ {
+ if ( !(nFlags & WINDOW_POSSIZE_X) )
+ {
+ nFlags |= WINDOW_POSSIZE_X;
+ nX = mnX;
+ }
+ }
+*/
+ mnOutWidth = nWidth;
+ bNewSize = TRUE;
+ bCopyBits = FALSE;
+ bNewWidth = TRUE;
+ }
+ }
+ if ( nFlags & WINDOW_POSSIZE_HEIGHT )
+ {
+ if ( nHeight < 0 )
+ nHeight = 0;
+ if ( nHeight != mnOutHeight )
+ {
+ mnOutHeight = nHeight;
+ bNewSize = TRUE;
+ bCopyBits = FALSE;
+ }
+ }
+
+ if ( nFlags & WINDOW_POSSIZE_X )
+ {
+ if ( nX != mnX )
+ {
+ long nOrgX = nX;
+/* --- RTL ---
+ if ( !ImplIsOverlapWindow() )
+ nX = mpParent->mnOutWidth-mnOutWidth-nX;
+*/
+
+ if ( bCopyBits && !pOverlapRegion )
+ {
+ pOverlapRegion = new Region();
+ ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
+ Size( mnOutWidth, mnOutHeight ) ),
+ *pOverlapRegion, FALSE, TRUE, TRUE );
+ }
+ mnX = nX;
+ maPos.X() = nOrgX;
+ bNewPos = TRUE;
+ }
+ }
+ if ( nFlags & WINDOW_POSSIZE_Y )
+ {
+ if ( nY != mnY )
+ {
+ if ( bCopyBits && !pOverlapRegion )
+ {
+ pOverlapRegion = new Region();
+ ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
+ Size( mnOutWidth, mnOutHeight ) ),
+ *pOverlapRegion, FALSE, TRUE, TRUE );
+ }
+ mnY = nY;
+ maPos.Y() = nY;
+ bNewPos = TRUE;
+ }
+ }
+
+ if ( bNewPos || bNewSize )
+ {
+#ifndef REMOTE_APPSERVER
+ BOOL bUpdateSysObjPos = FALSE;
+ if ( bNewPos )
+ bUpdateSysObjPos = ImplUpdatePos();
+#else
+ if ( bNewPos )
+ ImplUpdatePos();
+#endif
+
+ if ( mpClientWindow )
+ {
+ mpClientWindow->ImplPosSizeWindow( mpClientWindow->mnLeftBorder,
+ mpClientWindow->mnTopBorder,
+ mnOutWidth-mpClientWindow->mnLeftBorder-mpClientWindow->mnRightBorder,
+ mnOutHeight-mpClientWindow->mnTopBorder-mpClientWindow->mnBottomBorder,
+ WINDOW_POSSIZE_X | WINDOW_POSSIZE_Y |
+ WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT );
+ // Wenn wir ein ClientWindow haben, dann hat dieses fuer die
+ // Applikation auch die Position des FloatingWindows
+ mpClientWindow->maPos = maPos;
+ if ( bNewPos )
+ {
+ if ( mpClientWindow->IsVisible() )
+ {
+ mpClientWindow->mbCallMove = FALSE;
+ mpClientWindow->Move();
+ }
+ else
+ mpClientWindow->mbCallMove = TRUE;
+ }
+ }
+ else
+ {
+ if ( mpBorderWindow )
+ maPos = mpBorderWindow->maPos;
+ }
+
+/* --- RTL ---
+ if ( bNewWidth && !ImplIsOverlapWindow() )
+ ImplAlignChilds();
+*/
+
+ // Move()/Resize() werden erst bei Show() gerufen, damit min. eins vor
+ // einem Show() kommt
+ if ( IsVisible() )
+ {
+ if ( bNewPos )
+ {
+ mbCallMove = FALSE;
+ Move();
+ }
+ if ( bNewSize )
+ {
+ mbCallResize = FALSE;
+ Resize();
+ }
+ }
+ else
+ {
+ if ( bNewPos )
+ mbCallMove = TRUE;
+ if ( bNewSize )
+ mbCallResize = TRUE;
+ }
+
+#ifndef REMOTE_APPSERVER
+ BOOL bUpdateSysObjClip = FALSE;
+#endif
+ if ( IsReallyVisible() )
+ {
+ if ( bNewPos || bNewSize )
+ {
+ // Hintergrund-Sicherung zuruecksetzen
+ if ( mpOverlapData && mpOverlapData->mpSaveBackDev )
+ ImplDeleteOverlapBackground();
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+ // Clip-Flag neu setzen
+#ifndef REMOTE_APPSERVER
+ bUpdateSysObjClip = !ImplSetClipFlag( TRUE );
+#else
+ ImplSetClipFlag();
+#endif
+ }
+
+ // Fensterinhalt invalidieren ?
+ if ( bNewPos || (mnOutWidth > nOldOutWidth) || (mnOutHeight > nOldOutHeight) )
+ {
+ if ( bNewPos )
+ {
+ BOOL bInvalidate = FALSE;
+ BOOL bParentPaint = TRUE;
+ if ( !ImplIsOverlapWindow() )
+ bParentPaint = mpParent->IsPaintEnabled();
+ if ( bCopyBits && bParentPaint && !HasPaintEvent() )
+ {
+ Point aPoint( mnOutOffX, mnOutOffY );
+ Region aRegion( Rectangle( aPoint,
+ Size( mnOutWidth, mnOutHeight ) ) );
+ if ( mbWinRegion )
+ aRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) );
+ ImplClipBoundaries( aRegion, FALSE, TRUE );
+ if ( !pOverlapRegion->IsEmpty() )
+ {
+ pOverlapRegion->Move( mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY );
+ aRegion.Exclude( *pOverlapRegion );
+ }
+ if ( !aRegion.IsEmpty() )
+ {
+ // Paint-Bereiche anpassen
+ ImplMoveAllInvalidateRegions( Rectangle( Point( nOldOutOffX, nOldOutOffY ),
+ Size( nOldOutWidth, nOldOutHeight ) ),
+ mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY,
+ TRUE );
+#ifndef REMOTE_APPSERVER
+ SalGraphics* pGraphics = ImplGetFrameGraphics();
+ if ( pGraphics )
+ {
+ BOOL bSelectClipRegion = ImplSelectClipRegion( pGraphics, aRegion );
+ if ( bSelectClipRegion )
+ {
+ pGraphics->CopyArea( mnOutOffX, mnOutOffY,
+ nOldOutOffX, nOldOutOffY,
+ nOldOutWidth, nOldOutHeight,
+ SAL_COPYAREA_WINDOWINVALIDATE );
+ }
+ else
+ bInvalidate = TRUE;
+ }
+ else
+ bInvalidate = TRUE;
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics( TRUE );
+ if ( pGraphics )
+ {
+ pGraphics->SetClipRegion( aRegion );
+ pGraphics->CopyArea( mnOutOffX, mnOutOffY,
+ nOldOutOffX, nOldOutOffY,
+ nOldOutWidth, nOldOutHeight,
+ COPYAREA_WINDOWINVALIDATE );
+ }
+ else
+ bInvalidate = TRUE;
+#endif
+ if ( !bInvalidate )
+ {
+ if ( !pOverlapRegion->IsEmpty() )
+ ImplInvalidateFrameRegion( pOverlapRegion, INVALIDATE_CHILDREN );
+ }
+ }
+ }
+ else
+ bInvalidate = TRUE;
+ if ( bInvalidate )
+ ImplInvalidateFrameRegion( NULL, INVALIDATE_CHILDREN );
+ }
+ else
+ {
+ Point aPoint( mnOutOffX, mnOutOffY );
+ Region aRegion( Rectangle( aPoint,
+ Size( mnOutWidth, mnOutHeight ) ) );
+ aRegion.Exclude( *pOldRegion );
+ if ( mbWinRegion )
+ aRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) );
+ ImplClipBoundaries( aRegion, FALSE, TRUE );
+ if ( !aRegion.IsEmpty() )
+ ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN );
+ }
+ }
+
+ // Parent oder Overlaps invalidieren
+ if ( bNewPos ||
+ (mnOutWidth < nOldOutWidth) || (mnOutHeight < nOldOutHeight) )
+ {
+ Region aRegion( *pOldRegion );
+ if ( !mbPaintTransparent )
+ ImplExcludeWindowRegion( aRegion );
+ ImplClipBoundaries( aRegion, FALSE, TRUE );
+ if ( !aRegion.IsEmpty() && !mpBorderWindow )
+ ImplInvalidateParentFrameRegion( aRegion );
+ }
+ }
+
+#ifndef REMOTE_APPSERVER
+ // System-Objekte anpassen
+ if ( bUpdateSysObjClip )
+ ImplUpdateSysObjClip();
+ if ( bUpdateSysObjPos )
+ ImplUpdateSysObjPos();
+ if ( bNewSize && mpSysObj )
+ mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
+#endif
+ }
+
+ if ( pOverlapRegion )
+ delete pOverlapRegion;
+ if ( pOldRegion )
+ delete pOldRegion;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplToBottomChild()
+{
+ if ( !ImplIsOverlapWindow() && !mbReallyVisible && (mpParent->mpLastChild != this) )
+ {
+ // Fenster an das Ende der Liste setzen
+ if ( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ mpParent->mpFirstChild = mpNext;
+ mpNext->mpPrev = mpPrev;
+ mpPrev = mpParent->mpLastChild;
+ mpParent->mpLastChild = this;
+ mpPrev->mpNext = this;
+ mpNext = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData )
+{
+ DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" );
+
+ if ( !mbFrame )
+ {
+ if ( IsReallyVisible() )
+ {
+ // Region berechnen, wo das Fenster mit anderen Fenstern ueberlappt
+ Point aPoint( mnOutOffX, mnOutOffY );
+ Region aRegion( Rectangle( aPoint,
+ Size( mnOutWidth, mnOutHeight ) ) );
+ Region aInvalidateRegion;
+ ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion );
+
+ if ( !aInvalidateRegion.IsEmpty() )
+ {
+ ImplCalcToTopData* pData = new ImplCalcToTopData;
+ pPrevData->mpNext = pData;
+ pData->mpNext = NULL;
+ pData->mpWindow = this;
+ pData->mpInvalidateRegion = new Region( aInvalidateRegion );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCalcChildOverlapToTop( ImplCalcToTopData* pPrevData )
+{
+ DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcChildOverlapToTop(): Is not a OverlapWindow" );
+
+ ImplCalcToTop( pPrevData );
+ if ( pPrevData->mpNext )
+ pPrevData = pPrevData->mpNext;
+
+ Window* pOverlap = mpFirstOverlap;
+ while ( pOverlap )
+ {
+ pOverlap->ImplCalcToTop( pPrevData );
+ if ( pPrevData->mpNext )
+ pPrevData = pPrevData->mpNext;
+ pOverlap = pOverlap->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplToTop( USHORT nFlags )
+{
+ DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" );
+
+ if ( mbFrame )
+ {
+ // Wenn in das externe Fenster geklickt wird, ist dieses
+ // dafuer zustaendig dafuer zu sorgen, das unser Frame
+ // nach vorne kommt
+ if ( !mpFrameData->mbHasFocus &&
+ !mpFrameData->mbSysObjFocus &&
+ !mpFrameData->mbInSysObjFocusHdl &&
+ !mpFrameData->mbInSysObjToTopHdl )
+ {
+#ifndef REMOTE_APPSERVER
+ USHORT nSysFlags = 0;
+ if ( nFlags & TOTOP_RESTOREWHENMIN )
+ nSysFlags = SAL_FRAME_TOTOP_RESTOREWHENMIN;
+ if ( nFlags & TOTOP_FOREGROUNDTASK )
+ nSysFlags = SAL_FRAME_TOTOP_FOREGROUNDTASK;
+ mpFrame->ToTop( nSysFlags );
+#else
+ mpFrame->ToTop( nFlags );
+#endif
+ }
+ }
+ else
+ {
+ if ( mpOverlapWindow->mpFirstOverlap != this )
+ {
+ // Fenster aus der Liste entfernen
+ mpPrev->mpNext = mpNext;
+ if ( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ mpOverlapWindow->mpLastOverlap = mpPrev;
+
+ // AlwaysOnTop beruecksichtigen
+ BOOL bOnTop = IsAlwaysOnTopEnabled();
+ Window* pNextWin = mpOverlapWindow->mpFirstOverlap;
+ if ( !bOnTop )
+ {
+ while ( pNextWin )
+ {
+ if ( !pNextWin->IsAlwaysOnTopEnabled() )
+ break;
+ pNextWin = pNextWin->mpNext;
+ }
+ }
+
+ // TopLevel abpruefen
+ BYTE nTopLevel = mpOverlapData->mnTopLevel;
+ while ( pNextWin )
+ {
+ if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) ||
+ (nTopLevel <= pNextWin->mpOverlapData->mnTopLevel) )
+ break;
+ pNextWin = pNextWin->mpNext;
+ }
+
+ // Fenster in die Liste wieder eintragen
+ mpNext = pNextWin;
+ if ( pNextWin )
+ {
+ mpPrev = pNextWin->mpPrev;
+ pNextWin->mpPrev = this;
+ }
+ else
+ {
+ mpPrev = mpOverlapWindow->mpLastOverlap;
+ mpOverlapWindow->mpLastOverlap = this;
+ }
+ if ( mpPrev )
+ mpPrev->mpNext = this;
+ else
+ mpOverlapWindow->mpFirstOverlap = this;
+
+ // ClipRegion muss von diesem Fenster und allen weiteren
+ // ueberlappenden Fenstern neu berechnet werden.
+ if ( IsReallyVisible() )
+ {
+ // Hintergrund-Sicherung zuruecksetzen
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+ mpOverlapWindow->ImplSetClipFlagOverlapWindows();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplStartToTop( USHORT nFlags )
+{
+ ImplCalcToTopData aStartData;
+ ImplCalcToTopData* pCurData;
+ ImplCalcToTopData* pNextData;
+ Window* pOverlapWindow;
+ if ( ImplIsOverlapWindow() )
+ pOverlapWindow = this;
+ else
+ pOverlapWindow = mpOverlapWindow;
+
+ // Zuerst die Paint-Bereiche berechnen
+ Window* pTempOverlapWindow = pOverlapWindow;
+ aStartData.mpNext = NULL;
+ pCurData = &aStartData;
+ do
+ {
+ pTempOverlapWindow->ImplCalcToTop( pCurData );
+ if ( pCurData->mpNext )
+ pCurData = pCurData->mpNext;
+ pTempOverlapWindow = pTempOverlapWindow->mpOverlapWindow;
+ }
+ while ( !pTempOverlapWindow->mbFrame );
+ // Dann die Paint-Bereiche der ChildOverlap-Windows berechnen
+ pTempOverlapWindow = mpFirstOverlap;
+ while ( pTempOverlapWindow )
+ {
+ pTempOverlapWindow->ImplCalcToTop( pCurData );
+ if ( pCurData->mpNext )
+ pCurData = pCurData->mpNext;
+ pTempOverlapWindow = pTempOverlapWindow->mpNext;
+ }
+
+ // Dann die Fenster-Verkettung aendern
+ pTempOverlapWindow = pOverlapWindow;
+ do
+ {
+ pTempOverlapWindow->ImplToTop( nFlags );
+ pTempOverlapWindow = pTempOverlapWindow->mpOverlapWindow;
+ }
+ while ( !pTempOverlapWindow->mbFrame );
+ // Und zum Schluss invalidieren wir die ungueltigen Bereiche
+ pCurData = aStartData.mpNext;
+ while ( pCurData )
+ {
+ pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, INVALIDATE_CHILDREN );
+ pNextData = pCurData->mpNext;
+ delete pCurData->mpInvalidateRegion;
+ delete pCurData;
+ pCurData = pNextData;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplFocusToTop( USHORT nFlags, BOOL bReallyVisible )
+{
+ // Soll Focus auch geholt werden?
+ if ( !(nFlags & TOTOP_NOGRABFOCUS) )
+ {
+ // Erstes Fenster mit GrabFocus-Activate bekommt den Focus
+ Window* pFocusWindow = this;
+ while ( !pFocusWindow->ImplIsOverlapWindow() )
+ {
+ // Nur wenn Fenster kein Border-Fenster hat, da wir
+ // immer das dazugehoerende BorderFenster finden wollen
+ if ( !pFocusWindow->mpBorderWindow )
+ {
+ if ( pFocusWindow->mnActivateMode & ACTIVATE_MODE_GRABFOCUS )
+ break;
+ }
+ pFocusWindow = pFocusWindow->ImplGetParent();
+ }
+ if ( (pFocusWindow->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) &&
+ !pFocusWindow->HasChildPathFocus( TRUE ) )
+ pFocusWindow->GrabFocus();
+ }
+
+ if ( bReallyVisible )
+ ImplGenerateMouseMove();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplShowAllOverlaps()
+{
+ Window* pOverlapWindow = mpFirstOverlap;
+ while ( pOverlapWindow )
+ {
+ if ( pOverlapWindow->mbOverlapVisible )
+ {
+ pOverlapWindow->Show( TRUE, SHOW_NOACTIVATE );
+ pOverlapWindow->mbOverlapVisible = FALSE;
+ }
+
+ pOverlapWindow = pOverlapWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplHideAllOverlaps()
+{
+ Window* pOverlapWindow = mpFirstOverlap;
+ while ( pOverlapWindow )
+ {
+ if ( pOverlapWindow->IsVisible() )
+ {
+ pOverlapWindow->mbOverlapVisible = TRUE;
+ pOverlapWindow->Show( FALSE );
+ }
+
+ pOverlapWindow = pOverlapWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCallMouseMove( USHORT nMouseCode, BOOL bModChanged )
+{
+ if ( mpFrameData->mbMouseIn && mpFrameWindow->mbReallyVisible )
+ {
+ ULONG nTime = Time::GetSystemTicks();
+ long nX = mpFrameData->mnLastMouseX;
+ long nY = mpFrameData->mnLastMouseY;
+ USHORT nCode = nMouseCode;
+ USHORT nMode = mpFrameData->mnMouseMode;
+ BOOL bLeave;
+ // Auf MouseLeave testen
+ if ( ((nX < 0) || (nY < 0) ||
+ (nX >= mpFrameWindow->mnOutWidth) ||
+ (nY >= mpFrameWindow->mnOutHeight)) &&
+ !ImplGetSVData()->maWinData.mpCaptureWin )
+ bLeave = TRUE;
+ else
+ bLeave = FALSE;
+ nMode |= MOUSE_SYNTHETIC;
+ if ( bModChanged )
+ nMode |= MOUSE_MODIFIERCHANGED;
+ ImplHandleMouseEvent( mpFrameWindow, EVENT_MOUSEMOVE, bLeave, nX, nY, nTime, nCode, nMode );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplGenerateMouseMove()
+{
+ if ( !mpFrameData->mnMouseMoveId )
+ Application::PostUserEvent( mpFrameData->mnMouseMoveId, LINK( mpFrameWindow, Window, ImplGenerateMouseMoveHdl ) );
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Window, ImplGenerateMouseMoveHdl, void*, EMPTYARG )
+{
+ mpFrameData->mnMouseMoveId = 0;
+ ImplCallMouseMove( mpFrameData->mnMouseCode );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInvertFocus( const Rectangle& rRect )
+{
+ InvertTracking( rRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCallFocusChangeActivate( Window* pNewOverlapWindow,
+ Window* pOldOverlapWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pNewRealWindow;
+ Window* pOldRealWindow;
+ Window* pLastRealWindow;
+ BOOL bCallActivate = TRUE;
+ BOOL bCallDeactivate = TRUE;
+
+ pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
+ pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
+ if ( (pOldRealWindow->GetType() != WINDOW_FLOATINGWINDOW) ||
+ pOldRealWindow->GetActivateMode() )
+ {
+ if ( (pNewRealWindow->GetType() == WINDOW_FLOATINGWINDOW) &&
+ !pNewRealWindow->GetActivateMode() )
+ {
+ pSVData->maWinData.mpLastDeacWin = pOldOverlapWindow;
+ bCallDeactivate = FALSE;
+ }
+ }
+ else if ( (pNewRealWindow->GetType() != WINDOW_FLOATINGWINDOW) ||
+ pNewRealWindow->GetActivateMode() )
+ {
+ if ( pSVData->maWinData.mpLastDeacWin )
+ {
+ if ( pSVData->maWinData.mpLastDeacWin == pNewOverlapWindow )
+ bCallActivate = FALSE;
+ else
+ {
+ pLastRealWindow = pSVData->maWinData.mpLastDeacWin->ImplGetWindow();
+ pSVData->maWinData.mpLastDeacWin->mbActive = FALSE;
+ pSVData->maWinData.mpLastDeacWin->Deactivate();
+ if ( pLastRealWindow != pSVData->maWinData.mpLastDeacWin )
+ {
+ pLastRealWindow->mbActive = TRUE;
+ pLastRealWindow->Activate();
+ }
+ }
+ pSVData->maWinData.mpLastDeacWin = NULL;
+ }
+ }
+
+ if ( bCallDeactivate )
+ {
+ pOldOverlapWindow->mbActive = FALSE;
+ pOldOverlapWindow->Deactivate();
+ if ( pOldRealWindow != pOldOverlapWindow )
+ {
+ pOldRealWindow->mbActive = FALSE;
+ pOldRealWindow->Deactivate();
+ }
+ }
+ if ( bCallActivate )
+ {
+ pNewOverlapWindow->mbActive = TRUE;
+ pNewOverlapWindow->Activate();
+ if ( pNewRealWindow != pNewOverlapWindow )
+ {
+ pNewRealWindow->mbActive = TRUE;
+ pNewRealWindow->Activate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplGrabFocus( USHORT nFlags )
+{
+ // Es soll immer das Client-Fenster den Focus bekommen. Falls
+ // wir mal auch Border-Fenstern den Focus geben wollen,
+ // muessten wir bei allen GrabFocus()-Aufrufen in VCL dafuer
+ // sorgen, das es an der Stelle gemacht wird. Dies wuerde
+ // beispielsweise bei ToTop() der Fall sein.
+ if ( mpClientWindow )
+ {
+ // Wegen nicht ganz durchdachtem Konzept muessen wir hier
+ // leider noch einen Hack einbauen, damit wenn Dialoge
+ // geschlossen werden der Focus wieder auf das richtige
+ // Fenster zurueckgesetzt wird
+ if ( mpLastFocusWindow && (mpLastFocusWindow != this) &&
+ !(mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
+ mpLastFocusWindow->IsEnabled() )
+ mpLastFocusWindow->GrabFocus();
+ else
+ mpClientWindow->GrabFocus();
+ return;
+ }
+ else if ( mbFrame )
+ {
+ // Wegen nicht ganz durchdachtem Konzept muessen wir hier
+ // leider noch einen Hack einbauen, damit wenn Dialoge
+ // geschlossen werden der Focus wieder auf das richtige
+ // Fenster zurueckgesetzt wird
+ if ( mpLastFocusWindow && (mpLastFocusWindow != this) &&
+ !(mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
+ mpLastFocusWindow->IsEnabled() )
+ {
+ mpLastFocusWindow->GrabFocus();
+ return;
+ }
+ }
+
+ // Wir brauchen Focus nur setzen, wenn es diesen noch nicht hat
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maWinData.mpFocusWin != this )
+ {
+ // Dieses Fenster als letztes FocusWindow merken
+ Window* pOverlapWindow = ImplGetFirstOverlapWindow();
+ pOverlapWindow->mpLastFocusWindow = this;
+ mpFrameData->mpFocusWin = this;
+
+#ifndef REMOTE_APPSERVER
+ if ( !mpSysObj && !mpFrameData->mbHasFocus )
+#else
+ if ( !mpFrameData->mbHasFocus )
+#endif
+ {
+ // Hier setzen wir schon den Focus um, da ToTop() den Focus
+ // nicht auf ein anderes Fenster setzen darf
+ DBG_WARNING( "Window::GrabFocus() - Frame doesn't have the focus" );
+ mpFrame->ToTop( 0 );
+ return;
+ }
+
+ Window* pOldFocusWindow = pSVData->maWinData.mpFocusWin;
+ pSVData->maWinData.mpFocusWin = this;
+
+ if ( pOldFocusWindow )
+ {
+ // Cursor hiden
+ if ( pOldFocusWindow->mpCursor )
+ pOldFocusWindow->mpCursor->ImplHide();
+ }
+
+ // !!!!! Wegen altem SV-Office Activate/Deavtivate Handling
+ // !!!!! erstmal so wie frueher
+ if ( pOldFocusWindow )
+ {
+ // Focus merken
+ Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
+ Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
+ if ( pOldOverlapWindow != pNewOverlapWindow )
+ ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
+ }
+ else
+ {
+ Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
+ Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
+ pNewOverlapWindow->mbActive = TRUE;
+ pNewOverlapWindow->Activate();
+ if ( pNewRealWindow != pNewOverlapWindow )
+ {
+ pNewRealWindow->mbActive = TRUE;
+ pNewRealWindow->Activate();
+ }
+ }
+/*
+ // call Deactivate and Activate
+ Window* pDeactivateParent;
+ Window* pActivateParent;
+ Window* pParent;
+ Window* pLastParent;
+ pDeactivateParent = pOldFocusWindow;
+ while ( pDeactivateParent )
+ {
+ pParent = pDeactivateParent;
+ if ( pParent->ImplIsChild( this ) )
+ break;
+
+ if ( pDeactivateParent->ImplIsOverlapWindow() )
+ {
+ if ( !pDeactivateParent->mbParentActive )
+ break;
+ }
+
+ pDeactivateParent = pDeactivateParent->ImplGetParent();
+ }
+ if ( pOldFocusWindow )
+ {
+ pActivateParent = this;
+ while ( pActivateParent )
+ {
+ pParent = pActivateParent;
+ if ( pParent->ImplIsChild( pOldFocusWindow ) )
+ break;
+
+ if ( pActivateParent->ImplIsOverlapWindow() )
+ {
+ if ( !pActivateParent->mbParentActive )
+ break;
+ }
+
+ pActivateParent = pActivateParent->ImplGetParent();
+ }
+ }
+ else
+ {
+ if ( ImplIsOverlapWindow() )
+ pActivateParent = this;
+ else
+ pActivateParent = mpOverlapWindow;
+ while ( pActivateParent )
+ {
+ if ( pActivateParent->ImplIsOverlapWindow() )
+ {
+ if ( !pActivateParent->mbParentActive )
+ break;
+ }
+
+ pActivateParent = pActivateParent->ImplGetParent();
+ }
+ }
+ if ( pDeactivateParent )
+ {
+ do
+ {
+ pLastParent = pOldFocusWindow;
+ if ( pLastParent != pDeactivateParent )
+ {
+ pParent = pLastParent->ImplGetParent();
+ while ( pParent )
+ {
+ if ( pParent == pDeactivateParent )
+ break;
+ pLastParent = pParent;
+ pParent = pParent->ImplGetParent();
+ }
+ }
+ else
+ pParent = pLastParent;
+
+ pParent->mbActive = FALSE;
+ pParent->Deactivate();
+ pDeactivateParent = pLastParent;
+ }
+ while ( pDeactivateParent != pOldFocusWindow );
+ }
+ do
+ {
+ pLastParent = this;
+ if ( pLastParent != pActivateParent )
+ {
+ pParent = pLastParent->ImplGetParent();
+ while ( pParent )
+ {
+ if ( pParent == pActivateParent )
+ break;
+ pLastParent = pParent;
+ pParent = pParent->ImplGetParent();
+ }
+ }
+ else
+ pParent = pLastParent;
+
+ pParent->mbActive = TRUE;
+ pParent->Activate();
+ pActivateParent = pLastParent;
+ }
+ while ( pActivateParent != this );
+*/
+ // call Get- and LoseFocus
+ if ( pOldFocusWindow )
+ {
+ if ( pOldFocusWindow->IsTracking() &&
+ (pSVData->maWinData.mnTrackFlags & STARTTRACK_FOCUSCANCEL) )
+ pOldFocusWindow->EndTracking( ENDTRACK_CANCEL | ENDTRACK_FOCUS );
+ pOldFocusWindow->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
+ NotifyEvent aNEvt( EVENT_LOSEFOCUS, pOldFocusWindow );
+ if ( !ImplCallPreNotify( aNEvt ) )
+ pOldFocusWindow->LoseFocus();
+ pOldFocusWindow->ImplCallDeactivateListeners( this );
+ }
+
+ if ( pSVData->maWinData.mpFocusWin == this )
+ {
+#ifndef REMOTE_APPSERVER
+ if ( mpSysObj )
+ {
+ mpFrameData->mpFocusWin = this;
+ if ( !mpFrameData->mbInSysObjFocusHdl )
+ mpSysObj->GrabFocus();
+ }
+#endif
+
+ if ( pSVData->maWinData.mpFocusWin == this )
+ {
+ if ( mpCursor )
+ mpCursor->ImplShow();
+ mbInFocusHdl = TRUE;
+ mnGetFocusFlags = nFlags;
+ NotifyEvent aNEvt( EVENT_GETFOCUS, this );
+ if ( !ImplCallPreNotify( aNEvt ) )
+ GetFocus();
+ ImplCallActivateListeners( pOldFocusWindow );
+ mnGetFocusFlags = 0;
+ mbInFocusHdl = FALSE;
+ }
+ }
+
+ GetpApp()->FocusChanged();
+ ImplNewInputContext();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplNewInputContext()
+{
+#ifndef REMOTE_APPSERVER
+ SalInputContext aNewContext;
+ const InputContext& rInputContext = GetInputContext();
+ const Font& rFont = rInputContext.GetFont();
+ const XubString& rFontName = rFont.GetName();
+ ImplFontEntry* pFontEntry = NULL;
+ if ( rFontName.Len() )
+ {
+ Size aSize = ImplLogicToDevicePixel( rFont.GetSize() );
+ if ( !aSize.Height() )
+ {
+ // Nur dann Defaultgroesse setzen, wenn Fonthoehe auch in logischen
+ // Koordinaaten 0 ist
+ if ( rFont.GetSize().Height() )
+ aSize.Height() = 1;
+ else
+ aSize.Height() = (12*mnDPIY)/72;
+ }
+ pFontEntry = mpFontCache->Get( mpFontList, rFont, aSize );
+ aNewContext.mpFont = &(mpFontEntry->maFontSelData);
+ }
+ else
+ aNewContext.mpFont = NULL;
+ aNewContext.meCharSet = rFont.GetCharSet();
+ aNewContext.meLanguage = rFont.GetLanguage();
+ aNewContext.mnOptions = rInputContext.GetOptions();
+ ImplGetFrame()->SetInputContext( &aNewContext );
+
+ if ( pFontEntry )
+ mpFontCache->Release( pFontEntry );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+Window::Window( WindowType nType ) :
+ maZoom( 1, 1 ),
+ maWinRegion( REGION_NULL ),
+ maWinClipRegion( REGION_NULL )
+{
+ DBG_CTOR( Window, ImplDbgCheckWindow );
+
+ ImplInitData( nType );
+}
+
+// -----------------------------------------------------------------------
+
+Window::Window( Window* pParent, WinBits nStyle ) :
+ maZoom( 1, 1 ),
+ maWinRegion( REGION_NULL ),
+ maWinClipRegion( REGION_NULL )
+{
+ DBG_CTOR( Window, ImplDbgCheckWindow );
+
+ ImplInitData( WINDOW_WINDOW );
+ ImplInit( pParent, nStyle, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+Window::Window( Window* pParent, const ResId& rResId ) :
+ maZoom( 1, 1 ),
+ maWinRegion( REGION_NULL ),
+ maWinClipRegion( REGION_NULL )
+{
+ DBG_CTOR( Window, ImplDbgCheckWindow );
+
+ ImplInitData( WINDOW_WINDOW );
+ rResId.SetRT( RSC_WINDOW );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle, NULL );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+Window::~Window()
+{
+ DBG_DTOR( Window, ImplDbgCheckWindow );
+
+ mbInDtor = TRUE;
+
+ UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
+ if ( pWrapper )
+ pWrapper->WindowDestroyed( this );
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maHelpData.mpHelpWin && (pSVData->maHelpData.mpHelpWin->GetParent() == this) )
+ ImplDestroyHelpWindow( FALSE );
+
+ DBG_ASSERT( pSVData->maWinData.mpTrackWin != this,
+ "Window::~Window(): Window is in TrackingMode" );
+ DBG_ASSERT( pSVData->maWinData.mpCaptureWin != this,
+ "Window::~Window(): Window has the mouse captured" );
+ DBG_ASSERT( pSVData->maWinData.mpDefDialogParent != this,
+ "Window::~Window(): Window is DefModalDialogParent" );
+
+ // Wegen alter kompatibilitaet
+ if ( pSVData->maWinData.mpTrackWin == this )
+ EndTracking();
+ if ( pSVData->maWinData.mpCaptureWin == this )
+ ReleaseMouse();
+ if ( pSVData->maWinData.mpDefDialogParent == this )
+ pSVData->maWinData.mpDefDialogParent = NULL;
+
+#ifdef DBG_UTIL
+ if ( DbgIsAssert() )
+ {
+ ByteString aErrorStr;
+ BOOL bError = FALSE;
+ Window* pTempWin = mpFrameData->mpFirstOverlap;
+ while ( pTempWin )
+ {
+ if ( ImplIsRealParentPath( pTempWin ) )
+ {
+ bError = TRUE;
+ if ( aErrorStr.Len() )
+ aErrorStr += "; ";
+ aErrorStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
+ }
+ pTempWin = pTempWin->mpNextOverlap;
+ }
+ if ( bError )
+ {
+ ByteString aTempStr( "Window (" );
+ aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
+ aTempStr += ") with living SystemWindow(s) destroyed: ";
+ aTempStr += aErrorStr;
+ DBG_ERROR( aTempStr.GetBuffer() );
+ }
+
+ if ( mpFirstChild )
+ {
+ ByteString aTempStr( "Window (" );
+ aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
+ aTempStr += ") with living Child(s) destroyed: ";
+ Window* pTempWin = mpFirstChild;
+ while ( pTempWin )
+ {
+ aTempStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
+ pTempWin = pTempWin->mpNext;
+ if ( pTempWin )
+ aTempStr += "; ";
+ }
+ DBG_ERROR( aTempStr.GetBuffer() );
+ }
+
+ if ( mpFirstOverlap )
+ {
+ ByteString aTempStr( "Window (" );
+ aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
+ aTempStr += ") with living SystemWindow(s) destroyed: ";
+ Window* pTempWin = mpFirstOverlap;
+ while ( pTempWin )
+ {
+ aTempStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
+ pTempWin = pTempWin->mpNext;
+ if ( pTempWin )
+ aTempStr += "; ";
+ }
+ DBG_ERROR( aTempStr.GetBuffer() );
+ }
+ }
+#endif
+
+ // Fenster hiden, um das entsprechende Paint-Handling auszuloesen
+ Hide();
+
+ // Mitteilen, das Fenster zerstoert wird
+ {
+ NotifyEvent aNEvt( EVENT_DESTROY, this );
+ Notify( aNEvt );
+ }
+
+ // Wenn wir den Focus haben, dann den Focus auf ein anderes Fenster setzen
+ Window* pOverlapWindow = ImplGetFirstOverlapWindow();
+ if ( pSVData->maWinData.mpFocusWin == this )
+ {
+ if ( mbFrame )
+ {
+ pSVData->maWinData.mpFocusWin = NULL;
+ pOverlapWindow->mpLastFocusWindow = NULL;
+ GetpApp()->FocusChanged();
+ }
+ else
+ {
+ Window* pParent = GetParent();
+ Window* pBorderWindow = mpBorderWindow;
+ // Bei ueberlappenden Fenstern wird der Focus auf den
+ // Parent vom naechsten FrameWindow gesetzt
+ if ( pBorderWindow )
+ {
+ if ( pBorderWindow->ImplIsOverlapWindow() )
+ pParent = pBorderWindow->mpOverlapWindow;
+ }
+ else if ( ImplIsOverlapWindow() )
+ pParent = mpOverlapWindow;
+ if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() )
+ pParent->GrabFocus();
+ else
+ mpFrameWindow->GrabFocus();
+ // Falls der Focus wieder auf uns gesetzt wurde, dann wird er
+ // auf nichts gesetzt
+ if ( pSVData->maWinData.mpFocusWin == this )
+ {
+ pSVData->maWinData.mpFocusWin = NULL;
+ pOverlapWindow->mpLastFocusWindow = NULL;
+ GetpApp()->FocusChanged();
+ }
+ }
+ }
+ if ( pOverlapWindow->mpLastFocusWindow == this )
+ pOverlapWindow->mpLastFocusWindow = NULL;
+
+ // gemerkte Fenster zuruecksetzen
+ if ( mpFrameData->mpFocusWin == this )
+ mpFrameData->mpFocusWin = NULL;
+ if ( mpFrameData->mpMouseMoveWin == this )
+ mpFrameData->mpMouseMoveWin = NULL;
+ if ( mpFrameData->mpMouseDownWin == this )
+ mpFrameData->mpMouseDownWin = NULL;
+
+ // Deactivate-Window zuruecksetzen
+ if ( pSVData->maWinData.mpLastDeacWin == this )
+ pSVData->maWinData.mpLastDeacWin = NULL;
+
+#ifdef REMOTE_APPSERVER
+ {
+ // Events als ungueltig markieren...
+ VOS_NAMESPACE(OGuard,vos) aGuard( pSVData->mpWindowObjectMutex );
+ if ( mpRmEvents )
+ {
+ ExtRmEvent* p = mpRmEvents;
+ while ( p )
+ {
+ p->MarkInvalid();
+ p = p->GetNextWindowEvent();
+ }
+ }
+ }
+#endif
+
+ if ( mbFrame )
+ {
+#ifndef REMOTE_APPSERVER
+ DragManager::SystemEnableDrop( mpFrame, FALSE);
+#endif
+ if ( mpFrameData->mnFocusId )
+ Application::RemoveUserEvent( mpFrameData->mnFocusId );
+ if ( mpFrameData->mnMouseMoveId )
+ Application::RemoveUserEvent( mpFrameData->mnMouseMoveId );
+ }
+
+ // Graphic freigeben
+#ifndef REMOTE_APPSERVER
+ ImplReleaseGraphics();
+#else
+ ImplReleaseServerGraphics();
+#endif
+
+ // Evt. anderen Funktion mitteilen, das das Fenster geloescht
+ // wurde
+ ImplDelData* pDelData = mpFirstDel;
+ while ( pDelData )
+ {
+ pDelData->mbDel = TRUE;
+ pDelData = pDelData->mpNext;
+ }
+
+ // Fenster aus den Listen austragen
+ ImplRemoveWindow( TRUE );
+
+ // Extra Window Daten loeschen
+ if ( mpWinData )
+ {
+ if ( mpWinData->mpExtPosAry )
+ delete [] mpWinData->mpExtPosAry;
+ if ( mpWinData->mpFocusRect )
+ delete mpWinData->mpFocusRect;
+ if ( mpWinData->mpTrackRect )
+ delete mpWinData->mpTrackRect;
+ delete mpWinData;
+ }
+
+ // Overlap-Window-Daten loeschen
+ if ( mpOverlapData )
+ {
+ delete mpOverlapData;
+ }
+
+ // Evt. noch BorderWindow oder Frame zerstoeren
+ if ( mpBorderWindow )
+ delete mpBorderWindow;
+ else if ( mbFrame )
+ {
+ if ( pSVData->maWinData.mpFirstFrame == this )
+ pSVData->maWinData.mpFirstFrame = mpFrameData->mpNextFrame;
+ else
+ {
+ Window* pSysWin = pSVData->maWinData.mpFirstFrame;
+ while ( pSysWin->mpFrameData->mpNextFrame != this )
+ pSysWin = pSysWin->mpFrameData->mpNextFrame;
+ pSysWin->mpFrameData->mpNextFrame = mpFrameData->mpNextFrame;
+ }
+#ifndef REMOTE_APPSERVER
+ mpFrame->SetCallback( NULL, NULL );
+ pSVData->mpDefInst->DestroyFrame( mpFrame );
+#else
+ mpGraphics->SetInterface( REF( NMSP_CLIENT::XRmOutputDevice )() );
+ delete mpFrame;
+#endif
+ if ( mpFrameData->mpDragTimer )
+ delete mpFrameData->mpDragTimer;
+ delete mpFrameData;
+#ifdef REMOTE_APPSERVER
+ delete mpGraphics;
+#endif
+ }
+
+ if ( mpChildClipRegion )
+ delete mpChildClipRegion;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::MouseMove( const MouseEvent& rMEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ NotifyEvent aNEvt( EVENT_MOUSEMOVE, this, &rMEvt );
+ if ( !Notify( aNEvt ) )
+ mbMouseMove = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ NotifyEvent aNEvt( EVENT_MOUSEBUTTONDOWN, this, &rMEvt );
+ if ( !Notify( aNEvt ) )
+ mbMouseButtonDown = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ NotifyEvent aNEvt( EVENT_MOUSEBUTTONUP, this, &rMEvt );
+ if ( !Notify( aNEvt ) )
+ mbMouseButtonUp = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::KeyInput( const KeyEvent& rKEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ NotifyEvent aNEvt( EVENT_KEYINPUT, this, &rKEvt );
+ if ( !Notify( aNEvt ) )
+ mbKeyInput = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::KeyUp( const KeyEvent& rKEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ NotifyEvent aNEvt( EVENT_KEYUP, this, &rKEvt );
+ if ( !Notify( aNEvt ) )
+ mbKeyUp = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Paint( const Rectangle& rRect )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ if ( mxWindowPeer.is() )
+ Application::GetUnoWrapper()->WindowEvent_Paint( this, rRect );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Draw( OutputDevice*, const Point&, const Size&, ULONG )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Move()
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ if ( mxWindowPeer.is() )
+ Application::GetUnoWrapper()->WindowEvent_Move( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Resize()
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ if ( mxWindowPeer.is() )
+ Application::GetUnoWrapper()->WindowEvent_Resize( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Activate()
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Deactivate()
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::GetFocus()
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ if ( HasFocus() && mpLastFocusWindow && !(mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
+ mpLastFocusWindow->GrabFocus();
+
+ NotifyEvent aNEvt( EVENT_GETFOCUS, this );
+ Notify( aNEvt );
+
+ if ( Application::GetAccessHdlCount() )
+ Application::AccessNotify( AccessNotification( ACCESS_EVENT_GETFOCUS, this ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::LoseFocus()
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ NotifyEvent aNEvt( EVENT_LOSEFOCUS, this );
+ Notify( aNEvt );
+
+ if ( Application::GetAccessHdlCount() )
+ Application::AccessNotify( AccessNotification( ACCESS_EVENT_LOSEFOCUS, this ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::RequestHelp( const HelpEvent& rHEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ // Wenn Balloon-Help angefordert wird, dann den Balloon mit dem
+ // gesetzten Hilfetext anzeigen
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ {
+ const XubString* pStr = &(GetHelpText());
+ if ( !pStr->Len() )
+ pStr = &(GetQuickHelpText());
+ if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() )
+ ImplGetParent()->RequestHelp( rHEvt );
+ else
+ Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), *pStr );
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_QUICK )
+ {
+ const XubString* pStr = &(GetQuickHelpText());
+ if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() )
+ ImplGetParent()->RequestHelp( rHEvt );
+ else
+ {
+ Point aPos = GetPosPixel();
+ if ( ImplGetParent() && !ImplIsOverlapWindow() )
+ aPos = ImplGetParent()->OutputToScreenPixel( aPos );
+ Rectangle aRect( aPos, GetSizePixel() );
+ String aHelpText;
+ if ( pStr->Len() )
+ aHelpText = GetHelpText();
+ Help::ShowQuickHelp( this, aRect, *pStr, aHelpText, QUICKHELP_CTRLTEXT );
+ }
+ }
+ else
+ {
+ ULONG nStartHelpId = GetHelpId();
+
+ if ( !nStartHelpId && ImplGetParent() )
+ ImplGetParent()->RequestHelp( rHEvt );
+ else
+ {
+ if ( !nStartHelpId )
+ nStartHelpId = HELP_INDEX;
+
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nStartHelpId );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Command( const CommandEvent& rCEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ if ( mxWindowPeer.is() )
+ Application::GetUnoWrapper()->WindowEvent_Command( this, rCEvt );
+
+ NotifyEvent aNEvt( EVENT_COMMAND, this, &rCEvt );
+ if ( !Notify( aNEvt ) )
+ mbCommand = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Tracking( const TrackingEvent& )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::QueryDrop( DropEvent& rDEvt )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ NotifyEvent aNEvt( EVENT_QUERYDROP, this, &rDEvt, FALSE );
+ Notify( aNEvt );
+ return (BOOL)aNEvt.GetReturnValue();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::Drop( const DropEvent& rDEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ NotifyEvent aNEvt( EVENT_DROP, this, &rDEvt, FALSE );
+ Notify( aNEvt );
+ return (BOOL)aNEvt.GetReturnValue();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::UserEvent( ULONG, void* )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::StateChanged( StateChangedType )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::DataChanged( const DataChangedEvent& )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+}
+
+// -----------------------------------------------------------------------
+
+long Window::PreNotify( NotifyEvent& rNEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ BOOL bDone = FALSE;
+ if ( mpParent && !ImplIsOverlapWindow() )
+ bDone = mpParent->PreNotify( rNEvt );
+
+ if ( !bDone )
+ {
+ if( rNEvt.GetType() == EVENT_GETFOCUS )
+ {
+ BOOL bCompoundFocusChanged = FALSE;
+ if ( mbCompoundControl && !mbCompoundControlHasFocus && HasChildPathFocus() )
+ {
+ mbCompoundControlHasFocus = TRUE;
+ bCompoundFocusChanged = TRUE;
+ }
+
+ if ( mxWindowPeer.is() && ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) ) )
+ Application::GetUnoWrapper()->WindowEvent_GetFocus( this );
+ }
+ else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ BOOL bCompoundFocusChanged = FALSE;
+ if ( mbCompoundControl && mbCompoundControlHasFocus && !HasChildPathFocus() )
+ {
+ mbCompoundControlHasFocus = FALSE ;
+ bCompoundFocusChanged = TRUE;
+ }
+
+ if ( mxWindowPeer.is() && ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) ) )
+ Application::GetUnoWrapper()->WindowEvent_LoseFocus( this );
+ }
+ else if( rNEvt.GetType() == EVENT_MOUSEMOVE )
+ {
+ if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) )
+ {
+ if ( rNEvt.GetWindow() == this )
+ Application::GetUnoWrapper()->WindowEvent_MouseMove( this, *rNEvt.GetMouseEvent() );
+ else
+ Application::GetUnoWrapper()->WindowEvent_MouseMove( this, ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
+ }
+ }
+ else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP )
+ {
+ if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) )
+ {
+ if ( rNEvt.GetWindow() == this )
+ Application::GetUnoWrapper()->WindowEvent_MouseButtonUp( this, *rNEvt.GetMouseEvent() );
+ else
+ Application::GetUnoWrapper()->WindowEvent_MouseButtonUp( this, ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
+ }
+ }
+ else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) )
+ {
+ if ( rNEvt.GetWindow() == this )
+ Application::GetUnoWrapper()->WindowEvent_MouseButtonDown( this, *rNEvt.GetMouseEvent() );
+ else
+ Application::GetUnoWrapper()->WindowEvent_MouseButtonDown( this, ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
+ }
+ }
+ else if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) )
+ Application::GetUnoWrapper()->WindowEvent_KeyInput( this, *rNEvt.GetKeyEvent() );
+ }
+ else if( rNEvt.GetType() == EVENT_KEYUP )
+ {
+ if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) )
+ Application::GetUnoWrapper()->WindowEvent_KeyUp( this, *rNEvt.GetKeyEvent() );
+ }
+ }
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+long Window::Notify( NotifyEvent& rNEvt )
+{
+ { // Klammerung, da in diesem Handler das Window zerstoert werden darf
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ }
+
+ long nRet = FALSE;
+
+ // Dialog-Steuerung
+ if ( (GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL )
+ {
+ // Wenn Parent auch DialogSteuerung aktiviert hat, uebernimmt dieser die Steuerung
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) || (rNEvt.GetType() == EVENT_KEYUP) )
+ {
+ if ( ImplIsOverlapWindow() ||
+ ((ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
+ {
+ nRet = ImplDlgCtrl( *rNEvt.GetKeyEvent(), rNEvt.GetType() == EVENT_KEYINPUT );
+ }
+ }
+ else if ( (rNEvt.GetType() == EVENT_GETFOCUS) || (rNEvt.GetType() == EVENT_LOSEFOCUS) )
+ {
+ ImplDlgCtrlFocusChanged( rNEvt.GetWindow(), rNEvt.GetType() == EVENT_GETFOCUS );
+ if ( (rNEvt.GetWindow() == this) && (rNEvt.GetType() == EVENT_GETFOCUS) &&
+ !(GetStyle() & WB_TABSTOP) && !(mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
+ {
+ USHORT n = 0;
+ Window* pFirstChild = ImplGetDlgWindow( n, DLGWINDOW_FIRST );
+ if ( pFirstChild )
+ pFirstChild->ImplControlFocus();
+ }
+ }
+ }
+
+ if ( !nRet )
+ {
+ if ( mpParent && !ImplIsOverlapWindow() )
+ nRet = mpParent->Notify( rNEvt );
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Window::PostUserEvent( ULONG nEvent, void* pEventData )
+{
+ ULONG nEventId;
+ PostUserEvent( nEventId, nEvent, pEventData );
+ return nEventId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Window::PostUserEvent( const Link& rLink, void* pCaller )
+{
+ ULONG nEventId;
+ PostUserEvent( nEventId, rLink, pCaller );
+ return nEventId;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::PostUserEvent( ULONG& rEventId, ULONG nEvent, void* pEventData )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplSVEvent* pSVEvent = new ImplSVEvent;
+ pSVEvent->mnEvent = nEvent;
+ pSVEvent->mpData = pEventData;
+ pSVEvent->mpLink = NULL;
+ pSVEvent->mpWindow = this;
+ pSVEvent->mbCall = TRUE;
+ ImplAddDel( &(pSVEvent->maDelData) );
+ rEventId = (ULONG)pSVEvent;
+#ifndef REMOTE_APPSERVER
+ if ( mpFrame->PostEvent( pSVEvent ) )
+ return TRUE;
+ else
+ {
+ rEventId = 0;
+ ImplRemoveDel( &(pSVEvent->maDelData) );
+ delete pSVEvent;
+ return FALSE;
+ }
+#else
+ ExtRmEvent* pEvt = new ExtRmEvent( RMEVENT_USEREVENT, NULL, pSVEvent );
+ ImplPostEvent( pEvt );
+ return TRUE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::PostUserEvent( ULONG& rEventId, const Link& rLink, void* pCaller )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplSVEvent* pSVEvent = new ImplSVEvent;
+ pSVEvent->mnEvent = 0;
+ pSVEvent->mpData = pCaller;
+ pSVEvent->mpLink = new Link( rLink );
+ pSVEvent->mpWindow = this;
+ pSVEvent->mbCall = TRUE;
+ ImplAddDel( &(pSVEvent->maDelData) );
+ rEventId = (ULONG)pSVEvent;
+#ifndef REMOTE_APPSERVER
+ if ( mpFrame->PostEvent( pSVEvent ) )
+ return TRUE;
+ else
+ {
+ rEventId = 0;
+ ImplRemoveDel( &(pSVEvent->maDelData) );
+ delete pSVEvent;
+ return FALSE;
+ }
+#else
+ ExtRmEvent* pEvt = new ExtRmEvent( RMEVENT_USEREVENT, NULL, pSVEvent );
+ ImplPostEvent( pEvt );
+ return TRUE;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Window::RemoveUserEvent( ULONG nUserEvent )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplSVEvent* pSVEvent = (ImplSVEvent*)nUserEvent;
+
+ DBG_ASSERT( pSVEvent->mpWindow == this,
+ "Window::RemoveUserEvent(): Event doesn't send to this window or is already removed" );
+ DBG_ASSERT( pSVEvent->mbCall,
+ "Window::RemoveUserEvent(): Event is already removed" );
+
+ if ( pSVEvent->mpWindow )
+ {
+ pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
+ pSVEvent->mpWindow = NULL;
+ }
+
+ pSVEvent->mbCall = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Window, ImplAsyncStateChangedHdl, void*, pState )
+{
+ StateChanged( (StateChangedType)(ULONG)pState );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::PostStateChanged( StateChangedType nState )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ PostUserEvent( LINK( this, Window, ImplAsyncStateChangedHdl ), (void*)(ULONG)nState );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetStyle( WinBits nStyle )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mnStyle != nStyle )
+ {
+ mnPrevStyle = mnStyle;
+ mnStyle = nStyle;
+ StateChanged( STATE_CHANGE_STYLE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetExtendedStyle( WinBits nExtendedStyle )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mnExtendedStyle != nExtendedStyle )
+ {
+ mnPrevExtendedStyle = mnExtendedStyle;
+ mnExtendedStyle = nExtendedStyle;
+ StateChanged( STATE_CHANGE_EXTENDEDSTYLE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SystemWindow* Window::GetSystemWindow() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ const Window* pWin = this;
+ while ( !pWin->IsSystemWindow() )
+ pWin = pWin->GetParent();
+ return (SystemWindow*)pWin;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetBorderStyle( USHORT nBorderStyle )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ {
+ if ( mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
+ ((ImplBorderWindow*)mpBorderWindow)->SetBorderStyle( nBorderStyle );
+ else
+ mpBorderWindow->SetBorderStyle( nBorderStyle );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Window::GetBorderStyle() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ {
+ if ( mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
+ return ((ImplBorderWindow*)mpBorderWindow)->GetBorderStyle();
+ else
+ return mpBorderWindow->GetBorderStyle();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long Window::CalcTitleWidth() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ {
+ if ( mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
+ return ((ImplBorderWindow*)mpBorderWindow)->CalcTitleWidth();
+ else
+ return mpBorderWindow->CalcTitleWidth();
+ }
+ else if ( mbFrame && (mnStyle & WB_MOVEABLE) )
+ {
+ // Fuer Frame-Fenster raten wir die Breite, da wir den Border fuer
+ // externe Dialoge nicht kennen
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Font aFont = GetFont();
+ ((Window*)this)->SetPointFont( rStyleSettings.GetTitleFont() );
+ long nTitleWidth = GetTextWidth( GetText() );
+ ((Window*)this)->SetFont( aFont );
+ nTitleWidth += rStyleSettings.GetTitleHeight() * 3;
+ nTitleWidth += rStyleSettings.GetBorderSize() * 2;
+ nTitleWidth += 10;
+ return nTitleWidth;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::EnableClipSiblings( BOOL bClipSiblings )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ mpBorderWindow->EnableClipSiblings( bClipSiblings );
+
+ mbClipSiblings = bClipSiblings;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetMouseTransparent( BOOL bTransparent )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ mpBorderWindow->SetMouseTransparent( bTransparent );
+
+ mbMouseTransparent = bTransparent;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetPaintTransparent( BOOL bTransparent )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ mpBorderWindow->SetPaintTransparent( bTransparent );
+
+ mbPaintTransparent = bTransparent;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetInputContext( const InputContext& rInputContext )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ maInputContext = rInputContext;
+ if ( !mbInFocusHdl && HasFocus() )
+ ImplNewInputContext();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::UpdateExtTextInputArea()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+#ifndef REMOTE_APPSERVER
+ if ( mbExtTextInput )
+ ImplGetFrame()->UpdateExtTextInputArea();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Window::EndExtTextInput( USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+#ifndef REMOTE_APPSERVER
+ if ( mbExtTextInput )
+ ImplGetFrame()->EndExtTextInput( nFlags );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetExtTextInputPos( USHORT nStart, USHORT nCount, const Rectangle* pPosAry )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplWinData* pWinData = ImplGetWinData();
+
+ if ( pWinData->mpExtPosAry )
+ delete [] pWinData->mpExtPosAry;
+ if ( nCount )
+ {
+ pWinData->mpExtPosAry = new Rectangle[nCount];
+ pWinData->mnExtPosStart = nStart;
+ pWinData->mnExtPosCount = nCount;
+ memcpy( pWinData->mpExtPosAry, pPosAry, nCount*sizeof( Rectangle ) );
+ }
+ else
+ pWinData->mpExtPosAry = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+const Rectangle* Window::GetExtTextInputPosAry() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplWinData* pWinData = ImplGetWinData();
+ return pWinData->mpExtPosAry;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Window::GetExtTextInputPosStart() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplWinData* pWinData = ImplGetWinData();
+ return pWinData->mnExtPosStart;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Window::GetExtTextInputPosCount() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplWinData* pWinData = ImplGetWinData();
+ return pWinData->mnExtPosCount;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetSettings( const AllSettings& rSettings, BOOL bChild )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ {
+ mpBorderWindow->SetSettings( rSettings, FALSE );
+ if ( (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
+ ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow->SetSettings( rSettings, TRUE );
+ }
+
+ AllSettings aOldSettings = maSettings;
+ OutputDevice::SetSettings( rSettings );
+ ULONG nChangeFlags = aOldSettings.GetChangeFlags( rSettings );
+ if ( nChangeFlags )
+ {
+ DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
+ DataChanged( aDCEvt );
+ }
+
+ // AppFont-Aufloesung und DPI-Aufloesung neu berechnen
+ ImplInitResolutionSettings();
+
+ if ( bChild || mbChildNotify )
+ {
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->SetSettings( rSettings, bChild );
+ pChild = pChild->mpNext;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::UpdateSettings( const AllSettings& rSettings, BOOL bChild )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ {
+ mpBorderWindow->UpdateSettings( rSettings, FALSE );
+ if ( (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
+ ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow->UpdateSettings( rSettings, TRUE );
+ }
+
+ AllSettings aOldSettings = maSettings;
+ ULONG nChangeFlags = maSettings.Update( maSettings.GetWindowUpdate(), rSettings );
+ if ( nChangeFlags )
+ {
+ DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
+ DataChanged( aDCEvt );
+ }
+
+ // AppFont-Aufloesung und DPI-Aufloesung neu berechnen
+ ImplInitResolutionSettings();
+
+ if ( bChild || mbChildNotify )
+ {
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->UpdateSettings( rSettings, bChild );
+ pChild = pChild->mpNext;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::NotifyAllChilds( DataChangedEvent& rDCEvt )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ DataChanged( rDCEvt );
+
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->NotifyAllChilds( rDCEvt );
+ pChild = pChild->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetPointFont( const Font& rFont )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Font aFont = rFont;
+ ImplPointToLogic( aFont );
+ SetFont( aFont );
+}
+
+// -----------------------------------------------------------------------
+
+Font Window::GetPointFont() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Font aFont = GetFont();
+ ImplLogicToPoint( aFont );
+ return aFont;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::GetFontResolution( long& nDPIX, long& nDPIY ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ nDPIX = mpFrameData->mnFontDPIX;
+ nDPIY = mpFrameData->mnFontDPIY;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetParentClipMode( USHORT nMode )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ mpBorderWindow->SetParentClipMode( nMode );
+ else
+ {
+ if ( !ImplIsOverlapWindow() )
+ {
+ mnParentClipMode = nMode;
+ if ( nMode & PARENTCLIPMODE_CLIP )
+ mpParent->mbClipChildren = TRUE;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Window::GetParentClipMode() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ return mpBorderWindow->GetParentClipMode();
+ else
+ return mnParentClipMode;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetWindowRegionPixel()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ mpBorderWindow->SetWindowRegionPixel();
+ else
+ {
+ if ( mbWinRegion )
+ {
+ maWinRegion = Region( REGION_NULL );
+ mbWinRegion = FALSE;
+ ImplSetClipFlag();
+
+ if ( IsReallyVisible() )
+ {
+ // Hintergrund-Sicherung zuruecksetzen
+ if ( mpOverlapData && mpOverlapData->mpSaveBackDev )
+ ImplDeleteOverlapBackground();
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+ Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ Region aRegion( aRect );
+ ImplInvalidateParentFrameRegion( aRegion );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetWindowRegionPixel( const Region& rRegion )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ mpBorderWindow->SetWindowRegionPixel( rRegion );
+ else
+ {
+ BOOL bInvalidate = FALSE;
+
+ if ( rRegion.GetType() == REGION_NULL )
+ {
+ if ( mbWinRegion )
+ {
+ maWinRegion = Region( REGION_NULL );
+ mbWinRegion = FALSE;
+ ImplSetClipFlag();
+ bInvalidate = TRUE;
+ }
+ }
+ else
+ {
+ maWinRegion = rRegion;
+ mbWinRegion = TRUE;
+ ImplSetClipFlag();
+ bInvalidate = TRUE;
+ }
+
+ if ( IsReallyVisible() )
+ {
+ // Hintergrund-Sicherung zuruecksetzen
+ if ( mpOverlapData && mpOverlapData->mpSaveBackDev )
+ ImplDeleteOverlapBackground();
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+ Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ Region aRegion( aRect );
+ ImplInvalidateParentFrameRegion( aRegion );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+const Region& Window::GetWindowRegionPixel() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ return mpBorderWindow->GetWindowRegionPixel();
+ else
+ return maWinRegion;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::IsWindowRegionPixel() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ return mpBorderWindow->IsWindowRegionPixel();
+ else
+ return mbWinRegion;
+}
+
+// -----------------------------------------------------------------------
+
+Region Window::GetWindowClipRegionPixel( USHORT nFlags ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Region aWinClipRegion;
+
+ if ( nFlags & WINDOW_GETCLIPREGION_NOCHILDREN )
+ {
+ if ( mbInitWinClipRegion )
+ ((Window*)this)->ImplInitWinClipRegion();
+ aWinClipRegion = maWinClipRegion;
+ }
+ else
+ {
+ Region* pWinChildClipRegion = ((Window*)this)->ImplGetWinChildClipRegion();
+ aWinClipRegion = *pWinChildClipRegion;
+ }
+
+ if ( nFlags & WINDOW_GETCLIPREGION_NULL )
+ {
+ Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ Region aWinRegion( aWinRect );
+
+ if ( aWinRegion == aWinClipRegion )
+ aWinClipRegion.SetNull();
+ }
+
+ aWinClipRegion.Move( -mnOutOffX, -mnOutOffY );
+
+ return aWinClipRegion;
+}
+
+// -----------------------------------------------------------------------
+
+Region Window::GetPaintRegion() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpPaintRegion )
+ {
+ Region aRegion = *mpPaintRegion;
+ aRegion.Move( -mnOutOffX, -mnOutOffY );
+ return PixelToLogic( aRegion );
+ }
+ else
+ {
+ Region aPaintRegion( REGION_NULL );
+ return aPaintRegion;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetParent( Window* pNewParent )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ DBG_ASSERT( pNewParent, "Window::SetParent(): pParent == NULL" );
+
+ if ( mbFrame )
+ return;
+
+ if ( mpBorderWindow )
+ {
+ mpRealParent = pNewParent;
+ mpBorderWindow->SetParent( pNewParent );
+ return;
+ }
+
+ if ( mpParent == pNewParent )
+ return;
+
+ BOOL bVisible = IsVisible();
+ Show( FALSE, SHOW_NOFOCUSCHANGE );
+
+ // Testen, ob sich das Overlap-Window aendert
+ Window* pOldOverlapWindow;
+ Window* pNewOverlapWindow;
+ if ( ImplIsOverlapWindow() )
+ pOldOverlapWindow = NULL;
+ else
+ {
+ pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow();
+ if ( mpOverlapWindow != pNewOverlapWindow )
+ pOldOverlapWindow = mpOverlapWindow;
+ else
+ pOldOverlapWindow = NULL;
+ }
+
+ // Fenster in der Hirachie umsetzen
+ BOOL bFocusOverlapWin = HasChildPathFocus( TRUE );
+ BOOL bFocusWin = HasChildPathFocus();
+ BOOL bNewFrame = pNewParent->mpFrameWindow != mpFrameWindow;
+ if ( bNewFrame )
+ {
+ if ( mpFrameData->mpFocusWin )
+ {
+ if ( IsWindowOrChild( mpFrameData->mpFocusWin ) )
+ mpFrameData->mpFocusWin = NULL;
+ }
+ if ( mpFrameData->mpMouseMoveWin )
+ {
+ if ( IsWindowOrChild( mpFrameData->mpMouseMoveWin ) )
+ mpFrameData->mpMouseMoveWin = NULL;
+ }
+ if ( mpFrameData->mpMouseDownWin )
+ {
+ if ( IsWindowOrChild( mpFrameData->mpMouseDownWin ) )
+ mpFrameData->mpMouseDownWin = NULL;
+ }
+ }
+ ImplRemoveWindow( bNewFrame );
+ ImplInsertWindow( pNewParent );
+ if ( mnParentClipMode & PARENTCLIPMODE_CLIP )
+ pNewParent->mbClipChildren = TRUE;
+ ImplUpdateWindowPtr();
+#ifndef REMOTE_APPSERVER
+ if ( ImplUpdatePos() )
+ ImplUpdateSysObjPos();
+#else
+ ImplUpdatePos();
+#endif
+
+ // Wenn sich das Overlap-Window geaendert hat, dann muss getestet werden,
+ // ob auch OverlapWindow die das Child-Fenster als Parent gehabt haben
+ // in der Window-Hirachie umgesetzt werden muessen
+ if ( ImplIsOverlapWindow() )
+ {
+ if ( bNewFrame )
+ {
+ Window* pOverlapWindow = mpFirstOverlap;
+ while ( pOverlapWindow )
+ {
+ Window* pNextOverlapWindow = pOverlapWindow->mpNext;
+ pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
+ pOverlapWindow = pNextOverlapWindow;
+ }
+ }
+ }
+ else if ( pOldOverlapWindow )
+ {
+ // Focus-Save zuruecksetzen
+ if ( bFocusWin ||
+ (pOldOverlapWindow->mpLastFocusWindow &&
+ IsWindowOrChild( pOldOverlapWindow->mpLastFocusWindow )) )
+ pOldOverlapWindow->mpLastFocusWindow = NULL;
+
+ Window* pOverlapWindow = pOldOverlapWindow->mpFirstOverlap;
+ while ( pOverlapWindow )
+ {
+ Window* pNextOverlapWindow = pOverlapWindow->mpNext;
+ if ( ImplIsRealParentPath( pOverlapWindow->ImplGetWindow() ) )
+ pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
+ pOverlapWindow = pNextOverlapWindow;
+ }
+
+ // Activate-Status beim naechsten Overlap-Window updaten
+ if ( HasChildPathFocus( TRUE ) )
+ ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
+ }
+
+ // Activate-Status mit umsetzen
+ if ( bNewFrame )
+ {
+ if ( (GetType() == WINDOW_BORDERWINDOW) &&
+ (ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
+ ((ImplBorderWindow*)this)->SetDisplayActive( mpFrameData->mbHasFocus );
+ }
+
+ // Focus evtl. auf den neuen Frame umsetzen, wenn FocusWindow mit
+ // SetParent() umgesetzt wird
+ if ( bFocusOverlapWin )
+ {
+ mpFrameData->mpFocusWin = Application::GetFocusWindow();
+ if ( !mpFrameData->mbHasFocus )
+ {
+ mpFrame->ToTop( 0 );
+ }
+ }
+
+ if ( bVisible )
+ Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Show( BOOL bVisible, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mbVisible == bVisible )
+ return;
+
+ mbVisible = bVisible != 0;
+
+ if ( !bVisible )
+ {
+ ImplHideAllOverlaps();
+
+ if ( mpBorderWindow )
+ {
+ BOOL bOldUpdate = mpBorderWindow->mbNoParentUpdate;
+ if ( mbNoParentUpdate )
+ mpBorderWindow->mbNoParentUpdate = TRUE;
+ mpBorderWindow->Show( FALSE, nFlags );
+ mpBorderWindow->mbNoParentUpdate = bOldUpdate;
+ }
+ else if ( mbFrame )
+ mpFrame->Show( FALSE );
+
+ StateChanged( STATE_CHANGE_VISIBLE );
+
+ if ( mbReallyVisible )
+ {
+ Region aInvRegion( REGION_EMPTY );
+ BOOL bSaveBack = FALSE;
+
+ if ( ImplIsOverlapWindow() && !mbFrame )
+ {
+ if ( ImplRestoreOverlapBackground( aInvRegion ) )
+ bSaveBack = TRUE;
+ }
+
+ if ( !bSaveBack )
+ {
+ if ( mbInitWinClipRegion )
+ ImplInitWinClipRegion();
+ aInvRegion = maWinClipRegion;
+ }
+
+ ImplResetReallyVisible();
+ ImplSetClipFlag();
+
+ if ( ImplIsOverlapWindow() && !mbFrame )
+ {
+ // Focus umsetzen
+ if ( !(nFlags & SHOW_NOFOCUSCHANGE) && HasChildPathFocus() )
+ {
+ if ( mpOverlapWindow->IsEnabled() && mpOverlapWindow->IsInputEnabled() )
+ mpOverlapWindow->GrabFocus();
+ }
+ }
+
+ if ( !mbFrame )
+ {
+ if ( !mbNoParentUpdate && !(nFlags & SHOW_NOPARENTUPDATE) )
+ {
+ if ( !aInvRegion.IsEmpty() )
+ ImplInvalidateParentFrameRegion( aInvRegion );
+ }
+ ImplGenerateMouseMove();
+ }
+ }
+ }
+ else
+ {
+ if ( mbCallMove )
+ {
+ mbCallMove = FALSE;
+ Move();
+ }
+ if ( mbCallResize )
+ {
+ mbCallResize = FALSE;
+ Resize();
+ }
+
+ StateChanged( STATE_CHANGE_VISIBLE );
+
+ Window* pTestParent;
+ if ( ImplIsOverlapWindow() )
+ pTestParent = mpOverlapWindow;
+ else
+ pTestParent = ImplGetParent();
+ if ( mbFrame || pTestParent->mbReallyVisible )
+ {
+ // Wenn ein Window gerade sichtbar wird, schicken wir allen
+ // Child-Fenstern ein StateChanged, damit diese sich
+ // initialisieren koennen
+ ImplCallInitShow();
+
+ // Wenn es ein SystemWindow ist, dann kommt es auch automatisch
+ // nach vorne, wenn es gewuenscht ist
+ if ( ImplIsOverlapWindow() && !(nFlags & SHOW_NOACTIVATE) )
+ {
+ ImplStartToTop( 0 );
+ ImplFocusToTop( 0, FALSE );
+ }
+
+ // Hintergrund sichern
+ if ( mpOverlapData && mpOverlapData->mbSaveBack )
+ ImplSaveOverlapBackground();
+ // Dafuer sorgen, das Clip-Rechtecke neu berechnet werden
+ ImplSetReallyVisible();
+ ImplSetClipFlag();
+
+ if ( !mbFrame )
+ {
+ ImplInvalidate( NULL, INVALIDATE_NOTRANSPARENT | INVALIDATE_CHILDREN );
+ ImplGenerateMouseMove();
+ }
+ }
+
+ if ( mpBorderWindow )
+ mpBorderWindow->Show( TRUE, nFlags );
+ else if ( mbFrame )
+ {
+ mbPaintFrame = TRUE;
+ mpFrame->Show( TRUE );
+
+ // Query the correct size of the window, if we are waiting for
+ // a system resize
+ if ( mbWaitSystemResize )
+ {
+ long nOutWidth;
+ long nOutHeight;
+ mpFrame->GetClientSize( nOutWidth, nOutHeight );
+ ImplHandleResize( this, nOutWidth, nOutHeight );
+ }
+ }
+
+#ifdef DBG_UTIL
+ if ( IsDialog() || (GetType() == WINDOW_TABPAGE) )
+ {
+ DBG_DIALOGTEST( this );
+ }
+#endif
+
+ ImplShowAllOverlaps();
+ }
+
+ // Hintergrund-Sicherung zuruecksetzen
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+
+ if ( mxWindowPeer.is() )
+ Application::GetUnoWrapper()->WindowEvent_Show( this, mbVisible );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Enable( BOOL bEnable, BOOL bChild )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !bEnable )
+ {
+ // Wenn ein Fenster disablte wird, wird automatisch der Tracking-Modus
+ // beendet oder der Capture geklaut
+ if ( IsTracking() )
+ EndTracking( ENDTRACK_CANCEL );
+ if ( IsMouseCaptured() )
+ ReleaseMouse();
+ // Wenn Fenster den Focus hat und in der Dialog-Steuerung enthalten,
+ // wird versucht, den Focus auf das naechste Control weiterzuschalten
+ // mbDisabled darf erst nach Aufruf von ImplDlgCtrlNextWindow() gesetzt
+ // werden. Ansonsten muss ImplDlgCtrlNextWindow() umgestellt werden
+ if ( HasFocus() )
+ ImplDlgCtrlNextWindow();
+ }
+
+ if ( mpBorderWindow )
+ {
+ mpBorderWindow->Enable( bEnable, FALSE );
+ if ( (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
+ ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow->Enable( bEnable, TRUE );
+ }
+
+ if ( mbDisabled != !bEnable )
+ {
+ mbDisabled = !bEnable;
+#ifndef REMOTE_APPSERVER
+ if ( mpSysObj )
+ mpSysObj->Enable( bEnable && !mbInputDisabled );
+#endif
+// if ( mbFrame )
+// mpFrame->Enable( bEnable && !mbInputDisabled );
+ StateChanged( STATE_CHANGE_ENABLE );
+ }
+
+ if ( bChild || mbChildNotify )
+ {
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->Enable( bEnable, bChild );
+ pChild = pChild->mpNext;
+ }
+ }
+
+ if ( IsReallyVisible() )
+ ImplGenerateMouseMove();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::EnableInput( BOOL bEnable, BOOL bChild )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ {
+ mpBorderWindow->EnableInput( bEnable, FALSE );
+ if ( (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
+ ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow )
+ ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow->EnableInput( bEnable, TRUE );
+ }
+
+ if ( !mbAlwaysEnableInput || bEnable )
+ {
+ // Wenn ein Fenster disablte wird, wird automatisch der
+ // Tracking-Modus beendet oder der Capture geklaut
+ if ( !bEnable )
+ {
+ if ( IsTracking() )
+ EndTracking( ENDTRACK_CANCEL );
+ if ( IsMouseCaptured() )
+ ReleaseMouse();
+ }
+
+ if ( mbInputDisabled != !bEnable )
+ {
+ mbInputDisabled = !bEnable;
+#ifndef REMOTE_APPSERVER
+ if ( mpSysObj )
+ mpSysObj->Enable( !mbDisabled && bEnable );
+#endif
+// if ( mbFrame )
+// mpFrame->Enable( !mbDisabled && bEnable );
+ }
+ }
+
+ if ( bChild || mbChildNotify )
+ {
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->EnableInput( bEnable, bChild );
+ pChild = pChild->mpNext;
+ }
+ }
+
+ if ( IsReallyVisible() )
+ ImplGenerateMouseMove();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::EnableInput( BOOL bEnable, BOOL bChild, BOOL bSysWin,
+ const Window* pExcludeWindow )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ EnableInput( bEnable, bChild );
+ if ( bSysWin )
+ {
+ // pExculeWindow is the first Overlap-Frame --> if this
+ // shouldn't be the case, than this must be changed in dialog.cxx
+ pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow();
+ Window* pSysWin = mpFrameWindow->mpFrameData->mpFirstOverlap;
+ while ( pSysWin )
+ {
+ // Is Window in the path from this window
+ if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, TRUE ) )
+ {
+ // Is Window not in the exclude window path or not the
+ // exclude window, than change the status
+ if ( !pExcludeWindow->ImplIsWindowOrChild( pSysWin, TRUE ) )
+ pSysWin->EnableInput( bEnable, bChild );
+ }
+ pSysWin = pSysWin->mpNextOverlap;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::AlwaysEnableInput( BOOL bAlways, BOOL bChild )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ mpBorderWindow->AlwaysEnableInput( bAlways, FALSE );
+
+ if ( mbAlwaysEnableInput != bAlways )
+ {
+ mbAlwaysEnableInput = bAlways;
+
+ if ( bAlways )
+ EnableInput( TRUE, FALSE );
+ }
+
+ if ( bChild || mbChildNotify )
+ {
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ pChild->AlwaysEnableInput( bAlways, bChild );
+ pChild = pChild->mpNext;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetActivateMode( USHORT nMode )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ mpBorderWindow->SetActivateMode( nMode );
+
+ if ( mnActivateMode != nMode )
+ {
+ mnActivateMode = nMode;
+
+ // Evtl. ein Decativate/Activate ausloesen
+ if ( mnActivateMode )
+ {
+ if ( (mbActive || (GetType() == WINDOW_BORDERWINDOW)) &&
+ !HasChildPathFocus( TRUE ) )
+ {
+ mbActive = FALSE;
+ Deactivate();
+ }
+ }
+ else
+ {
+ if ( !mbActive || (GetType() == WINDOW_BORDERWINDOW) )
+ {
+ mbActive = TRUE;
+ Activate();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ToTop( USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplStartToTop( nFlags );
+ ImplFocusToTop( nFlags, IsReallyVisible() );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetZOrder( Window* pRefWindow, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ {
+ mpBorderWindow->SetZOrder( pRefWindow, nFlags );
+ return;
+ }
+
+ if ( nFlags & WINDOW_ZORDER_FIRST )
+ {
+ if ( ImplIsOverlapWindow() )
+ pRefWindow = mpOverlapWindow->mpFirstOverlap;
+ else
+ pRefWindow = mpParent->mpFirstChild;
+ nFlags |= WINDOW_ZORDER_BEFOR;
+ }
+ else if ( nFlags & WINDOW_ZORDER_LAST )
+ {
+ if ( ImplIsOverlapWindow() )
+ pRefWindow = mpOverlapWindow->mpLastOverlap;
+ else
+ pRefWindow = mpParent->mpLastChild;
+ nFlags |= WINDOW_ZORDER_BEHIND;
+ }
+
+ while ( pRefWindow->mpBorderWindow )
+ pRefWindow = pRefWindow->mpBorderWindow;
+ if ( (pRefWindow == this) || mbFrame )
+ return;
+
+ DBG_ASSERT( pRefWindow->mpParent == mpParent, "Window::SetZOrder() - pRefWindow has other parent" );
+ if ( nFlags & WINDOW_ZORDER_BEFOR )
+ {
+ if ( pRefWindow->mpPrev == this )
+ return;
+
+ if ( ImplIsOverlapWindow() )
+ {
+ if ( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ mpOverlapWindow->mpFirstOverlap = mpNext;
+ if ( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ mpOverlapWindow->mpLastOverlap = mpPrev;
+ if ( !pRefWindow->mpPrev )
+ mpOverlapWindow->mpFirstOverlap = this;
+ }
+ else
+ {
+ if ( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ mpParent->mpFirstChild = mpNext;
+ if ( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ mpParent->mpLastChild = mpPrev;
+ if ( !pRefWindow->mpPrev )
+ mpParent->mpFirstChild = this;
+ }
+
+ mpPrev = pRefWindow->mpPrev;
+ mpNext = pRefWindow;
+ if ( mpPrev )
+ mpPrev->mpNext = this;
+ mpNext->mpPrev = this;
+ }
+ else if ( nFlags & WINDOW_ZORDER_BEHIND )
+ {
+ if ( pRefWindow->mpNext == this )
+ return;
+
+ if ( ImplIsOverlapWindow() )
+ {
+ if ( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ mpOverlapWindow->mpFirstOverlap = mpNext;
+ if ( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ mpOverlapWindow->mpLastOverlap = mpPrev;
+ if ( !pRefWindow->mpNext )
+ mpOverlapWindow->mpLastOverlap = this;
+ }
+ else
+ {
+ if ( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ mpParent->mpFirstChild = mpNext;
+ if ( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ mpParent->mpLastChild = mpPrev;
+ if ( !pRefWindow->mpNext )
+ mpParent->mpLastChild = this;
+ }
+
+ mpPrev = pRefWindow;
+ mpNext = pRefWindow->mpNext;
+ if ( mpNext )
+ mpNext->mpPrev = this;
+ mpPrev->mpNext = this;
+ }
+
+ if ( IsReallyVisible() )
+ {
+ // Hintergrund-Sicherung zuruecksetzen
+ if ( mpFrameData->mpFirstBackWin )
+ ImplInvalidateAllOverlapBackgrounds();
+
+ if ( mbInitWinClipRegion || !maWinClipRegion.IsEmpty() )
+ {
+ BOOL bInitWinClipRegion = mbInitWinClipRegion;
+ ImplSetClipFlag();
+
+ // Wenn ClipRegion noch nicht initalisiert wurde, dann
+ // gehen wir davon aus, das das Fenster noch nicht
+ // ausgegeben wurde und loesen somit auch keine
+ // Invalidates aus. Dies ist eine Optimierung fuer
+ // HTML-Dokumenten mit vielen Controls. Wenn es mal
+ // Probleme mit dieser Abfrage gibt, sollte man ein
+ // Flag einfuehren, ob das Fenster nach Show schon
+ // einmal ausgegeben wurde.
+ if ( !bInitWinClipRegion )
+ {
+ // Alle nebeneinanderliegen Fenster invalidieren
+ // Noch nicht komplett implementiert !!!
+ Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
+ Window* pWindow = NULL;
+ if ( ImplIsOverlapWindow() )
+ {
+ if ( mpOverlapWindow )
+ pWindow = mpOverlapWindow->mpFirstOverlap;
+ }
+ else
+ pWindow = ImplGetParent()->mpFirstChild;
+ // Alle Fenster, die vor uns liegen und von uns verdeckt wurden,
+ // invalidieren
+ while ( pWindow )
+ {
+ if ( pWindow == this )
+ break;
+ Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
+ Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
+ if ( aWinRect.IsOver( aCompRect ) )
+ pWindow->Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
+ pWindow = pWindow->mpNext;
+ }
+ // Wenn uns ein Fenster welches im Hinterund liegt verdeckt hat,
+ // dann muessen wir uns neu ausgeben
+ while ( pWindow )
+ {
+ if ( pWindow != this )
+ {
+ Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
+ Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
+ if ( aWinRect.IsOver( aCompRect ) )
+ {
+ Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
+ break;
+ }
+ }
+ pWindow = pWindow->mpNext;
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::EnableAlwaysOnTop( BOOL bEnable )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ mbAlwaysOnTop = bEnable;
+
+ if ( mpBorderWindow )
+ mpBorderWindow->EnableAlwaysOnTop( bEnable );
+ else if ( bEnable && IsReallyVisible() )
+ ToTop();
+
+ if ( mbFrame )
+ mpFrame->SetAlwaysOnTop( bEnable );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetPosSizePixel( long nX, long nY,
+ long nWidth, long nHeight, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( nFlags & WINDOW_POSSIZE_POS )
+ mbDefPos = FALSE;
+ if ( nFlags & WINDOW_POSSIZE_SIZE )
+ mbDefSize = FALSE;
+
+ // Oberstes BorderWindow ist das Window, welches positioniert werden soll
+ Window* pWindow = this;
+ while ( pWindow->mpBorderWindow )
+ pWindow = pWindow->mpBorderWindow;
+
+ if ( pWindow->mbFrame )
+ {
+ // Nur Groessenaenderungen werden beruecksichtig
+ if ( (nFlags & WINDOW_POSSIZE_SIZE) == WINDOW_POSSIZE_SIZE )
+ {
+ if ( !(nFlags & WINDOW_POSSIZE_WIDTH) )
+ nWidth = pWindow->mnOutWidth;
+ if ( !(nFlags & WINDOW_POSSIZE_HEIGHT) )
+ nHeight = pWindow->mnOutHeight;
+
+ pWindow->mpFrame->SetClientSize( nWidth, nHeight );
+ // Resize should be called directly. If we havn't
+ // set the correct size, we get a second resize from
+ // the system with the correct size. This can be happend
+ // if the size is to small or to lare.
+ ImplHandleResize( pWindow, nWidth, nHeight );
+ }
+ }
+ else
+ {
+ pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
+ if ( IsReallyVisible() )
+ ImplGenerateMouseMove();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Point Window::OutputToScreenPixel( const Point& rPos ) const
+{
+ return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
+}
+
+// -----------------------------------------------------------------------
+
+Point Window::ScreenToOutputPixel( const Point& rPos ) const
+{
+ return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Scroll( long nHorzScroll, long nVertScroll, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplScroll( Rectangle( Point( mnOutOffX, mnOutOffY ),
+ Size( mnOutWidth, mnOutHeight ) ),
+ nHorzScroll, nVertScroll, nFlags & ~SCROLL_CLIP );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Scroll( long nHorzScroll, long nVertScroll,
+ const Rectangle& rRect, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Rectangle aRect = ImplLogicToDevicePixel( rRect );
+ aRect.Intersection( Rectangle( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ) );
+ if ( !aRect.IsEmpty() )
+ ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Invalidate( USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
+ return;
+
+ ImplInvalidate( NULL, nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Invalidate( const Rectangle& rRect, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
+ return;
+
+ Rectangle aRect = ImplLogicToDevicePixel( rRect );
+ if ( !aRect.IsEmpty() )
+ {
+ Region aRegion( aRect );
+ ImplInvalidate( &aRegion, nFlags );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Invalidate( const Region& rRegion, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
+ return;
+
+ if ( rRegion.IsNull() )
+ ImplInvalidate( NULL, nFlags );
+ else
+ {
+ Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
+ if ( !aRegion.IsEmpty() )
+ ImplInvalidate( &aRegion, nFlags );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Validate( USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
+ return;
+
+ ImplValidate( NULL, nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Validate( const Rectangle& rRect, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
+ return;
+
+ Rectangle aRect = ImplLogicToDevicePixel( rRect );
+ if ( !aRect.IsEmpty() )
+ {
+ Region aRegion( aRect );
+ ImplValidate( &aRegion, nFlags );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Validate( const Region& rRegion, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
+ return;
+
+ if ( rRegion.IsNull() )
+ ImplValidate( NULL, nFlags );
+ else
+ {
+ Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
+ if ( !aRegion.IsEmpty() )
+ ImplValidate( &aRegion, nFlags );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::HasPaintEvent() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !mbReallyVisible )
+ return FALSE;
+
+ if ( mpFrameWindow->mbPaintFrame )
+ return TRUE;
+
+ if ( mnPaintFlags & IMPL_PAINT_PAINT )
+ return TRUE;
+
+ if ( !ImplIsOverlapWindow() )
+ {
+ const Window* pTempWindow = this;
+ do
+ {
+ pTempWindow = pTempWindow->ImplGetParent();
+ if ( pTempWindow->mnPaintFlags & (IMPL_PAINT_PAINTCHILDS | IMPL_PAINT_PAINTALLCHILDS) )
+ return TRUE;
+ }
+ while ( !pTempWindow->ImplIsOverlapWindow() );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Update()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpBorderWindow )
+ {
+ mpBorderWindow->Update();
+ return;
+ }
+
+ if ( !mbReallyVisible )
+ return;
+
+ BOOL bFlush = FALSE;
+ if ( mpFrameWindow->mbPaintFrame )
+ {
+ Point aPoint( 0, 0 );
+ Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
+ ImplInvalidateOverlapFrameRegion( aRegion );
+ if ( mbFrame || (mpBorderWindow && mpBorderWindow->mbFrame) )
+ bFlush = TRUE;
+ }
+
+ // Zuerst muessen wir alle Fenster ueberspringen, die Paint-Transparent
+ // sind
+ Window* pUpdateWindow = this;
+ Window* pWindow = pUpdateWindow;
+ while ( !pWindow->ImplIsOverlapWindow() )
+ {
+ if ( !pWindow->mbPaintTransparent )
+ {
+ pUpdateWindow = pWindow;
+ break;
+ }
+ pWindow = pWindow->ImplGetParent();
+ }
+ // Ein Update wirkt immer auf das Window, wo PAINTALLCHILDS gesetzt
+ // ist, damit nicht zuviel gemalt wird
+ pWindow = pUpdateWindow;
+ do
+ {
+ if ( pWindow->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
+ pUpdateWindow = pWindow;
+ if ( pWindow->ImplIsOverlapWindow() )
+ break;
+ pWindow = pWindow->ImplGetParent();
+ }
+ while ( pWindow );
+
+ // Wenn es etwas zu malen gibt, dann ein Paint ausloesen
+ if ( pUpdateWindow->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
+ {
+ // und fuer alle ueber uns stehende System-Fenster auch ein Update
+ // ausloesen, damit nicht die ganze Zeit luecken stehen bleiben
+ Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpFirstOverlap;
+ while ( pUpdateOverlapWindow )
+ {
+ pUpdateOverlapWindow->Update();
+ pUpdateOverlapWindow = pUpdateOverlapWindow->mpNext;
+ }
+
+ pUpdateWindow->ImplCallPaint( NULL, pUpdateWindow->mnPaintFlags );
+ }
+
+ if ( bFlush )
+ Flush();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Flush()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+#ifdef REMOTE_APPSERVER
+ // !!!!!
+#else
+ mpFrame->Flush();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Sync()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+#ifdef REMOTE_APPSERVER
+ // Wir rufen eine syncrone Funktion, um uns zu syncronisieren
+ long nDummy;
+ mpFrame->GetClientSize( nDummy, nDummy );
+#else
+ mpFrame->Sync();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetUpdateMode( BOOL bUpdate )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ mbNoUpdate = !bUpdate;
+ StateChanged( STATE_CHANGE_UPDATEMODE );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::GrabFocus()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplGrabFocus( 0 );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::HasFocus() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ return (this == ImplGetSVData()->maWinData.mpFocusWin);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::HasChildPathFocus( BOOL bSystemWindow ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Window* pWindow = ImplGetSVData()->maWinData.mpFocusWin;
+ if ( pWindow )
+ return ImplIsWindowOrChild( pWindow, bSystemWindow );
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::CaptureMouse()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Tracking evt. beenden
+ if ( pSVData->maWinData.mpTrackWin != this )
+ {
+ if ( pSVData->maWinData.mpTrackWin )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
+ }
+
+ if ( pSVData->maWinData.mpCaptureWin != this )
+ {
+ pSVData->maWinData.mpCaptureWin = this;
+ mpFrame->CaptureMouse( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ReleaseMouse()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ DBG_ASSERTWARNING( pSVData->maWinData.mpCaptureWin == this,
+ "Window::ReleaseMouse(): window doesn't have the mouse capture" );
+
+ if ( pSVData->maWinData.mpCaptureWin == this )
+ {
+ pSVData->maWinData.mpCaptureWin = NULL;
+ mpFrame->CaptureMouse( FALSE );
+ ImplGenerateMouseMove();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::IsMouseCaptured() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ return (this == ImplGetSVData()->maWinData.mpCaptureWin);
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetPointer( const Pointer& rPointer )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( maPointer == rPointer )
+ return;
+
+ maPointer = rPointer;
+
+ // Pointer evt. direkt umsetzen
+ if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
+ mpFrame->SetPointer( ImplGetMousePointer() );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::EnableChildPointerOverwrite( BOOL bOverwrite )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mbChildPtrOverwrite == bOverwrite )
+ return;
+
+ mbChildPtrOverwrite = bOverwrite;
+
+ // Pointer evt. direkt umsetzen
+ if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
+ mpFrame->SetPointer( ImplGetMousePointer() );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetPointerPosPixel( const Point& rPos )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Point aPos = ImplOutputToFrame( rPos );
+ mpFrame->SetPointerPos( aPos.X(), aPos.Y() );
+}
+
+// -----------------------------------------------------------------------
+
+Point Window::GetPointerPosPixel()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ return ImplFrameToOutput( Point( mpFrameData->mnLastMouseX, mpFrameData->mnLastMouseY ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ShowPointer( BOOL bVisible )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mbNoPtrVisible != !bVisible )
+ {
+ mbNoPtrVisible = !bVisible;
+
+ // Pointer evt. direkt umsetzen
+ if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
+ mpFrame->SetPointer( ImplGetMousePointer() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::EnterWait()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ mnWaitCount++;
+
+ if ( mnWaitCount == 1 )
+ {
+ // Pointer evt. direkt umsetzen
+ if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
+ mpFrame->SetPointer( ImplGetMousePointer() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::LeaveWait()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mnWaitCount )
+ {
+ mnWaitCount--;
+
+ if ( !mnWaitCount )
+ {
+ // Pointer evt. direkt umsetzen
+ if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
+ mpFrame->SetPointer( ImplGetMousePointer() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetCursor( Cursor* pCursor )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpCursor != pCursor )
+ {
+ if ( mpCursor )
+ mpCursor->ImplHide();
+ mpCursor = pCursor;
+ if ( pCursor )
+ pCursor->ImplShow();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetText( const XubString& rStr )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ maText = rStr;
+
+ if ( mpBorderWindow )
+ mpBorderWindow->SetText( rStr );
+ else if ( mbFrame )
+ mpFrame->SetTitle( rStr );
+
+ StateChanged( STATE_CHANGE_TEXT );
+}
+
+// -----------------------------------------------------------------------
+
+XubString Window::GetText() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ return maText;
+}
+
+// -----------------------------------------------------------------------
+
+const XubString& Window::GetHelpText() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !maHelpText.Len() && mnHelpId )
+ {
+ if ( !IsDialog() && (mnType != WINDOW_TABPAGE) && (mnType != WINDOW_FLOATINGWINDOW) )
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ ((Window*)this)->maHelpText = pHelp->GetHelpText( GetHelpId() );
+ }
+ }
+
+ return maHelpText;
+}
+
+// -----------------------------------------------------------------------
+
+Window* Window::FindWindow( const Point& rPos ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Point aPos = OutputToScreenPixel( rPos );
+ return ((Window*)this)->ImplFindWindow( aPos );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Window::GetChildCount() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ USHORT nChildCount = 0;
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ nChildCount++;
+ pChild = pChild->mpNext;
+ }
+
+ return nChildCount;
+}
+
+// -----------------------------------------------------------------------
+
+Window* Window::GetChild( USHORT nChild ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ USHORT nChildCount = 0;
+ Window* pChild = mpFirstChild;
+ while ( pChild )
+ {
+ if ( nChild == nChildCount )
+ return pChild;
+ pChild = pChild->mpNext;
+ nChildCount++;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+Window* Window::GetWindow( USHORT nType ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ switch ( nType )
+ {
+ case WINDOW_PARENT:
+ return mpRealParent;
+
+ case WINDOW_FIRSTCHILD:
+ return mpFirstChild;
+
+ case WINDOW_LASTCHILD:
+ return mpLastChild;
+
+ case WINDOW_PREV:
+ return mpPrev;
+
+ case WINDOW_NEXT:
+ return mpNext;
+
+ case WINDOW_FIRSTOVERLAP:
+ return mpFirstOverlap;
+
+ case WINDOW_LASTOVERLAP:
+ return mpLastOverlap;
+
+ case WINDOW_OVERLAP:
+ if ( ImplIsOverlapWindow() )
+ return (Window*)this;
+ else
+ return mpOverlapWindow;
+
+ case WINDOW_PARENTOVERLAP:
+ if ( ImplIsOverlapWindow() )
+ return mpOverlapWindow;
+ else
+ return mpOverlapWindow->mpOverlapWindow;
+
+ case WINDOW_CLIENT:
+ return ((Window*)this)->ImplGetWindow();
+
+ case WINDOW_REALPARENT:
+ return ImplGetParent();
+
+ case WINDOW_FRAME:
+ return mpFrameWindow;
+
+ case WINDOW_BORDER:
+ if ( mpBorderWindow )
+ return mpBorderWindow->GetWindow( WINDOW_BORDER );
+ return (Window*)this;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::IsChild( const Window* pWindow, BOOL bSystemWindow ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow );
+
+ do
+ {
+ if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
+ break;
+
+ pWindow = pWindow->ImplGetParent();
+
+ if ( pWindow == this )
+ return TRUE;
+ }
+ while ( pWindow );
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::IsWindowOrChild( const Window* pWindow, BOOL bSystemWindow ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow );
+
+ if ( this == pWindow )
+ return TRUE;
+ return ImplIsChild( pWindow, bSystemWindow );
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* Window::GetSystemData() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+#ifndef REMOTE_APPSERVER
+ return mpFrame->GetSystemData();
+#else
+ return NULL;
+#endif
+}
+
+::com::sun::star::uno::Any Window::GetSystemDataAny() const
+{
+ ::com::sun::star::uno::Any aRet;
+ const SystemEnvData* pSysData = GetSystemData();
+ if( pSysData )
+ {
+ ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)pSysData, pSysData->nSize );
+ aRet <<= aSeq;
+ }
+ return aRet;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetWindowPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer, VCLXWindow* pVCLXWindow )
+{
+ mxWindowPeer = xPeer;
+ mpVCLXWindow = pVCLXWindow;
+}
+
+// -----------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > Window::GetComponentInterface( BOOL bCreate )
+{
+ if ( !mxWindowPeer.is() && bCreate )
+ {
+ UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
+ if ( pWrapper )
+ mxWindowPeer = pWrapper->GetWindowInterface( this, sal_True );
+ }
+ return mxWindowPeer;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetComponentInterface( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xIFace )
+{
+ UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
+ DBG_ASSERT( pWrapper, "SetComponentInterface: No Wrapper!" );
+ if ( pWrapper )
+ pWrapper->SetWindowInterface( this, xIFace );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCallDeactivateListeners( Window *pNew )
+{
+ // Ich werde nicht deaktiviert, wenn das neu aktivierte Window ein Child von mir ist
+ if ( !pNew || !ImplIsChild( pNew ) )
+ {
+ if ( mxWindowPeer.is() )
+ Application::GetUnoWrapper()->WindowEvent_Activate( this, FALSE );
+ if ( ImplGetParent() )
+ ImplGetParent()->ImplCallDeactivateListeners( pNew );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplCallActivateListeners( Window *pOld )
+{
+ // Ich werde nicht aktiviert, wenn das alte aktive Fenster ein Child von mir ist
+ if ( !pOld || !ImplIsChild( pOld ) )
+ {
+ if ( mxWindowPeer.is() )
+ // Hier muss noch irgendwie pOld mitgeschickt werden!
+ Application::GetUnoWrapper()->WindowEvent_Activate( this, TRUE );
+ if ( ImplGetParent() )
+ ImplGetParent()->ImplCallActivateListeners( pOld );
+ }
+}
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx
new file mode 100644
index 000000000000..6fc297a1cfa0
--- /dev/null
+++ b/vcl/source/window/window2.cxx
@@ -0,0 +1,1384 @@
+/*************************************************************************
+ *
+ * $RCSfile: window2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_WINDOW_CXX
+
+#include <limits.h>
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#else
+#include <rmoutdev.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_METRIC_HXX
+#include <metric.hxx>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+#ifndef _SV_OUTDEV_H
+#include <outdev.h>
+#endif
+#ifndef _SV_ACCESS_HXX
+#include <access.hxx>
+#endif
+#ifndef _SV_POLY_H
+#include <poly.h>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <virdev.hxx>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_WINDOW_HXX
+#include <window.hxx>
+#endif
+#ifndef _SV_SCRBAR_HXX
+#include <scrbar.hxx>
+#endif
+#ifndef _SV_SCRWND_HXX
+#include <scrwnd.hxx>
+#endif
+
+#pragma hdrstop
+
+// =======================================================================
+
+DBG_NAMEEX( Window );
+
+// =======================================================================
+
+#define IMPL_MAXSAVEBACKSIZE (640*480)
+#define IMPL_MAXALLSAVEBACKSIZE (800*600*2)
+
+// =======================================================================
+
+struct ImplFocusDelData : public ImplDelData
+{
+ Window* mpFocusWin;
+};
+
+// =======================================================================
+
+BOOL Window::ImplIsWindowInFront( const Window* pTestWindow ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+ DBG_CHKOBJ( pTestWindow, Window, ImplDbgCheckWindow );
+
+ // Testen, ob es Fenster untereinander liegen
+ pTestWindow = pTestWindow->ImplGetFirstOverlapWindow();
+ const Window* pTempWindow = pTestWindow;
+ const Window* pThisWindow = ImplGetFirstOverlapWindow();
+ if ( pTempWindow == pThisWindow )
+ return FALSE;
+ do
+ {
+ if ( pTempWindow == pThisWindow )
+ return TRUE;
+ if ( pTempWindow->mbFrame )
+ break;
+ pTempWindow = pTempWindow->mpOverlapWindow;
+ }
+ while ( pTempWindow );
+ pTempWindow = pThisWindow;
+ do
+ {
+ if ( pTempWindow == pTestWindow )
+ return FALSE;
+ if ( pTempWindow->mbFrame )
+ break;
+ pTempWindow = pTempWindow->mpOverlapWindow;
+ }
+ while ( pTempWindow );
+
+ // Fenster auf gleiche Ebene bringen
+ if ( pThisWindow->mpOverlapWindow != pTestWindow->mpOverlapWindow )
+ {
+ USHORT nThisLevel = 0;
+ USHORT nTestLevel = 0;
+ pTempWindow = pThisWindow;
+ do
+ {
+ nThisLevel++;
+ pTempWindow = pTempWindow->mpOverlapWindow;
+ }
+ while ( !pTempWindow->mbFrame );
+ pTempWindow = pTestWindow;
+ do
+ {
+ nTestLevel++;
+ pTempWindow = pTempWindow->mpOverlapWindow;
+ }
+ while ( !pTempWindow->mbFrame );
+
+ if ( nThisLevel < nTestLevel )
+ {
+ do
+ {
+ if ( pTestWindow->mpOverlapWindow == pThisWindow->mpOverlapWindow )
+ break;
+ if ( pTestWindow->mbFrame )
+ break;
+ pTestWindow = pTestWindow->mpOverlapWindow;
+ }
+ while ( pTestWindow );
+ }
+ else
+ {
+ do
+ {
+ if ( pThisWindow->mpOverlapWindow == pTempWindow->mpOverlapWindow )
+ break;
+ if ( pThisWindow->mbFrame )
+ break;
+ pThisWindow = pThisWindow->mpOverlapWindow;
+ }
+ while ( pThisWindow );
+ }
+ }
+
+ // Wenn TestWindow vor ThisWindow kommt, liegt es vorne
+ pTempWindow = pTestWindow;
+ do
+ {
+ if ( pTempWindow == pThisWindow )
+ return TRUE;
+ pTempWindow = pTempWindow->mpNext;
+ }
+ while ( pTempWindow );
+
+ return FALSE;
+}
+
+// =======================================================================
+
+void Window::ImplSaveOverlapBackground()
+{
+ DBG_ASSERT( !mpOverlapData->mpSaveBackDev, "Window::ImplSaveOverlapBackground() - Background already saved" );
+
+ if ( !mbFrame )
+ {
+ ULONG nSaveBackSize = mnOutWidth*mnOutHeight;
+ if ( nSaveBackSize <= IMPL_MAXSAVEBACKSIZE )
+ {
+ if ( nSaveBackSize+mpFrameData->mnAllSaveBackSize <= IMPL_MAXALLSAVEBACKSIZE )
+ {
+ Size aOutSize( mnOutWidth, mnOutHeight );
+ mpOverlapData->mpSaveBackDev = new VirtualDevice( *mpFrameWindow );
+ if ( mpOverlapData->mpSaveBackDev->SetOutputSizePixel( aOutSize ) )
+ {
+ mpFrameWindow->ImplUpdateAll();
+
+ if ( mbInitWinClipRegion )
+ ImplInitWinClipRegion();
+
+ mpOverlapData->mnSaveBackSize = nSaveBackSize;
+ mpFrameData->mnAllSaveBackSize += nSaveBackSize;
+ Point aDevPt;
+ mpFrameWindow->ImplGetFrameDev( Point( mnOutOffX, mnOutOffY ),
+ aDevPt, aOutSize,
+ *(mpOverlapData->mpSaveBackDev) );
+ mpOverlapData->mpNextBackWin = mpFrameData->mpFirstBackWin;
+ mpFrameData->mpFirstBackWin = this;
+ }
+ else
+ {
+ delete mpOverlapData->mpSaveBackDev;
+ mpOverlapData->mpSaveBackDev = NULL;
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::ImplRestoreOverlapBackground( Region& rInvRegion )
+{
+ if ( mpOverlapData->mpSaveBackDev )
+ {
+ if ( mbInitWinClipRegion )
+ ImplInitWinClipRegion();
+
+ if ( mpOverlapData->mpSaveBackDev )
+ {
+ Point aDevPt;
+ Point aDestPt( mnOutOffX, mnOutOffY );
+ Size aDevSize = mpOverlapData->mpSaveBackDev->GetOutputSizePixel();
+ if ( mpOverlapData->mpSaveBackRgn )
+ {
+ mpOverlapData->mpSaveBackRgn->Intersect( maWinClipRegion );
+ rInvRegion = maWinClipRegion;
+ rInvRegion.Exclude( *mpOverlapData->mpSaveBackRgn );
+ mpFrameWindow->ImplDrawFrameDev( aDestPt, aDevPt, aDevSize,
+ *(mpOverlapData->mpSaveBackDev),
+ *mpOverlapData->mpSaveBackRgn );
+ }
+ else
+ {
+ mpFrameWindow->ImplDrawFrameDev( aDestPt, aDevPt, aDevSize,
+ *(mpOverlapData->mpSaveBackDev),
+ maWinClipRegion );
+ }
+ ImplDeleteOverlapBackground();
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplDeleteOverlapBackground()
+{
+ if ( mpOverlapData->mpSaveBackDev )
+ {
+ mpFrameData->mnAllSaveBackSize -= mpOverlapData->mnSaveBackSize;
+ delete mpOverlapData->mpSaveBackDev;
+ mpOverlapData->mpSaveBackDev = NULL;
+ if ( mpOverlapData->mpSaveBackRgn )
+ {
+ delete mpOverlapData->mpSaveBackRgn;
+ mpOverlapData->mpSaveBackRgn = NULL;
+ }
+
+ // Fenster aus der Liste entfernen
+ if ( mpFrameData->mpFirstBackWin == this )
+ mpFrameData->mpFirstBackWin = mpOverlapData->mpNextBackWin;
+ else
+ {
+ Window* pTemp = mpFrameData->mpFirstBackWin;
+ while ( pTemp->mpOverlapData->mpNextBackWin != this )
+ pTemp = pTemp->mpOverlapData->mpNextBackWin;
+ pTemp->mpOverlapData->mpNextBackWin = mpOverlapData->mpNextBackWin;
+ }
+ mpOverlapData->mpNextBackWin = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplInvalidateAllOverlapBackgrounds()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Window* pWindow = mpFrameData->mpFirstBackWin;
+ while ( pWindow )
+ {
+ // Naechstes Fenster schon hier merken, da dieses Fenster in
+ // der if-Abfrage aus der Liste entfernt werden kann
+ Window* pNext = pWindow->mpOverlapData->mpNextBackWin;
+
+ if ( ImplIsWindowInFront( pWindow ) )
+ {
+ Rectangle aRect1( Point( mnOutOffX, mnOutOffY ),
+ Size( mnOutWidth, mnOutHeight ) );
+ Rectangle aRect2( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
+ Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
+ aRect1.Intersection( aRect2 );
+ if ( !aRect1.IsEmpty() )
+ {
+ if ( !pWindow->mpOverlapData->mpSaveBackRgn )
+ pWindow->mpOverlapData->mpSaveBackRgn = new Region( aRect2 );
+ pWindow->mpOverlapData->mpSaveBackRgn->Exclude( aRect1 );
+ if ( pWindow->mpOverlapData->mpSaveBackRgn->IsEmpty() )
+ pWindow->ImplDeleteOverlapBackground();
+ }
+
+ }
+
+ pWindow = pNext;
+ }
+}
+
+// =======================================================================
+
+Bitmap Window::SnapShot() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Bitmap aBmp;
+
+ if ( mpBorderWindow )
+ aBmp = mpBorderWindow->SnapShot();
+ else if ( IsReallyVisible() )
+ mpFrameWindow->ImplGetFrameBitmap( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ), aBmp );
+
+ return aBmp;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ShowFocus( const Rectangle& rRect )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplWinData* pWinData = ImplGetWinData();
+
+ if ( !mbInPaint )
+ {
+ if ( mbFocusVisible )
+ {
+ if ( *(pWinData->mpFocusRect) == rRect )
+ return;
+
+ ImplInvertFocus( *(pWinData->mpFocusRect) );
+ }
+
+ ImplInvertFocus( rRect );
+ }
+
+ if ( !pWinData->mpFocusRect )
+ pWinData->mpFocusRect = new Rectangle( rRect );
+ else
+ *(pWinData->mpFocusRect) = rRect;
+ mbFocusVisible = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::HideFocus()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !mbFocusVisible )
+ return;
+
+ if ( !mbInPaint )
+ ImplInvertFocus( *(ImplGetWinData()->mpFocusRect) );
+ mbFocusVisible = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Invert( const Rectangle& rRect, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+
+ if ( aRect.IsEmpty() )
+ return;
+ aRect.Justify();
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if ( mbOutputClipped )
+ return;
+
+ SalInvert nSalFlags = 0;
+ if ( nFlags & INVERT_HIGHLIGHT )
+ nSalFlags |= SAL_INVERT_HIGHLIGHT;
+ if ( nFlags & INVERT_50 )
+ nSalFlags |= SAL_INVERT_50;
+ mpGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), nSalFlags );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ pGraphics->Invert( aRect, nFlags );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Window::Invert( const Polygon& rPoly, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ USHORT nPoints = rPoly.GetSize();
+
+ if ( nPoints < 2 )
+ return;
+
+ Polygon aPoly( ImplLogicToDevicePixel( rPoly ) );
+
+#ifndef REMOTE_APPSERVER
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if ( mbOutputClipped )
+ return;
+
+ SalInvert nSalFlags = 0;
+ if ( nFlags & INVERT_HIGHLIGHT )
+ nSalFlags |= SAL_INVERT_HIGHLIGHT;
+ if ( nFlags & INVERT_50 )
+ nSalFlags |= SAL_INVERT_50;
+ const SalPoint* pPtAry = (const SalPoint*)aPoly.ImplGetConstPointAry();
+ mpGraphics->Invert( nPoints, pPtAry, nSalFlags );
+#else
+ ImplServerGraphics* pGraphics = ImplGetServerGraphics();
+ if ( pGraphics )
+ pGraphics->Invert( aPoly, nFlags );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ShowTracking( const Rectangle& rRect, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplWinData* pWinData = ImplGetWinData();
+
+ if ( !mbInPaint || !(nFlags & SHOWTRACK_WINDOW) )
+ {
+ if ( mbTrackVisible )
+ {
+ if ( (*(pWinData->mpTrackRect) == rRect) &&
+ (pWinData->mnTrackFlags == nFlags) )
+ return;
+
+ InvertTracking( *(pWinData->mpTrackRect), pWinData->mnTrackFlags );
+ }
+
+ InvertTracking( rRect, nFlags );
+ }
+
+ if ( !pWinData->mpTrackRect )
+ pWinData->mpTrackRect = new Rectangle( rRect );
+ else
+ *(pWinData->mpTrackRect) = rRect;
+ pWinData->mnTrackFlags = nFlags;
+ mbTrackVisible = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::HideTracking()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mbTrackVisible )
+ {
+ ImplWinData* pWinData = ImplGetWinData();
+ if ( !mbInPaint || !(pWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
+ InvertTracking( *(pWinData->mpTrackRect), pWinData->mnTrackFlags );
+ mbTrackVisible = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::InvertTracking( const Rectangle& rRect, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
+
+ if ( aRect.IsEmpty() )
+ return;
+ aRect.Justify();
+
+#ifndef REMOTE_APPSERVER
+ SalGraphics* pGraphics;
+
+ if ( nFlags & SHOWTRACK_WINDOW )
+ {
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if ( mbOutputClipped )
+ return;
+
+ pGraphics = mpGraphics;
+ }
+ else
+ {
+ pGraphics = ImplGetFrameGraphics();
+
+ if ( nFlags & SHOWTRACK_CLIP )
+ {
+ Point aPoint( mnOutOffX, mnOutOffY );
+ Region aRegion( Rectangle( aPoint,
+ Size( mnOutWidth, mnOutHeight ) ) );
+ ImplClipBoundaries( aRegion, FALSE, FALSE );
+ ImplSelectClipRegion( pGraphics, aRegion );
+ }
+ }
+
+ USHORT nStyle = nFlags & SHOWTRACK_STYLE;
+ if ( nStyle == SHOWTRACK_OBJECT )
+ pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SAL_INVERT_TRACKFRAME );
+ else if ( nStyle == SHOWTRACK_SPLIT )
+ pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SAL_INVERT_50 );
+ else
+ {
+ long nBorder = 1;
+ if ( nStyle == SHOWTRACK_BIG )
+ nBorder = 3;
+ pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), nBorder, SAL_INVERT_50 );
+ pGraphics->Invert( aRect.Left(), aRect.Bottom()-nBorder+1, aRect.GetWidth(), nBorder, SAL_INVERT_50 );
+ pGraphics->Invert( aRect.Left(), aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SAL_INVERT_50 );
+ pGraphics->Invert( aRect.Right()-nBorder+1, aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SAL_INVERT_50 );
+ }
+#else
+ ImplServerGraphics* pGraphics;
+ if ( nFlags & SHOWTRACK_WINDOW )
+ {
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ pGraphics = ImplGetServerGraphics();
+ }
+ else
+ {
+ pGraphics = ImplGetServerGraphics( TRUE );
+
+ if ( nFlags & SHOWTRACK_CLIP )
+ {
+ Point aTmpPoint( mnOutOffX, mnOutOffY );
+ Size aTmpSize( mnOutWidth, mnOutHeight );
+ Rectangle aTmpRect( aTmpPoint, aTmpSize );
+ Region aRegion( aTmpRect );
+ ImplClipBoundaries( aRegion, FALSE, FALSE );
+ pGraphics->SetClipRegion( aRegion );
+ }
+ }
+
+ if ( pGraphics )
+ pGraphics->InvertTracking( aRect, nFlags );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Window::InvertTracking( const Polygon& rPoly, USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ USHORT nPoints = rPoly.GetSize();
+
+ if ( nPoints < 2 )
+ return;
+
+ Polygon aPoly( ImplLogicToDevicePixel( rPoly ) );
+
+#ifndef REMOTE_APPSERVER
+ SalGraphics* pGraphics;
+
+ if ( nFlags & SHOWTRACK_WINDOW )
+ {
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return;
+ }
+
+ if ( mbInitClipRegion )
+ ImplInitClipRegion();
+
+ if ( mbOutputClipped )
+ return;
+
+ pGraphics = mpGraphics;
+ }
+ else
+ {
+ pGraphics = ImplGetFrameGraphics();
+
+ if ( nFlags & SHOWTRACK_CLIP )
+ {
+ Point aPoint( mnOutOffX, mnOutOffY );
+ Region aRegion( Rectangle( aPoint,
+ Size( mnOutWidth, mnOutHeight ) ) );
+ ImplClipBoundaries( aRegion, FALSE, FALSE );
+ ImplSelectClipRegion( pGraphics, aRegion );
+ }
+ }
+
+ const SalPoint* pPtAry = (const SalPoint*)aPoly.ImplGetConstPointAry();
+ pGraphics->Invert( nPoints, pPtAry, SAL_INVERT_TRACKFRAME );
+#else
+ ImplServerGraphics* pGraphics;
+ if ( nFlags & SHOWTRACK_WINDOW )
+ {
+ if ( !IsDeviceOutputNecessary() )
+ return;
+
+ pGraphics = ImplGetServerGraphics();
+ }
+ else
+ {
+ pGraphics = ImplGetServerGraphics( TRUE );
+
+ if ( nFlags & SHOWTRACK_CLIP )
+ {
+ Point aTmpPoint( mnOutOffX, mnOutOffY );
+ Size aTmpSize( mnOutWidth, mnOutHeight );
+ Rectangle aTmpRect( aTmpPoint, aTmpSize );
+ Region aRegion( aTmpRect );
+ ImplClipBoundaries( aRegion, FALSE, FALSE );
+ pGraphics->SetClipRegion( aRegion );
+ }
+ }
+
+ if ( pGraphics )
+ pGraphics->InvertTracking( aPoly, nFlags );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Window, ImplTrackTimerHdl, Timer*, pTimer )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Bei Button-Repeat muessen wir den Timeout umsetzen
+ if ( pSVData->maWinData.mnTrackFlags & STARTTRACK_BUTTONREPEAT )
+ pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
+
+ // Tracking-Event erzeugen
+ Point aMousePos( mpFrameData->mnLastMouseX, mpFrameData->mnLastMouseY );
+ MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
+ mpFrameData->mnClickCount, 0,
+ mpFrameData->mnMouseCode, mpFrameData->mnMouseCode );
+ TrackingEvent aTEvt( aMEvt, TRACKING_REPEAT );
+ Tracking( aTEvt );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::StartTracking( USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpTrackWin != this )
+ {
+ if ( pSVData->maWinData.mpTrackWin )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
+ }
+
+ if ( nFlags & (STARTTRACK_SCROLLREPEAT | STARTTRACK_BUTTONREPEAT) )
+ {
+ pSVData->maWinData.mpTrackTimer = new AutoTimer;
+
+ if ( nFlags & STARTTRACK_SCROLLREPEAT )
+ pSVData->maWinData.mpTrackTimer->SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
+ else
+ pSVData->maWinData.mpTrackTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() );
+ pSVData->maWinData.mpTrackTimer->SetTimeoutHdl( LINK( this, Window, ImplTrackTimerHdl ) );
+ pSVData->maWinData.mpTrackTimer->Start();
+ }
+
+ pSVData->maWinData.mpTrackWin = this;
+ pSVData->maWinData.mnTrackFlags = nFlags;
+ CaptureMouse();
+}
+
+// -----------------------------------------------------------------------
+
+void Window::EndTracking( USHORT nFlags )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpTrackWin == this )
+ {
+ // Hier wegen DbgChkThis geklammert, da Window im Handler zerstoert
+ // werden kann
+ {
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( pSVData->maWinData.mpTrackTimer )
+ {
+ delete pSVData->maWinData.mpTrackTimer;
+ pSVData->maWinData.mpTrackTimer = NULL;
+ }
+
+ pSVData->maWinData.mpTrackWin = NULL;
+ pSVData->maWinData.mnTrackFlags = 0;
+ ReleaseMouse();
+ }
+
+ // EndTracking rufen, wenn es gerufen werden soll
+ if ( !(nFlags & ENDTRACK_DONTCALLHDL) )
+ {
+ Point aMousePos( mpFrameData->mnLastMouseX, mpFrameData->mnLastMouseY );
+ MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
+ mpFrameData->mnClickCount, 0,
+ mpFrameData->mnMouseCode, mpFrameData->mnMouseCode );
+ TrackingEvent aTEvt( aMEvt, nFlags | ENDTRACK_END );
+ Tracking( aTEvt );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::IsTracking() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ return (ImplGetSVData()->maWinData.mpTrackWin == this);
+}
+
+// -----------------------------------------------------------------------
+
+void Window::StartAutoScroll( USHORT nFlags )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpAutoScrollWin != this )
+ {
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ }
+
+ pSVData->maWinData.mpAutoScrollWin = this;
+ pSVData->maWinData.mnAutoScrollFlags = nFlags;
+ pSVData->maAppData.mpWheelWindow = new ImplWheelWindow( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::EndAutoScroll()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpAutoScrollWin == this )
+ {
+ pSVData->maWinData.mpAutoScrollWin = NULL;
+ pSVData->maWinData.mnAutoScrollFlags = 0;
+ delete pSVData->maAppData.mpWheelWindow;
+ pSVData->maAppData.mpWheelWindow = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::IsAutoScroll() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ return (ImplGetSVData()->maWinData.mpAutoScrollWin == this);
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SaveBackground( const Point& rPos, const Size& rSize,
+ const Point& rDestOff, VirtualDevice& rSaveDevice )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpPaintRegion )
+ {
+ Region aClip( *mpPaintRegion );
+ const Point aPixPos( LogicToPixel( rPos ) );
+
+ aClip.Move( -mnOutOffX, -mnOutOffY );
+ aClip.Intersect( Rectangle( aPixPos, LogicToPixel( rSize ) ) );
+
+ if ( !aClip.IsEmpty() )
+ {
+ const Region aOldClip( rSaveDevice.GetClipRegion() );
+ const Point aPixOffset( rSaveDevice.LogicToPixel( rDestOff ) );
+ const Point aPixTopLeft( aClip.GetBoundRect().TopLeft() );
+ const BOOL bMap = rSaveDevice.IsMapModeEnabled();
+
+ // move clip region to have the same distance to DestOffset
+ aClip.Move( aPixOffset.X() - aPixPos.X(), aPixOffset.Y() - aPixPos.Y() );
+
+ // set pixel clip region
+ rSaveDevice.EnableMapMode( FALSE );
+ rSaveDevice.SetClipRegion( aClip );
+ rSaveDevice.EnableMapMode( bMap );
+ rSaveDevice.DrawOutDev( rDestOff, rSize, rPos, rSize, *this );
+ rSaveDevice.SetClipRegion( aOldClip );
+ }
+ }
+ else
+ rSaveDevice.DrawOutDev( rDestOff, rSize, rPos, rSize, *this );
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Window::SaveFocus()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maWinData.mpFocusWin )
+ {
+ ImplFocusDelData* pDelData = new ImplFocusDelData;
+ pSVData->maWinData.mpFocusWin->ImplAddDel( pDelData );
+ pDelData->mpFocusWin = pSVData->maWinData.mpFocusWin;
+ return (ULONG)(void*)pDelData;
+ }
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::EndSaveFocus( ULONG nSaveId, BOOL bRestore )
+{
+ if ( !nSaveId )
+ return FALSE;
+ else
+ {
+ BOOL bOK = TRUE;
+ ImplFocusDelData* pDelData = (ImplFocusDelData*)(void*)nSaveId;
+ if ( !pDelData->IsDelete() )
+ {
+ pDelData->mpFocusWin->ImplRemoveDel( pDelData );
+ if ( bRestore )
+ pDelData->mpFocusWin->GrabFocus();
+ }
+ else
+ bOK = !bRestore;
+ delete pDelData;
+ return bOK;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetZoom( const Fraction& rZoom )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( maZoom != rZoom )
+ {
+ maZoom = rZoom;
+ StateChanged( STATE_CHANGE_ZOOM );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline long WinFloatRound( double fVal )
+{
+ return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetZoomedPointFont( const Font& rFont )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ const Fraction& rZoom = GetZoom();
+ if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
+ {
+ Font aFont( rFont );
+ Size aSize = aFont.GetSize();
+ double n = (double)aSize.Width();
+ n *= (double)rZoom.GetNumerator();
+ n /= (double)rZoom.GetDenominator();
+ aSize.Width() = WinFloatRound( n );
+ n = (double)aSize.Height();
+ n *= (double)rZoom.GetNumerator();
+ n /= (double)rZoom.GetDenominator();
+ aSize.Height() = WinFloatRound( n );
+ aFont.SetSize( aSize );
+ SetPointFont( aFont );
+
+ // Wenn Darstellung skaliert wird, nehmen wir gegebenenfalls
+ // einen anderen Font, wenn der aktuelle nicht skalierbar ist
+ FontMetric aMetric = GetFontMetric();
+ long nFontDiff = Abs( GetFont().GetSize().Height()-aMetric.GetSize().Height() );
+ if ( (aMetric.GetType() == TYPE_RASTER) && (nFontDiff >= 2) )
+ {
+ ImplDevFontListData* pStdFont = NULL;
+ USHORT nStdFont = 0xFFFF;
+ if ( aMetric.GetPitch() == PITCH_FIXED )
+ nStdFont = PITCH_FIXED;
+ else if ( aMetric.GetFamily() == FAMILY_SWISS )
+ nStdFont = IMPL_STDFONT_SWISS;
+ else if ( aMetric.GetFamily() == FAMILY_ROMAN )
+ nStdFont = IMPL_STDFONT_ROMAN;
+ if ( nStdFont != 0xFFFF )
+ {
+ if ( mpFontList )
+ pStdFont = mpFontList->GetStandardFont( nStdFont );
+ if ( pStdFont && (aFont.GetName() != pStdFont->maName) )
+ {
+ aFont.SetName( pStdFont->maName );
+ SetPointFont( aFont );
+ }
+ }
+ }
+ }
+ else
+ SetPointFont( rFont );
+}
+
+// -----------------------------------------------------------------------
+
+long Window::CalcZoom( long nCalc ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ const Fraction& rZoom = GetZoom();
+ if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
+ {
+ double n = (double)nCalc;
+ n *= (double)rZoom.GetNumerator();
+ n /= (double)rZoom.GetDenominator();
+ nCalc = WinFloatRound( n );
+ }
+ return nCalc;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetControlFont()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpControlFont )
+ {
+ delete mpControlFont;
+ mpControlFont = NULL;
+ StateChanged( STATE_CHANGE_CONTROLFONT );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetControlFont( const Font& rFont )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( rFont == Font() )
+ {
+ SetControlFont();
+ return;
+ }
+
+ if ( mpControlFont )
+ {
+ if ( *mpControlFont == rFont )
+ return;
+ *mpControlFont = rFont;
+ }
+ else
+ mpControlFont = new Font( rFont );
+
+ StateChanged( STATE_CHANGE_CONTROLFONT );
+}
+
+// -----------------------------------------------------------------------
+
+Font Window::GetControlFont() const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mpControlFont )
+ return *mpControlFont;
+ else
+ {
+ Font aFont;
+ return aFont;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetControlForeground()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mbControlForeground )
+ {
+ maControlForeground = Color( COL_TRANSPARENT );
+ mbControlForeground = FALSE;
+ StateChanged( STATE_CHANGE_CONTROLFOREGROUND );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetControlForeground( const Color& rColor )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( rColor.GetTransparency() )
+ {
+ if ( mbControlForeground )
+ {
+ maControlForeground = Color( COL_TRANSPARENT );
+ mbControlForeground = FALSE;
+ StateChanged( STATE_CHANGE_CONTROLFOREGROUND );
+ }
+ }
+ else
+ {
+ if ( maControlForeground != rColor )
+ {
+ maControlForeground = rColor;
+ mbControlForeground = TRUE;
+ StateChanged( STATE_CHANGE_CONTROLFOREGROUND );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetControlBackground()
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( mbControlBackground )
+ {
+ maControlBackground = Color( COL_TRANSPARENT );
+ mbControlBackground = FALSE;
+ StateChanged( STATE_CHANGE_CONTROLBACKGROUND );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::SetControlBackground( const Color& rColor )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ if ( rColor.GetTransparency() )
+ {
+ if ( mbControlBackground )
+ {
+ maControlBackground = Color( COL_TRANSPARENT );
+ mbControlBackground = FALSE;
+ StateChanged( STATE_CHANGE_CONTROLBACKGROUND );
+ }
+ }
+ else
+ {
+ if ( maControlBackground != rColor )
+ {
+ maControlBackground = rColor;
+ mbControlBackground = TRUE;
+ StateChanged( STATE_CHANGE_CONTROLBACKGROUND );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size Window::CalcWindowSize( const Size& rOutSz ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Size aSz = rOutSz;
+ aSz.Width() += mnLeftBorder+mnRightBorder;
+ aSz.Height() += mnTopBorder+mnBottomBorder;
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+Size Window::CalcOutputSize( const Size& rWinSz ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Size aSz = rWinSz;
+ aSz.Width() -= mnLeftBorder+mnRightBorder;
+ aSz.Height() -= mnTopBorder+mnBottomBorder;
+ return aSz;
+}
+
+// -----------------------------------------------------------------------
+
+Font Window::GetDrawPixelFont( OutputDevice* pDev ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ Font aFont = GetPointFont();
+ Size aFontSize = aFont.GetSize();
+ MapMode aPtMapMode( MAP_POINT );
+ aFontSize = pDev->LogicToPixel( aFontSize, aPtMapMode );
+ aFont.SetSize( aFontSize );
+ return aFont;
+}
+
+// -----------------------------------------------------------------------
+
+long Window::GetDrawPixel( OutputDevice* pDev, long nPixels ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ long nP = nPixels;
+ if ( pDev->GetOutDevType() != OUTDEV_WINDOW )
+ {
+ MapMode aMap( MAP_100TH_MM );
+ Size aSz( nP, 0 );
+ aSz = PixelToLogic( aSz, aMap );
+ aSz = pDev->LogicToPixel( aSz, aMap );
+ nP = aSz.Width();
+ }
+ return nP;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Window::HandleScrollCommand( const CommandEvent& rCmd,
+ ScrollBar* pHScrl, ScrollBar* pVScrl )
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ BOOL bRet = FALSE;
+
+ if ( pHScrl || pVScrl )
+ {
+ switch( rCmd.GetCommand() )
+ {
+ case COMMAND_STARTAUTOSCROLL:
+ {
+ USHORT nFlags = 0;
+ if ( pHScrl )
+ {
+ if ( (pHScrl->GetVisibleSize() < pHScrl->GetRangeMax()) &&
+ pHScrl->IsEnabled() && pHScrl->IsInputEnabled() )
+ nFlags |= AUTOSCROLL_HORZ;
+ }
+ if ( pVScrl )
+ {
+ if ( (pVScrl->GetVisibleSize() < pVScrl->GetRangeMax()) &&
+ pVScrl->IsEnabled() && pVScrl->IsInputEnabled() )
+ nFlags |= AUTOSCROLL_VERT;
+ }
+
+ if ( nFlags )
+ {
+ StartAutoScroll( nFlags );
+ bRet = TRUE;
+ }
+ }
+ break;
+
+ case COMMAND_WHEEL:
+ {
+ const CommandWheelData* pData = rCmd.GetWheelData();
+
+ if ( pData && (COMMAND_WHEEL_SCROLL == pData->GetMode()) && !pData->IsHorz() )
+ {
+ ULONG nScrollLines = pData->GetScrollLines();
+ long nLines;
+ if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL )
+ {
+ if ( pData->GetDelta() < 0 )
+ nLines = -LONG_MAX;
+ else
+ nLines = LONG_MAX;
+ }
+ else
+ nLines = pData->GetNotchDelta() * (long)nScrollLines;
+ if ( nLines )
+ {
+ ImplHandleScroll( NULL, 0L, pVScrl, nLines );
+ bRet = TRUE;
+ }
+ }
+ }
+ break;
+
+ case COMMAND_AUTOSCROLL:
+ {
+ const CommandScrollData* pData = rCmd.GetAutoScrollData();
+ if ( pData && (pData->GetDeltaX() || pData->GetDeltaY()) )
+ {
+ ImplHandleScroll( pHScrl, pData->GetDeltaX(),
+ pVScrl, pData->GetDeltaY() );
+ bRet = TRUE;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void Window::ImplHandleScroll( ScrollBar* pHScrl, long nX,
+ ScrollBar* pVScrl, long nY )
+{
+ if ( pHScrl && nX && pHScrl->IsEnabled() && pHScrl->IsInputEnabled() )
+ {
+ long nNewPos = pHScrl->GetThumbPos();
+
+ if ( nX == -LONG_MAX )
+ nNewPos += pHScrl->GetPageSize();
+ else if ( nX == LONG_MAX )
+ nNewPos -= pHScrl->GetPageSize();
+ else
+ {
+ const double fVal = (double)nNewPos - ((double)nX * pHScrl->GetLineSize());
+
+ if ( fVal < LONG_MIN )
+ nNewPos = LONG_MIN;
+ else if ( fVal > LONG_MAX )
+ nNewPos = LONG_MAX;
+ else
+ nNewPos = (long)fVal;
+ }
+
+ pHScrl->DoScroll( nNewPos );
+ }
+
+ if ( pVScrl && nY && pVScrl->IsEnabled() && pVScrl->IsInputEnabled() )
+ {
+ long nNewPos = pVScrl->GetThumbPos();
+
+ if ( nY == -LONG_MAX )
+ nNewPos += pVScrl->GetPageSize();
+ else if ( nY == LONG_MAX )
+ nNewPos -= pVScrl->GetPageSize();
+ else
+ {
+ const double fVal = (double)nNewPos - ((double)nY * pVScrl->GetLineSize());
+
+ if ( fVal < LONG_MIN )
+ nNewPos = LONG_MIN;
+ else if ( fVal > LONG_MAX )
+ nNewPos = LONG_MAX;
+ else
+ nNewPos = (long)fVal;
+ }
+
+ pVScrl->DoScroll( nNewPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Window::GetAccessObject( AccessObjectRef& rAcc ) const
+{
+ DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+
+ rAcc = new AccessObject( (void*) this, ACCESS_TYPE_WND );
+}
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
new file mode 100644
index 000000000000..db3382df3f88
--- /dev/null
+++ b/vcl/source/window/winproc.cxx
@@ -0,0 +1,2151 @@
+/*************************************************************************
+ *
+ * $RCSfile: winproc.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_WINPROC_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALWTYPE_HXX
+#include <salwtype.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#else
+#include <rmwindow.hxx>
+#include <rmevents.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _INTN_HXX
+#include <tools/intn.hxx>
+#endif
+
+#define private public
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_DBGGUI_HXX
+#include <dbggui.hxx>
+#endif
+#ifndef _SV_WINDATA_HXX
+#include <windata.hxx>
+#endif
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SOUND_HXX
+#include <sound.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_CURSOR_HXX
+#include <cursor.hxx>
+#endif
+#ifndef _SV_ACCMGR_HXX
+#include <accmgr.hxx>
+#endif
+#ifndef _SV_PRINT_H
+#include <print.h>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_FLOATWIN_HXX
+#include <floatwin.hxx>
+#endif
+#ifndef _SV_DRAG_HXX
+#include <drag.hxx>
+#endif
+#ifndef _SV_GETSYS_HXX
+#include <getsys.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_HELPWIN_HXX
+#include <helpwin.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+#undef private
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define IMPL_MIN_NEEDSYSWIN 49
+
+// =======================================================================
+
+long ImplCallPreNotify( NotifyEvent& rEvt )
+{
+ long nRet = Application::CallEventHooks( rEvt );
+ if ( !nRet )
+ nRet = rEvt.GetWindow()->PreNotify( rEvt );
+ return nRet;
+}
+
+// =======================================================================
+
+long ImplCallEvent( NotifyEvent& rEvt )
+{
+ long nRet = ImplCallPreNotify( rEvt );
+ if ( !nRet )
+ {
+ Window* pWindow = rEvt.GetWindow();
+ switch ( rEvt.GetType() )
+ {
+ case EVENT_MOUSEBUTTONDOWN:
+ pWindow->MouseButtonDown( *rEvt.GetMouseEvent() );
+ break;
+ case EVENT_MOUSEBUTTONUP:
+ pWindow->MouseButtonUp( *rEvt.GetMouseEvent() );
+ break;
+ case EVENT_MOUSEMOVE:
+ pWindow->MouseMove( *rEvt.GetMouseEvent() );
+ break;
+ case EVENT_KEYINPUT:
+ pWindow->KeyInput( *rEvt.GetKeyEvent() );
+ break;
+ case EVENT_KEYUP:
+ pWindow->KeyUp( *rEvt.GetKeyEvent() );
+ break;
+ case EVENT_GETFOCUS:
+ pWindow->GetFocus();
+ break;
+ case EVENT_LOSEFOCUS:
+ pWindow->LoseFocus();
+ break;
+ case EVENT_COMMAND:
+ pWindow->Command( *rEvt.GetCommandEvent() );
+ break;
+ case EVENT_QUERYDROP:
+ nRet = pWindow->QueryDrop( *rEvt.GetDropEvent() );
+ break;
+ case EVENT_DROP:
+ nRet = pWindow->QueryDrop( *rEvt.GetDropEvent() );
+ break;
+ }
+ }
+
+ return nRet;
+}
+
+// =======================================================================
+
+class ImplDragTimer : public AutoTimer
+{
+ Window* mpWindow;
+
+public:
+ ImplDragTimer( Window* pWindow );
+
+ virtual void Timeout();
+};
+
+static BOOL mbImplDragTimeoutHdl = FALSE;
+
+// -----------------------------------------------------------------------
+
+ImplDragTimer::ImplDragTimer( Window* pWindow )
+{
+ mpWindow = pWindow;
+ SetTimeout( 45 );
+ Start();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDragTimer::Timeout()
+{
+ if ( DragManager::GetDragManager() )
+ {
+ mbImplDragTimeoutHdl = TRUE;
+ mpWindow->ImplCallMouseMove( mpWindow->mpFrameData->mnMouseCode );
+ mbImplDragTimeoutHdl = FALSE;
+ }
+ else
+ {
+ mpWindow->mpFrameData->mpDragTimer = NULL;
+ delete this;
+ }
+}
+
+// =======================================================================
+
+static BOOL ImplHandleMouseFloatMode( Window* pChild, const Point& rMousePos,
+ USHORT nCode, USHORT nSVEvent,
+ BOOL bMouseLeave )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
+ !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pChild ) )
+ {
+ USHORT nHitTest;
+ FloatingWindow* pFloat = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( rMousePos, nHitTest );
+ FloatingWindow* pLastLevelFloat;
+ ULONG nPopupFlags;
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( bMouseLeave )
+ return TRUE;
+
+ if ( !pFloat || (nHitTest & IMPL_FLOATWIN_HITTEST_RECT) )
+ {
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+ pChild->mpFrame->SetPointer( POINTER_ARROW );
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ( nCode & MOUSE_LEFT )
+ {
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( !pFloat )
+ {
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+// Erstmal ausgebaut als Hack fuer Bug 53378
+// if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
+// return FALSE;
+// else
+ return TRUE;
+ }
+ else if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
+ {
+ if ( !(pFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE) )
+ pFloat->ImplSetMouseDown();
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ( pFloat )
+ {
+ if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
+ {
+ if ( pFloat->ImplIsMouseDown() )
+ pFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
+ return TRUE;
+ }
+ }
+ else
+ {
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ if ( !(nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) )
+ {
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ return TRUE;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( !pFloat )
+ {
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
+ {
+ if ( (nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) &&
+ (nSVEvent == EVENT_MOUSEBUTTONDOWN) )
+ return TRUE;
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
+ return FALSE;
+ else
+ return TRUE;
+ }
+ else
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleMouseHelpRequest( Window* pChild, const Point& rMousePos )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( ( pChild != pSVData->maHelpData.mpHelpWin ) && !DragManager::GetDragManager() )
+ {
+ USHORT nHelpMode = 0;
+ if ( pSVData->maHelpData.mbQuickHelp )
+ nHelpMode = HELPMODE_QUICK;
+ if ( pSVData->maHelpData.mbBalloonHelp )
+ nHelpMode |= HELPMODE_BALLOON;
+ if ( nHelpMode )
+ {
+ if ( pChild->IsInputEnabled() )
+ {
+ HelpEvent aHelpEvent( rMousePos, nHelpMode );
+ pSVData->maHelpData.mbRequestingHelp = TRUE;
+ pChild->RequestHelp( aHelpEvent );
+ pSVData->maHelpData.mbRequestingHelp = FALSE;
+ }
+ else if ( pSVData->maHelpData.mpHelpWin )
+ {
+ ImplDestroyHelpWindow( FALSE );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSetMousePointer( Window* pChild )
+{
+ // Drag&Drop active?
+ DragManager* pDragManager = DragManager::GetDragManager();
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if( pDragManager && pDragManager->isModifyPointer() )
+ pChild->mpFrame->SetPointer( pDragManager->GetDragPointer().GetStyle() );
+ else if ( pSVData->maHelpData.mbExtHelpMode )
+ pChild->mpFrame->SetPointer( POINTER_HELP );
+ else
+ pChild->mpFrame->SetPointer( pChild->ImplGetMousePointer() );
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleMouseEvent( Window* pWindow, USHORT nSVEvent, BOOL bMouseLeave,
+ long nX, long nY, ULONG nMsgTime,
+ USHORT nCode, USHORT nMode )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Point aMousePos( nX, nY );
+ Window* pChild;
+ long nRet;
+ USHORT nClicks;
+ USHORT nOldCode = pWindow->mpFrameData->mnMouseCode;
+
+ // we need a mousemove event, befor we get a mousebuttondown or a
+ // mousebuttonup event
+ if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
+ (nSVEvent == EVENT_MOUSEBUTTONUP) )
+ {
+ if ( (nSVEvent == EVENT_MOUSEBUTTONUP) && pSVData->maHelpData.mbExtHelpMode )
+ Help::EndExtHelp();
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+
+ if ( (pWindow->mpFrameData->mnLastMouseX != nX) ||
+ (pWindow->mpFrameData->mnLastMouseY != nY) )
+ {
+ ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE, nX, nY, nMsgTime, nCode, nMode );
+ }
+ }
+
+ // update frame data
+ pWindow->mpFrameData->mnLastMouseX = nX;
+ pWindow->mpFrameData->mnLastMouseY = nY;
+ pWindow->mpFrameData->mnMouseCode = nCode;
+ pWindow->mpFrameData->mnMouseMode = nMode & ~(MOUSE_SYNTHETIC | MOUSE_MODIFIERCHANGED);
+ if ( bMouseLeave )
+ {
+ pWindow->mpFrameData->mbMouseIn = FALSE;
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+
+ // If Drag&Drop is active try to start System-Drag&Drop
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ {
+ if ( pWindow->mpFrameData->mpDragTimer )
+ {
+ delete pWindow->mpFrameData->mpDragTimer;
+ pWindow->mpFrameData->mpDragTimer = NULL;
+ }
+ pDragManager->AppWindowLeaved();
+ }
+ }
+ else
+ {
+ // Handle Drag&Drop if window is (re)entered
+ if ( !pWindow->mpFrameData->mbMouseIn )
+ {
+ // Drag&Drop active?
+ DragManager* pDragManager = DragManager::GetDragManager();
+
+ // HRO: Nur Escape rufen, wenn es unser eigenes Drag & Drop war
+ if ( pDragManager && pDragManager->bOwnDragDrop )
+ {
+ // break Drag&Drop, if mouse button is not pressed
+ if( !( nCode & MOUSE_LEFT ) )
+ pDragManager->Escape( pWindow );
+ }
+ }
+
+ pWindow->mpFrameData->mbMouseIn = TRUE;
+ }
+
+ DBG_ASSERT( !pSVData->maWinData.mpTrackWin ||
+ (pSVData->maWinData.mpTrackWin == pSVData->maWinData.mpCaptureWin),
+ "ImplHandleMouseEvent: TrackWin != CaptureWin" );
+
+ // AutoScrollMode
+ if ( pSVData->maWinData.mpAutoScrollWin && (nSVEvent == EVENT_MOUSEBUTTONDOWN) )
+ {
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ return 1;
+ }
+
+ // find mouse window
+ if ( pSVData->maWinData.mpCaptureWin )
+ {
+ pChild = pSVData->maWinData.mpCaptureWin;
+
+ DBG_ASSERT( !bMouseLeave || (pWindow != pChild->mpFrameWindow),
+ "ImplHandleMouseEvent: MouseLeave is send and Mouse is captured" );
+ DBG_ASSERT( pWindow == pChild->mpFrameWindow,
+ "ImplHandleMouseEvent: mouse event is not sent to capture window" );
+
+ if ( bMouseLeave )
+ return 0;
+ }
+ else
+ {
+ if ( bMouseLeave )
+ pChild = NULL;
+ else
+ pChild = pWindow->ImplFindWindow( aMousePos );
+ }
+
+ // test this because mouse events are buffered in the remote version
+ // and size may not be in sync
+ if ( !pChild && !bMouseLeave )
+ return 0;
+
+ // Ein paar Test ausfuehren und Message abfangen oder Status umsetzen
+ if ( pChild )
+ {
+ // no mouse messages to system object windows
+#ifndef REMOTE_APPSERVER
+ if ( pChild->mpSysObj )
+ return 0;
+#endif
+
+ // no mouse messages to disabled windows
+ if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() )
+ {
+ ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ ImplHandleMouseHelpRequest( pChild, aMousePos );
+
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ Sound::Beep( SOUND_DISABLE, pChild );
+ return 1;
+ }
+ else
+ {
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ ImplSetMousePointer( pChild );
+ return 0;
+ }
+ }
+
+ // ExtTextInput-Modus beenden, wenn in das Fenster geklickt wird
+ if ( pChild->IsExtTextInput() )
+ {
+ if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
+ (nSVEvent == EVENT_MOUSEBUTTONUP) )
+ pChild->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
+ }
+ }
+
+ // determine mouse event data
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ // Testen, ob MouseMove an das gleiche Fenster geht und sich der
+ // Status nicht geaendert hat
+ if ( pChild )
+ {
+ Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
+ if ( !bMouseLeave &&
+ (pChild == pWindow->mpFrameData->mpMouseMoveWin) &&
+ (aChildMousePos.X() == pWindow->mpFrameData->mnLastMouseWinX) &&
+ (aChildMousePos.Y() == pWindow->mpFrameData->mnLastMouseWinY) &&
+ (nOldCode == pWindow->mpFrameData->mnMouseCode) &&
+ !mbImplDragTimeoutHdl )
+ {
+ // Mouse-Pointer neu setzen, da er sich geaendet haben
+ // koennte, da ein Modus umgesetzt wurde
+ ImplSetMousePointer( pChild );
+ return 0;
+ }
+
+ pWindow->mpFrameData->mnLastMouseWinX = aChildMousePos.X();
+ pWindow->mpFrameData->mnLastMouseWinY = aChildMousePos.Y();
+ }
+
+ // mouse click
+ nClicks = pWindow->mpFrameData->mnClickCount;
+
+ // Gegebenenfalls den Start-Drag-Handler rufen.
+ // Achtung: Muss vor Move gerufen werden, da sonst bei schnellen
+ // Mausbewegungen die Applikationen in den Selektionszustand gehen.
+ Window* pMouseDownWin = pWindow->mpFrameData->mpMouseDownWin;
+ if ( pMouseDownWin )
+ {
+ // Testen, ob StartDrag-Modus uebereinstimmt. Wir vergleichen nur
+ // den Status der Maustasten, damit man mit Mod1 z.B. sofort
+ // in den Kopiermodus gehen kann.
+ const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
+ if ( (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
+ (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) )
+ {
+ if ( !pMouseDownWin->mpFrameData->mbStartDragCalled )
+ {
+ long nDragW = rMSettings.GetStartDragWidth();
+ long nDragH = rMSettings.GetStartDragWidth();
+ long nMouseX = nX;
+ long nMouseY = nY;
+ if ( !(((nMouseX-nDragW) <= pMouseDownWin->mpFrameData->mnFirstMouseX) &&
+ ((nMouseX+nDragW) >= pMouseDownWin->mpFrameData->mnFirstMouseX)) ||
+ !(((nMouseY-nDragH) <= pMouseDownWin->mpFrameData->mnFirstMouseY) &&
+ ((nMouseY+nDragH) >= pMouseDownWin->mpFrameData->mnFirstMouseY)) )
+ {
+ pMouseDownWin->mpFrameData->mbStartDragCalled = TRUE;
+ Point aCmdMousePos( pMouseDownWin->mpFrameData->mnFirstMouseX,
+ pMouseDownWin->mpFrameData->mnFirstMouseY );
+ aCmdMousePos = pMouseDownWin->ImplFrameToOutput( aCmdMousePos );
+ CommandEvent aCEvt( aCmdMousePos, COMMAND_STARTDRAG, TRUE );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pMouseDownWin, &aCEvt );
+ ImplDelData aDelData;
+ pMouseDownWin->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) )
+ pMouseDownWin->Command( aCEvt );
+ if ( aDelData.IsDelete() )
+ return 1;
+ pMouseDownWin->ImplRemoveDel( &aDelData );
+ }
+ }
+ }
+ else
+ pMouseDownWin->mpFrameData->mbStartDragCalled = TRUE;
+ }
+
+ // test for mouseleave and mouseenter
+ Window* pMouseMoveWin = pWindow->mpFrameData->mpMouseMoveWin;
+ if ( pChild != pMouseMoveWin )
+ {
+ if ( pMouseMoveWin )
+ {
+ Point aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
+ MouseEvent aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MOUSE_LEAVEWINDOW, nCode, nCode );
+ NotifyEvent aNLeaveEvt( EVENT_MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
+ ImplDelData aDelData;
+ ImplDelData aDelData2;
+ pWindow->mpFrameData->mbInMouseMove = TRUE;
+ pMouseMoveWin->ImplAddDel( &aDelData );
+ // Durch MouseLeave kann auch dieses Fenster zerstoert
+ // werden
+ if ( pChild )
+ pChild->ImplAddDel( &aDelData2 );
+ if ( !ImplCallPreNotify( aNLeaveEvt ) )
+ {
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ pDragManager->MouseMove( aMLeaveEvt, pMouseMoveWin );
+ else
+ pMouseMoveWin->MouseMove( aMLeaveEvt );
+ }
+
+ pWindow->mpFrameData->mpMouseMoveWin = NULL;
+ pWindow->mpFrameData->mbInMouseMove = FALSE;
+
+ if ( pChild )
+ {
+ if ( aDelData2.IsDelete() )
+ pChild = NULL;
+ else
+ pChild->ImplRemoveDel( &aDelData2 );
+ }
+ if ( aDelData.IsDelete() )
+ return 1;
+ pMouseMoveWin->ImplRemoveDel( &aDelData );
+ }
+
+ nMode |= MOUSE_ENTERWINDOW;
+ }
+ pWindow->mpFrameData->mpMouseMoveWin = pChild;
+
+ // MouseLeave
+ if ( !pChild )
+ return 0;
+ }
+ else
+ {
+ // mouse click
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
+ ULONG nDblClkTime = rMSettings.GetDoubleClickTime();
+ long nDblClkW = rMSettings.GetDoubleClickWidth();
+ long nDblClkH = rMSettings.GetDoubleClickHeight();
+ long nMouseX = nX;
+ long nMouseY = nY;
+
+ if ( (pChild == pChild->mpFrameData->mpMouseDownWin) &&
+ (nCode == pChild->mpFrameData->mnFirstMouseCode) &&
+ ((nMsgTime-pChild->mpFrameData->mnMouseDownTime) < nDblClkTime) &&
+ ((nMouseX-nDblClkW) <= pChild->mpFrameData->mnFirstMouseX) &&
+ ((nMouseX+nDblClkW) >= pChild->mpFrameData->mnFirstMouseX) &&
+ ((nMouseY-nDblClkH) <= pChild->mpFrameData->mnFirstMouseY) &&
+ ((nMouseY+nDblClkH) >= pChild->mpFrameData->mnFirstMouseY) )
+ {
+ pChild->mpFrameData->mnClickCount++;
+ pChild->mpFrameData->mbStartDragCalled = TRUE;
+ }
+ else
+ {
+ pChild->mpFrameData->mpMouseDownWin = pChild;
+ pChild->mpFrameData->mnClickCount = 1;
+ pChild->mpFrameData->mnFirstMouseX = nMouseX;
+ pChild->mpFrameData->mnFirstMouseY = nMouseY;
+ pChild->mpFrameData->mnFirstMouseCode = nCode;
+ pChild->mpFrameData->mbStartDragCalled = !((nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
+ (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)));
+ }
+ pChild->mpFrameData->mnMouseDownTime = nMsgTime;
+ }
+ nClicks = pChild->mpFrameData->mnClickCount;
+
+ pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
+ }
+
+ DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild == NULL" );
+
+ // create mouse event
+ Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
+ MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
+
+ // tracking window gets the mouse events
+ BOOL bTracking = FALSE;
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ pChild = pSVData->maWinData.mpTrackWin;
+ bTracking = TRUE;
+ }
+
+ // handle FloatingMode
+ if ( !pSVData->maWinData.mpTrackWin && pSVData->maWinData.mpFirstFloat )
+ {
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+ if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
+ {
+ if ( !aDelData.IsDelete() )
+ {
+ pChild->ImplRemoveDel( &aDelData );
+ pChild->mpFrameData->mbStartDragCalled = TRUE;
+ }
+ return 1;
+ }
+ else
+ pChild->ImplRemoveDel( &aDelData );
+ }
+
+ // call handler
+ BOOL bDrag = FALSE;
+ BOOL bCallHelpRequest = TRUE;
+ DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild is NULL" );
+
+ ImplDelData aDelData;
+ NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
+ pChild->ImplAddDel( &aDelData );
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ pChild->mpFrameData->mbInMouseMove = TRUE;
+ // D&D im Gange?
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ {
+ bDrag = TRUE;
+ nRet = 1;
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( !pChild->mpFrameData->mpDragTimer )
+ pChild->mpFrameData->mpDragTimer = new ImplDragTimer( pChild->ImplGetFrameWindow() );
+ pDragManager->MouseMove( aMEvt, pChild );
+ }
+ else if ( nSVEvent == EVENT_MOUSEBUTTONUP )
+ {
+ pChild->ImplGenerateMouseMove();
+ pDragManager->ButtonUp( aMEvt, pChild );
+ }
+ }
+ else
+ {
+ // Fenster bei Klick nach vorne bringen
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ pChild->ToTop();
+ if ( aDelData.IsDelete() )
+ return 1;
+ }
+
+ if ( ImplCallPreNotify( aNEvt ) || aDelData.IsDelete() )
+ nRet = 1;
+ else
+ {
+ nRet = 0;
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( bTracking )
+ {
+ TrackingEvent aTEvt( aMEvt );
+ pChild->Tracking( aTEvt );
+ if ( !aDelData.IsDelete() )
+ {
+ // When ScrollRepeat, we restart the timer
+ if ( pSVData->maWinData.mpTrackTimer &&
+ (pSVData->maWinData.mnTrackFlags & STARTTRACK_SCROLLREPEAT) )
+ pSVData->maWinData.mpTrackTimer->Start();
+ }
+ bCallHelpRequest = FALSE;
+ nRet = 1;
+ }
+ else
+ {
+ // Auto-ToTop
+ if ( !pSVData->maWinData.mpCaptureWin &&
+ (pChild->GetSettings().GetMouseSettings().GetOptions() & MOUSE_OPTION_AUTOFOCUS) )
+ pChild->ToTop( TOTOP_NOGRABFOCUS );
+
+ // Wenn Hilfe-Fenster im MouseMove angezeigt/gehidet wird,
+ // wird danach nicht mehr der HelpRequest-Handler gerufen
+ Window* pOldHelpTextWin = pSVData->maHelpData.mpHelpWin;
+ pChild->mbMouseMove = FALSE;
+ pChild->MouseMove( aMEvt );
+ if ( pOldHelpTextWin != pSVData->maHelpData.mpHelpWin )
+ bCallHelpRequest = FALSE;
+ }
+ }
+ else if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( bTracking &&
+ !(pSVData->maWinData.mnTrackFlags & STARTTRACK_MOUSEBUTTONDOWN) )
+ nRet = 1;
+ else
+ {
+ pChild->mbMouseButtonDown = FALSE;
+ pChild->MouseButtonDown( aMEvt );
+ }
+ }
+ else
+ {
+ if ( bTracking )
+ {
+ pChild->EndTracking();
+ nRet = 1;
+ }
+ else
+ {
+ pChild->mbMouseButtonUp = FALSE;
+ pChild->MouseButtonUp( aMEvt );
+ }
+ }
+ }
+ }
+
+ if ( aDelData.IsDelete() )
+ return 1;
+
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ pChild->mpFrameData->mbInMouseMove = FALSE;
+
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( bCallHelpRequest )
+ ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
+ nRet = 1;
+ }
+ else if ( !nRet )
+ {
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( !pChild->mbMouseButtonDown )
+ nRet = 1;
+ }
+ else
+ {
+ if ( !pChild->mbMouseButtonUp )
+ nRet = 1;
+ }
+ }
+
+ pChild->ImplRemoveDel( &aDelData );
+
+ // ContextMenu
+ if ( !bDrag && ((nSVEvent == EVENT_MOUSEBUTTONDOWN) || (nSVEvent == EVENT_MOUSEBUTTONUP)) )
+ {
+ // StartAutoScrollMode-Command-Event
+ if ( /*(nRet == 0) &&*/ (nClicks == 1) && (nSVEvent == EVENT_MOUSEBUTTONDOWN) &&
+ (nCode == MOUSE_MIDDLE) )
+ {
+ BOOL bPreNotify;
+ CommandEvent aCEvt( aChildPos, COMMAND_STARTAUTOSCROLL, TRUE );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pChild->mbCommand = FALSE;
+ pChild->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return 1;
+ pChild->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pChild->mbCommand )
+ nRet = 0;
+ else
+ nRet = 1;
+ }
+ else
+ {
+ const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
+ if ( (nCode == rMSettings.GetContextMenuCode()) &&
+ (nClicks == rMSettings.GetContextMenuClicks()) )
+ {
+ BOOL bContextMenu;
+ if ( rMSettings.GetContextMenuDown() )
+ bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONDOWN);
+ else
+ bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONUP);
+ if ( bContextMenu )
+ {
+ BOOL bPreNotify;
+ CommandEvent aCEvt( aChildPos, COMMAND_CONTEXTMENU, TRUE );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pChild->mbCommand = FALSE;
+ pChild->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return 1;
+ pChild->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pChild->mbCommand )
+ nRet = 0;
+ else
+ nRet = 1;
+ }
+ }
+ }
+ }
+
+ // set new mouse pointer
+ if ( (nSVEvent == EVENT_MOUSEMOVE) && !bMouseLeave )
+ ImplSetMousePointer( pChild );
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static Window* ImplGetKeyInputWindow( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // determine last input time
+ pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
+
+ // find window
+ Window* pChild = pWindow->mpFrameData->mpFocusWin;
+
+ // Nur KeyInput an das Focus-Window auswerten
+ if ( !pChild || (pChild != pSVData->maWinData.mpFocusWin) )
+ return 0;
+ DBG_ASSERT( pChild == pSVData->maWinData.mpFocusWin,
+ "ImplHandleKey: Keyboard-Input is sent to the wrong frame" );
+
+ // no keyinput to disabled windows
+ if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() )
+ return 0;
+
+ return pChild;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleKey( Window* pWindow, USHORT nSVEvent,
+ USHORT nKeyCode, USHORT nCharCode, USHORT nRepeat )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ KeyCode aKeyCode( nKeyCode, nKeyCode );
+ USHORT nCode = aKeyCode.GetCode();
+
+ // determine last input time
+ pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
+
+ // handle tracking window
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+#ifdef DBG_UTIL
+#ifdef REMOTE_APPSERVER
+ if ( aKeyCode.IsShift() && aKeyCode.IsMod2() && (aKeyCode.GetCode() == KEY_D) )
+#else
+ if ( aKeyCode.IsShift() && aKeyCode.IsMod1() && (aKeyCode.GetCode() == KEY_D) )
+#endif
+ {
+ DBGGUI_START();
+ return 1;
+ }
+#endif
+
+ if ( pSVData->maHelpData.mbExtHelpMode )
+ {
+ Help::EndExtHelp();
+ if ( nCode == KEY_ESCAPE )
+ return 1;
+ }
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+
+ // AutoScrollMode
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ {
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ if ( nCode == KEY_ESCAPE )
+ return 1;
+ }
+
+ // D&D im Gange und Escape?
+ if ( nCode == KEY_ESCAPE )
+ {
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ {
+ // Ist pWindow immer das TargetWindow?
+ // Nicht unbedingt. Aktuelles TargetWindow im DragManager merken?
+ pWindow->ImplGenerateMouseMove();
+ pDragManager->Escape( pWindow );
+ return 1;
+ }
+ }
+
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ if ( (nCode == KEY_ESCAPE) && !(pSVData->maWinData.mnTrackFlags & STARTTRACK_NOKEYCANCEL) )
+ {
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ if ( nCode == KEY_ESCAPE )
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+ }
+ return 1;
+ }
+ else if ( nCode == KEY_RETURN )
+ {
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_KEY );
+ return 1;
+ }
+ else if ( !(pSVData->maWinData.mnTrackFlags & STARTTRACK_KEYINPUT) )
+ return 1;
+ }
+
+ // handle FloatingMode
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ if ( nCode == KEY_ESCAPE )
+ {
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ return 1;
+ }
+ }
+ }
+
+ // test for accel
+ if ( pSVData->maAppData.mpAccelMgr )
+ {
+ if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode, nRepeat ) )
+ return 1;
+ }
+ }
+
+ // find window
+ Window* pChild = pWindow->mpFrameData->mpFocusWin;
+
+ // Nur KeyInput an das Focus-Window auswerten
+ if ( !pChild || (pChild != pSVData->maWinData.mpFocusWin) )
+ return 0;
+ DBG_ASSERT( pChild == pSVData->maWinData.mpFocusWin,
+ "ImplHandleKey: Keyboard-Input is sent to the wrong frame" );
+
+ // no keyinput to disabled windows
+ if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() )
+ return 0;
+
+ // call handler
+ ImplDelData aDelData;
+ KeyEvent aKEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
+ NotifyEvent aNEvt( nSVEvent, pChild, &aKEvt );
+ BOOL bPreNotify;
+ long nRet = 1;
+
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+ pChild->mbKeyInput = FALSE;
+ pChild->KeyInput( aKEvt );
+ }
+ else
+ {
+ pChild->mbKeyUp = FALSE;
+ pChild->KeyUp( aKEvt );
+ }
+ }
+ else
+ bPreNotify = TRUE;
+
+ if ( aDelData.IsDelete() )
+ return 1;
+
+ pChild->ImplRemoveDel( &aDelData );
+
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+ if ( !bPreNotify && pChild->mbKeyInput )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ // ContextMenu
+ if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift()) )
+ {
+ CommandEvent aCEvt( pChild->GetPointerPosPixel(), COMMAND_CONTEXTMENU, FALSE );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pChild->mbCommand = FALSE;
+ pChild->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return 1;
+ pChild->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pChild->mbCommand )
+ nRet = 0;
+ }
+ else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
+ {
+ if ( !aKeyCode.GetModifier() )
+ {
+ if ( pSVData->maHelpData.mbContextHelp )
+ {
+ Point aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
+ HelpEvent aHelpEvent( aMousePos, HELPMODE_CONTEXT );
+ pChild->RequestHelp( aHelpEvent );
+ }
+ else
+ nRet = 0;
+ }
+ else if ( aKeyCode.IsShift() )
+ {
+ if ( pSVData->maHelpData.mbExtHelp )
+ Help::StartExtHelp();
+ else
+ nRet = 0;
+ }
+ }
+ else
+ {
+ if ( ImplCallHotKey( aKeyCode ) )
+ nRet = 1;
+ else
+ nRet = 0;
+ }
+ }
+ }
+ else
+ {
+ if ( !bPreNotify && pChild->mbKeyUp )
+ nRet = 0;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplCallExtTextInput( Window* pChild, USHORT nEvt,
+ void* pData = NULL )
+{
+ CommandEvent aCEvt( pChild->GetPointerPosPixel(), nEvt, FALSE, pData );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
+ ImplDelData aDelData;
+ BOOL bPreNotify;
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pChild->mbCommand = FALSE;
+ pChild->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return FALSE;
+ pChild->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pChild->mbCommand )
+ return TRUE;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleStartExtTextInput( Window* pWindow )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ long nRet = 0;
+ if ( pChild )
+ {
+ pChild->mbExtTextInput = TRUE;
+ pChild->ImplGetWinData()->mnExtOldTextLen = 0;
+ nRet = ImplCallExtTextInput( pChild, COMMAND_STARTEXTTEXTINPUT );
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleEndExtTextInput( Window* pWindow )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ long nRet = 0;
+ if ( pChild )
+ {
+ pChild->mbExtTextInput = FALSE;
+ pChild->ImplGetWinData()->mnExtOldTextLen = 0;
+ nRet = ImplCallExtTextInput( pChild, COMMAND_ENDEXTTEXTINPUT );
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleExtTextInput( Window* pWindow, ULONG nTime,
+ const XubString& rText,
+ const USHORT* pTextAttr,
+ ULONG nCursorPos, BOOL bCursorVisible,
+ ULONG nDeltaStart, BOOL bOnlyCursor )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ long nRet = 0;
+ if ( pChild )
+ {
+ BOOL bSmartMode = FALSE;
+ if ( !pChild->mbExtTextInput )
+ {
+ bSmartMode = TRUE;
+ ImplHandleStartExtTextInput( pWindow );
+ }
+ CommandExtTextInputData aData( rText, pTextAttr,
+ (USHORT)nCursorPos, bCursorVisible,
+ (USHORT)nDeltaStart,
+ pChild->ImplGetWinData()->mnExtOldTextLen,
+ bOnlyCursor );
+ pChild->ImplGetWinData()->mnExtOldTextLen = rText.Len();
+ nRet = ImplCallExtTextInput( pChild, COMMAND_EXTTEXTINPUT, &aData );
+ if ( bSmartMode )
+ {
+ // TextAttribute muessen zum Schluss restauriert ausgegeben werden
+ if ( pTextAttr )
+ {
+ ImplHandleExtTextInput( pWindow, nTime, rText, NULL,
+ nCursorPos, bCursorVisible,
+ nDeltaStart, bOnlyCursor );
+ }
+ ImplHandleEndExtTextInput( pWindow );
+ }
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static Window* ImplHandleExtTextInputPos( Window* pWindow, ULONG nFirst,
+ ULONG nChars )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ if ( pChild )
+ {
+ CommandExtTextInputPosData aData( (USHORT)nFirst, (USHORT)nChars, EXTTEXTINPUTPOS_NOSHOWPOS );
+ ImplCallExtTextInput( pChild, COMMAND_EXTTEXTINPUTPOS, &aData );
+ }
+ return pChild;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleInputContextChange( Window* pWindow )
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleICursorPos( Window* pWindow, long& rX, long& rY,
+ long& rWidth, long& rHeight )
+{
+ rX = 0;
+ rY = 0;
+ rWidth = 0;
+ rHeight = 0;
+
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ if ( pChild )
+ {
+ ImplCallExtTextInput( pChild, COMMAND_CURSORPOS );
+ Cursor* pCursor = pChild->GetCursor();
+ if ( pCursor )
+ {
+ Point aPos = pChild->ImplLogicToDevicePixel( pCursor->GetPos() );
+ rX = aPos.X();
+ rY = aPos.Y();
+ Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
+ rWidth = aSize.Width();
+ rHeight = aSize.Height();
+ if ( !aSize.Width() )
+ rWidth = pChild->GetSettings().GetStyleSettings().GetCursorSize();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplCallWheelCommand( Window* pWindow, const Point& rPos,
+ const CommandWheelData* pWheelData )
+{
+ Point aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
+ CommandEvent aCEvt( aCmdMousePos, COMMAND_WHEEL, TRUE, pWheelData );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
+ ImplDelData aDelData;
+ BOOL bPreNotify;
+ pWindow->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pWindow->mbCommand = FALSE;
+ pWindow->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return FALSE;
+ pWindow->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pWindow->mbCommand )
+ return TRUE;
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleWheelEvent( Window* pWindow,
+ long nX, long nY, ULONG nMsgTime,
+ long nDelta, long nNotchDelta,
+ ULONG nScrollLines, USHORT nCode, BOOL bHorz )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ USHORT nMode;
+
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+
+ if ( nCode & KEY_MOD1 )
+ nMode = COMMAND_WHEEL_ZOOM;
+ else if ( nCode & KEY_SHIFT )
+ nMode = COMMAND_WHEEL_DATAZOOM;
+ else
+ nMode = COMMAND_WHEEL_SCROLL;
+
+ Point aMousePos( nX, nY );
+ CommandWheelData aWheelData( nDelta, nNotchDelta, nScrollLines, nMode, nCode, bHorz );
+ BOOL bRet = TRUE;
+
+ // Zuerst rufen wir den Command an dem Fenster, worueber die Maus steht
+ Window* pMouseWindow = pWindow->ImplFindWindow( aMousePos );
+ if ( pMouseWindow &&
+ pMouseWindow->IsEnabled() && pMouseWindow->IsInputEnabled() )
+ bRet = ImplCallWheelCommand( pMouseWindow, aMousePos, &aWheelData );
+
+ // Wenn das Fenster ueber dem die Maus steht, den Event nicht
+ // verarbeitet hat, rufen wir Command an dem Focus-Window
+ if ( bRet )
+ {
+ Window* pFocusWindow = pWindow->mpFrameData->mpFocusWin;
+ if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
+ (pFocusWindow == pSVData->maWinData.mpFocusWin) )
+ {
+ // no wheel-messages to disabled windows
+ if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() )
+ bRet = ImplCallWheelCommand( pFocusWindow, aMousePos, &aWheelData );
+ }
+ }
+
+ return !bRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandlePaint( Window* pWindow, const Rectangle& rBoundRect )
+{
+ // Bei Paints vom System, auch Hintergrund-Sicherung aufgeben
+ Window* pSaveBackWin = pWindow->mpFrameData->mpFirstBackWin;
+ while ( pSaveBackWin )
+ {
+ Window* pNext = pSaveBackWin->mpOverlapData->mpNextBackWin;
+ Rectangle aRect( Point( pSaveBackWin->mnOutOffX, pSaveBackWin->mnOutOffY ),
+ Size( pSaveBackWin->mnOutWidth, pSaveBackWin->mnOutHeight ) );
+ if ( aRect.IsOver( rBoundRect ) )
+ pSaveBackWin->ImplDeleteOverlapBackground();
+ pSaveBackWin = pNext;
+ }
+
+ // Paint fuer alle Fenster ausloesen, die im neu zu malenden Bereich
+ // liegen
+ Region aRegion( rBoundRect );
+ pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplHandleResize( Window* pWindow, long nNewWidth, long nNewHeight )
+{
+ if ( (nNewWidth > 0) && (nNewHeight > 0) ||
+ pWindow->ImplGetWindow()->mbAllResize )
+ {
+ if ( (nNewWidth != pWindow->mnOutWidth) || (nNewHeight != pWindow->mnOutHeight) )
+ {
+ pWindow->mnOutWidth = nNewWidth;
+ pWindow->mnOutHeight = nNewHeight;
+ pWindow->mbWaitSystemResize = FALSE;
+ if ( pWindow->IsReallyVisible() )
+ pWindow->ImplSetClipFlag();
+ if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->mbAllResize )
+ pWindow->Resize();
+ else
+ pWindow->mbCallResize = TRUE;
+ }
+ }
+
+ pWindow->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
+ (nNewHeight < IMPL_MIN_NEEDSYSWIN);
+ pWindow->mpFrameData->mbMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplActivateFloatingWindows( Window* pWindow, BOOL bActive )
+{
+ // Zuerst alle ueberlappenden Fenster ueberpruefen
+ Window* pTempWindow = pWindow->mpFirstOverlap;
+ while ( pTempWindow )
+ {
+ if ( !pTempWindow->GetActivateMode() )
+ {
+ if ( (pTempWindow->GetType() == WINDOW_BORDERWINDOW) &&
+ (pTempWindow->ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
+ ((ImplBorderWindow*)pTempWindow)->SetDisplayActive( bActive );
+ }
+
+ ImplActivateFloatingWindows( pTempWindow, bActive );
+ pTempWindow = pTempWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Window, ImplAsyncFocusHdl, void*, EMPTYARG )
+{
+ mpFrameData->mnFocusId = 0;
+
+ // Wenn Status erhalten geblieben ist, weil wir den Focus in der
+ // zwischenzeit schon wiederbekommen haben, brauchen wir auch
+ // nichts machen
+ BOOL bHasFocus = mpFrameData->mbHasFocus || mpFrameData->mbSysObjFocus;
+
+ // Dann die zeitverzoegerten Funktionen ausfuehren
+ if ( bHasFocus )
+ {
+ // Alle FloatingFenster deaktiv zeichnen
+ if ( mpFrameData->mbStartFocusState != bHasFocus )
+ ImplActivateFloatingWindows( this, bHasFocus );
+
+ if ( mpFrameData->mpFocusWin )
+ {
+ if ( mpFrameData->mpFocusWin->IsEnabled() )
+ mpFrameData->mpFocusWin->GrabFocus();
+ else
+ mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow()->GrabFocus();
+ }
+ else
+ GrabFocus();
+ }
+ else
+ {
+ Window* pFocusWin = mpFrameData->mpFocusWin;
+ if ( pFocusWin )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpFocusWin == pFocusWin )
+ {
+ // FocusWindow umsetzen
+ Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
+ pOverlapWindow->mpLastFocusWindow = pFocusWin;
+ pSVData->maWinData.mpFocusWin = NULL;
+
+ if ( pFocusWin->mpCursor )
+ pFocusWin->mpCursor->ImplHide();
+
+ // Deaktivate rufen
+ Window* pOldFocusWindow = pFocusWin;
+ if ( pOldFocusWindow )
+ {
+ Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
+ Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
+
+ pOldOverlapWindow->mbActive = FALSE;
+ pOldOverlapWindow->Deactivate();
+ if ( pOldRealWindow != pOldOverlapWindow )
+ {
+ pOldRealWindow->mbActive = FALSE;
+ pOldRealWindow->Deactivate();
+ }
+ }
+
+ // TrackingMode is ended in ImplHandleLoseFocus
+ pFocusWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
+ NotifyEvent aNEvt( EVENT_LOSEFOCUS, pFocusWin );
+ if ( !ImplCallPreNotify( aNEvt ) )
+ pFocusWin->LoseFocus();
+ pFocusWin->ImplCallDeactivateListeners( NULL );
+ GetpApp()->FocusChanged();
+ }
+ }
+
+ // Alle FloatingFenster deaktiv zeichnen
+ if ( mpFrameData->mbStartFocusState != bHasFocus )
+ ImplActivateFloatingWindows( this, bHasFocus );
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleGetFocus( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ InvalidateSystemClipboard();
+
+ pWindow->mpFrameData->mbHasFocus = TRUE;
+
+ // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
+ // nicht alles flackert, wenn diese den Focus bekommen
+ if ( !pWindow->mpFrameData->mnFocusId )
+ {
+ pWindow->mpFrameData->mbStartFocusState = !pWindow->mpFrameData->mbHasFocus;
+ Application::PostUserEvent( pWindow->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleLoseFocus( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Wenn wir den Focus verlieren gehen wir erst mal davon aus, dass sich das
+ // Systemclipboard aendert.
+ UpdateSystemClipboard();
+
+ // Wenn Frame den Focus verliert, brechen wir auch ein AutoScroll ab
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+
+ // Wenn Frame den Focus verliert, brechen wir auch ein Tracking ab
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ if ( pSVData->maWinData.mpTrackWin->mpFrameWindow == pWindow )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
+ }
+
+ // handle FloatingMode
+ // hier beenden wir immer den PopupModus, auch dann, wenn NOFOCUSCLOSE
+ // gesetzt ist, damit wir nicht beim Wechsel noch Fenster stehen lassen
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
+ pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+
+ pWindow->mpFrameData->mbHasFocus = FALSE;
+
+ // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
+ // nicht alles flackert, wenn diese den Focus bekommen
+ if ( !pWindow->mpFrameData->mnFocusId )
+ {
+ pWindow->mpFrameData->mbStartFocusState = !pWindow->mpFrameData->mbHasFocus;
+ Application::PostUserEvent( pWindow->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplHandleClose( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Bei Close schliessen wir erstmal alle FloatingModi mit
+ // und brechen auch sonstige Ablaeufe
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat;
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+ if ( pSVData->maHelpData.mbExtHelpMode )
+ Help::EndExtHelp();
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+ // AutoScrollMode
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ {
+ pWindow->ImplGenerateMouseMove();
+ pDragManager->Escape( pWindow );
+ }
+ if ( pSVData->maWinData.mpTrackWin )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
+
+ // Dann stellen wir fest, ob Close ueberhaupt erlaubt ist
+ SystemWindow* pSysWindow = (SystemWindow*)pWindow->ImplGetWindow();
+ if ( !pSysWindow->IsEnabled() || !pSysWindow->IsInputEnabled() )
+ Sound::Beep( SOUND_DISABLE, pSysWindow );
+ else
+ pSysWindow->Close();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
+{
+ if ( pSVEvent )
+ {
+ if ( pSVEvent->mbCall && !pSVEvent->maDelData.IsDelete() )
+ {
+ if ( pSVEvent->mpWindow )
+ {
+ pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
+ if ( pSVEvent->mpLink )
+ pSVEvent->mpLink->Call( pSVEvent->mpData );
+ else
+ pSVEvent->mpWindow->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
+ }
+ else
+ {
+ if ( pSVEvent->mpLink )
+ pSVEvent->mpLink->Call( pSVEvent->mpData );
+ else
+ GetpApp()->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
+ }
+ }
+
+ delete pSVEvent->mpLink;
+ delete pSVEvent;
+ }
+}
+
+// =======================================================================
+
+#ifndef REMOTE_APPSERVER
+
+static USHORT ImplGetMouseMoveMode( SalMouseEvent* pEvent )
+{
+ USHORT nMode = 0;
+ if ( !pEvent->mnCode )
+ nMode |= MOUSE_SIMPLEMOVE;
+ if ( (pEvent->mnCode & MOUSE_LEFT) && !(pEvent->mnCode & KEY_MOD1) )
+ nMode |= MOUSE_DRAGMOVE;
+ if ( (pEvent->mnCode & MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) )
+ nMode |= MOUSE_DRAGCOPY;
+ return nMode;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplGetMouseButtonMode( SalMouseEvent* pEvent )
+{
+ USHORT nMode = 0;
+ if ( pEvent->mnButton == MOUSE_LEFT )
+ nMode |= MOUSE_SIMPLECLICK;
+ if ( (pEvent->mnButton == MOUSE_LEFT) && !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT)) )
+ nMode |= MOUSE_SELECT;
+ if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) &&
+ !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_SHIFT)) )
+ nMode |= MOUSE_MULTISELECT;
+ if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_SHIFT) &&
+ !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_MOD1)) )
+ nMode |= MOUSE_RANGESELECT;
+ return nMode;
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseLeave( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, TRUE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime, pEvent->mnCode,
+ ImplGetMouseMoveMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseMove( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime, pEvent->mnCode,
+ ImplGetMouseMoveMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseButtonDown( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONDOWN, FALSE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime,
+ pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
+ ImplGetMouseButtonMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseButtonUp( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONUP, FALSE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime,
+ pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
+ ImplGetMouseButtonMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleSalMouseActivate( Window* pWindow, SalMouseActivateEvent* pEvent )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalKeyMod( Window* pWindow, SalKeyModEvent* pEvent )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pTrackWin = pSVData->maWinData.mpTrackWin;
+ if ( pTrackWin )
+ pWindow = pTrackWin;
+ USHORT nOldCode = pWindow->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
+ USHORT nNewCode = pEvent->mnCode;
+ if ( nOldCode != nNewCode )
+ {
+ nNewCode |= pWindow->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
+ pWindow->mpFrameWindow->ImplCallMouseMove( nNewCode, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalSettings( Window* pWindow, USHORT nEvent )
+{
+ // Application Notification werden nur fuer das AppWindow ausgeloest
+ SystemWindow* pSysWindow = (SystemWindow*)pWindow->ImplGetWindow();
+ WorkWindow* pAppWin = Application::GetAppWindow();
+
+ if ( pAppWin && (pSysWindow != pAppWin) )
+ return;
+
+ Application* pApp = GetpApp();
+ if ( nEvent == SALEVENT_SETTINGSCHANGED )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ AllSettings aSettings = pApp->GetSettings();
+ // International so umsetzen, das Daten durch
+ // UpdateInternationalSystemTables() nicht geaendert werden,
+ // damit wir feststellen koennen, ob sich Einstellungen
+ // geaendert haben
+ International aIntn = aSettings.GetInternational();
+ aIntn.SetQuotationMarkStart( aIntn.GetQuotationMarkStart() );
+ aIntn.SetDateFormat( aIntn.GetDateFormat() );
+ UpdateInternationalSystemTables();
+ if ( aIntn != aSettings.GetInternational() )
+ pSVData->maAppData.mbIntnChanged = TRUE;
+ pApp->MergeSystemSettings( aSettings );
+ pApp->SystemSettingsChanging( aSettings, pWindow );
+ pApp->SetSettings( aSettings );
+ pSVData->maAppData.mbIntnChanged = FALSE;
+ }
+ else
+ {
+ USHORT nType;
+ switch ( nEvent )
+ {
+ case SALEVENT_VOLUMECHANGED:
+ nType = 0;
+ break;
+ case SALEVENT_PRINTERCHANGED:
+ ImplDeletePrnQueueList();
+ nType = DATACHANGED_PRINTER;
+ break;
+ case SALEVENT_DISPLAYCHANGED:
+ nType = DATACHANGED_DISPLAY;
+ break;
+ case SALEVENT_FONTCHANGED:
+ OutputDevice::ImplUpdateAllFontData( TRUE );
+ nType = DATACHANGED_FONTS;
+ break;
+ case SALEVENT_DATETIMECHANGED:
+ nType = DATACHANGED_DATETIME;
+ break;
+ case SALEVENT_KEYBOARDCHANGED:
+ nType = 0;
+ break;
+ default:
+ nType = 0;
+ break;
+ }
+
+ if ( nType )
+ {
+ DataChangedEvent aDCEvt( nType );
+ pApp->DataChanged( aDCEvt );
+ pApp->NotifyAllWindows( aDCEvt );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalExtTextInputPos( Window* pWindow, SalExtTextInputPosEvent* pEvt )
+{
+ Window* pChild = ImplHandleExtTextInputPos( pWindow, pEvt->mnFirstPos, pEvt->mnChars );
+ if ( pChild )
+ {
+ USHORT nStart = pChild->GetExtTextInputPosStart();
+ USHORT nCount = pChild->GetExtTextInputPosCount();
+ const Rectangle* pAry = pChild->GetExtTextInputPosAry();
+ USHORT nPos;
+ for ( USHORT i = 0; i < pEvt->mnChars; i++ )
+ {
+ nPos = i+(USHORT)pEvt->mnFirstPos;
+ if ( (nPos >= nStart) && (nPos < nStart+nCount) )
+ {
+ SalExtCharPos* pSalPos = pEvt->mpPosAry+i;
+ const Rectangle* pPos = pAry+(nPos-nStart);
+ pSalPos->mnX = pChild->ImplLogicXToDevicePixel( pPos->Left() );
+ pSalPos->mnY = pChild->ImplLogicYToDevicePixel( pPos->Top() );
+ pSalPos->mnWidth = pChild->ImplLogicWidthToDevicePixel( pPos->GetWidth() );
+ pSalPos->mnHeight = pChild->ImplLogicHeightToDevicePixel( pPos->GetHeight() );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ImplWindowFrameProc( void* pInst, SalFrame* pFrame,
+ USHORT nEvent, const void* pEvent )
+{
+ DBG_TESTSOLARMUTEX();
+
+ long nRet = 0;
+
+ switch ( nEvent )
+ {
+ case SALEVENT_MOUSEMOVE:
+ nRet = ImplHandleSalMouseMove( (Window*)pInst, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_MOUSELEAVE:
+ nRet = ImplHandleSalMouseLeave( (Window*)pInst, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_MOUSEBUTTONDOWN:
+ nRet = ImplHandleSalMouseButtonDown( (Window*)pInst, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_MOUSEBUTTONUP:
+ nRet = ImplHandleSalMouseButtonUp( (Window*)pInst, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_MOUSEACTIVATE:
+ nRet = ImplHandleSalMouseActivate( (Window*)pInst, (SalMouseActivateEvent*)pEvent );
+ break;
+
+ case SALEVENT_KEYINPUT:
+ {
+ SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
+ nRet = ImplHandleKey( (Window*)pInst, EVENT_KEYINPUT,
+ pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat );
+ }
+ break;
+ case SALEVENT_KEYUP:
+ {
+ SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
+ nRet = ImplHandleKey( (Window*)pInst, EVENT_KEYUP,
+ pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat );
+ }
+ break;
+ case SALEVENT_KEYMODCHANGE:
+ ImplHandleSalKeyMod( (Window*)pInst, (SalKeyModEvent*)pEvent );
+ break;
+
+ case SALEVENT_WHEELMOUSE:
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+
+ SalWheelMouseEvent* pWheelEvt = (SalWheelMouseEvent*)pEvent;
+ nRet = ImplHandleWheelEvent( (Window*)pInst,
+ pWheelEvt->mnX, pWheelEvt->mnY,
+ pWheelEvt->mnTime,
+ pWheelEvt->mnDelta,
+ pWheelEvt->mnNotchDelta,
+ pWheelEvt->mnScrollLines,
+ pWheelEvt->mnCode, pWheelEvt->mbHorz );
+ }
+ break;
+
+ case SALEVENT_PAINT:
+ {
+ SalPaintEvent* pPaintEvt = (SalPaintEvent*)pEvent;
+ Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
+ Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
+ ImplHandlePaint( (Window*)pInst, aBoundRect );
+ }
+ break;
+
+ case SALEVENT_RESIZE:
+ {
+ long nNewWidth;
+ long nNewHeight;
+ ((Window*)pInst)->mpFrame->GetClientSize( nNewWidth, nNewHeight );
+ ImplHandleResize( (Window*)pInst, nNewWidth, nNewHeight );
+ }
+ break;
+
+ case SALEVENT_GETFOCUS:
+ ImplHandleGetFocus( (Window*)pInst );
+ break;
+ case SALEVENT_LOSEFOCUS:
+ ImplHandleLoseFocus( (Window*)pInst );
+ break;
+
+ case SALEVENT_CLOSE:
+ ImplHandleClose( (Window*)pInst );
+ break;
+
+ case SALEVENT_SHUTDOWN:
+ if ( Application::GetAppWindow() == ((WorkWindow*)pInst)->ImplGetWindow() )
+ {
+ if ( GetpApp()->QueryExit() )
+ {
+ // Message-Schleife beenden
+ Application::Quit();
+ return FALSE;
+ }
+ else
+ return TRUE;
+ }
+ break;
+
+ case SALEVENT_SETTINGSCHANGED:
+ case SALEVENT_VOLUMECHANGED:
+ case SALEVENT_PRINTERCHANGED:
+ case SALEVENT_DISPLAYCHANGED:
+ case SALEVENT_FONTCHANGED:
+ case SALEVENT_DATETIMECHANGED:
+ case SALEVENT_KEYBOARDCHANGED:
+ ImplHandleSalSettings( (Window*)pInst, nEvent );
+ break;
+
+ case SALEVENT_USEREVENT:
+ ImplHandleUserEvent( (ImplSVEvent*)pEvent );
+ break;
+
+ case SALEVENT_STARTEXTTEXTINPUT:
+ ImplHandleStartExtTextInput( (Window*)pInst );
+ break;
+ case SALEVENT_EXTTEXTINPUT:
+ {
+ SalExtTextInputEvent* pEvt = (SalExtTextInputEvent*)pEvent;
+ ImplHandleExtTextInput( (Window*)pInst, pEvt->mnTime,
+ pEvt->maText, pEvt->mpTextAttr,
+ pEvt->mnCursorPos, pEvt->mbCursorVisible,
+ pEvt->mnDeltaStart, pEvt->mbOnlyCursor );
+ }
+ break;
+ case SALEVENT_ENDEXTTEXTINPUT:
+ ImplHandleEndExtTextInput( (Window*)pInst );
+ break;
+ case SALEVENT_EXTTEXTINPUTPOS:
+ ImplHandleSalExtTextInputPos( (Window*)pInst, (SalExtTextInputPosEvent*)pEvent );
+ break;
+ case SALEVENT_INPUTCONTEXTCHANGE:
+ {
+ ImplHandleInputContextChange( (Window*)pInst );
+ }
+ break;
+
+ case SALEVENT_CURSORPOS:
+ {
+ SalCursorPosEvent* pEvt = (SalCursorPosEvent*)pEvent;
+ ImplHandleICursorPos( (Window*)pInst,
+ pEvt->mnX, pEvt->mnY,
+ pEvt->mnWidth, pEvt->mnHeight );
+ }
+ break;
+
+#ifdef DBG_UTIL
+ default:
+ DBG_ERROR1( "ImplWindowFrameProc(): unknown event (%lu)", (ULONG)nEvent );
+ break;
+#endif
+ }
+
+ return nRet;
+}
+
+#else // => REMOTE_APPSERVER
+
+void ImplRemoteWindowFrameProc( ExtRmEvent* pEvent )
+{
+ DBG_TESTSOLARMUTEX();
+
+ ULONG nId = pEvent->GetId();
+ switch ( nId )
+ {
+ case RMEVENT_KEYINPUT:
+ {
+ RmKeyEventData* pData = (RmKeyEventData*)pEvent->GetData();
+ ImplHandleKey( pEvent->GetWindow(), EVENT_KEYINPUT,
+ pData->nKeyCode, pData->nChar, pData->nCount );
+ }
+ break;
+ case RMEVENT_KEYUP:
+ {
+ RmKeyEventData* pData = (RmKeyEventData*)pEvent->GetData();
+ ImplHandleKey( pEvent->GetWindow(), EVENT_KEYUP,
+ pData->nKeyCode, pData->nChar, 0 );
+ }
+ break;
+ case RMEVENT_MOUSEBUTTONDOWN:
+ case RMEVENT_MOUSEBUTTONUP:
+ case RMEVENT_MOUSEMOVE:
+ {
+ USHORT nSVEvent;
+ if ( nId == RMEVENT_MOUSEBUTTONDOWN )
+ nSVEvent = EVENT_MOUSEBUTTONDOWN;
+ else if ( nId == RMEVENT_MOUSEBUTTONUP )
+ nSVEvent = EVENT_MOUSEBUTTONUP;
+ else
+ nSVEvent = EVENT_MOUSEMOVE;
+ RmMouseEventData* pData = (RmMouseEventData*)pEvent->GetData();
+ BOOL bMouseLeave = ( pData->nMode & MOUSE_LEAVEWINDOW ) ? TRUE : FALSE;
+ pData->nMode &= ~(MOUSE_ENTERWINDOW|MOUSE_LEAVEWINDOW);
+
+ // Bei MOUSE_MOVE eine Bestaetigung zurueckschicken, damit der
+ // RClient solange verzoegert...
+ // Vorm ImplHandleMouseEvent, falls dort z.B. ein modaler Dialog
+ // aufgemacht wird.
+ if ( nId == RMEVENT_MOUSEMOVE )
+ {
+ DBG_ASSERT( pEvent->GetWindow()->ImplGetFrame(), "RemoteWindowProc: Frame?" );
+ if ( pEvent->GetWindow()->ImplGetFrame() )
+ pEvent->GetWindow()->ImplGetFrame()->MouseMoveProcessed();
+ }
+
+ ImplHandleMouseEvent( pEvent->GetWindow(), nSVEvent, bMouseLeave,
+ pData->nX, pData->nY, pData->nSysTime,
+ pData->nCode, pData->nMode );
+
+ }
+ break;
+ case RMEVENT_PAINT:
+ {
+ Rectangle* pRect = (Rectangle*)pEvent->GetData();
+ ImplHandlePaint( pEvent->GetWindow(), *pRect );
+ }
+ break;
+ case RMEVENT_RESIZE:
+ {
+ Size* pSize = (Size*)pEvent->GetData();
+ ImplHandleResize( pEvent->GetWindow(), pSize->Width(), pSize->Height() );
+ }
+ break;
+ case RMEVENT_USEREVENT:
+ {
+ ImplHandleUserEvent( (ImplSVEvent*)pEvent->GetData() );
+ }
+ break;
+ case RMEVENT_CLOSE:
+ {
+ ImplHandleClose( pEvent->GetWindow() );
+ }
+ break;
+ case RMEVENT_GETFOCUS:
+ {
+ ImplHandleGetFocus( pEvent->GetWindow() );
+ };
+ break;
+ case RMEVENT_LOSEFOCUS:
+ {
+ ImplHandleLoseFocus( pEvent->GetWindow() );
+ };
+ break;
+ case RMEVENT_MOUSEWHEEL:
+ {
+ RmMouseWheelEventData* pData = (RmMouseWheelEventData*)pEvent->GetData();
+ ImplHandleWheelEvent( pEvent->GetWindow(),
+ pData->nX,
+ pData->nY,
+ pData->nSysTime,
+ pData->nDelta,
+ pData->nNotchDelta,
+ pData->nScrollLines,
+ pData->nCode,
+ pData->bHorz );
+ };
+ break;
+ }
+}
+
+#endif
diff --git a/vcl/source/window/wrkwin.cxx b/vcl/source/window/wrkwin.cxx
new file mode 100644
index 000000000000..1dd4d2a4e632
--- /dev/null
+++ b/vcl/source/window/wrkwin.cxx
@@ -0,0 +1,424 @@
+/*************************************************************************
+ *
+ * $RCSfile: wrkwin.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_WRKWIN_CXX
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#else
+#include <rmwindow.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_RC_H
+#include <rc.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+
+#include <rvp.hxx>
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define WORKWIN_WINDOWSTATE_FULLSCREEN ((ULONG)0x00010000)
+#define WORKWIN_WINDOWSTATE_ALL ((ULONG)0x00FF0000)
+
+// =======================================================================
+
+void WorkWindow::ImplInitData()
+{
+ mnIcon = 0;
+ mnPresentationFlags = 0;
+ mbPresentationMode = FALSE;
+ mbPresentationVisible = FALSE;
+ mbPresentationFull = FALSE;
+ mbFullScreenMode = FALSE;
+ mbSysChild = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void WorkWindow::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
+{
+#ifdef REMOTE_APPSERVER
+ static ::com::sun::star::uno::Any aVoid;
+ DBG_ASSERT( ! pSystemParentData, "SystemParentData not implemented in remote vcl" );
+ ImplInit( pParent, nStyle, aVoid );
+#else
+ USHORT nFrameStyle = BORDERWINDOW_STYLE_FRAME;
+ if ( nStyle & WB_APP )
+ nFrameStyle |= BORDERWINDOW_STYLE_APP;
+ ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, pSystemParentData, nStyle, nFrameStyle );
+ Window::ImplInit( pBorderWin, nStyle & (WB_3DLOOK | WB_CLIPCHILDREN | WB_DIALOGCONTROL), NULL );
+ pBorderWin->mpClientWindow = this;
+ pBorderWin->GetBorder( mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder );
+ mpBorderWindow = pBorderWin;
+// mpRealParent = pParent; // !!! Muesste eigentlich gesetzt werden, aber wegen Fehlern mit dem MenuBar erstmal nicht gesetzt !!!
+
+ if ( nStyle & WB_APP )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ DBG_ASSERT( !pSVData->maWinData.mpAppWin, "WorkWindow::WorkWindow(): More than one window with style WB_APP" );
+ pSVData->maWinData.mpAppWin = this;
+ }
+
+ SetActivateMode( ACTIVATE_MODE_GRABFOCUS );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void WorkWindow::ImplInit( Window* pParent, WinBits nStyle, const ::com::sun::star::uno::Any& aSystemWorkWindowToken )
+{
+#ifndef REMOTE_APPSERVER
+ if( aSystemWorkWindowToken.hasValue() )
+ {
+ ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
+ aSystemWorkWindowToken >>= aSeq;
+ SystemParentData* pData = (SystemParentData*)aSeq.getArray();
+ DBG_ASSERT( aSeq.getLength() == sizeof( SystemParentData ) && pData->nSize == sizeof( SystemParentData ), "WorkWindow::WorkWindow( Window*, const Any&, WinBits ) called with invalid Any" );
+ // init with style 0 as does WorkWindow::WorkWindow( SystemParentData* );
+ ImplInit( pParent, 0, pData );
+ }
+ else
+ ImplInit( pParent, nStyle, NULL );
+#else
+ USHORT nFrameStyle = BORDERWINDOW_STYLE_FRAME;
+ if ( nStyle & WB_APP )
+ nFrameStyle |= BORDERWINDOW_STYLE_APP;
+ ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle, nFrameStyle, aSystemWorkWindowToken );
+ Window::ImplInit( pBorderWin, nStyle & (WB_3DLOOK | WB_CLIPCHILDREN | WB_DIALOGCONTROL), aSystemWorkWindowToken );
+ pBorderWin->mpClientWindow = this;
+ pBorderWin->GetBorder( mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder );
+ mpBorderWindow = pBorderWin;
+// mpRealParent = pParent; // !!! Muesste eigentlich gesetzt werden, aber wegen Fehlern mit dem MenuBar erstmal nicht gesetzt !!!
+
+ if ( nStyle & WB_APP )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ DBG_ASSERT( !pSVData->maWinData.mpAppWin, "WorkWindow::WorkWindow(): More than one window with style WB_APP" );
+ pSVData->maWinData.mpAppWin = this;
+ }
+
+ SetActivateMode( ACTIVATE_MODE_GRABFOCUS );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+WorkWindow::WorkWindow( WindowType nType ) :
+ SystemWindow( nType )
+{
+ ImplInitData();
+}
+
+// -----------------------------------------------------------------------
+
+WorkWindow::WorkWindow( Window* pParent, WinBits nStyle ) :
+ SystemWindow( WINDOW_WORKWINDOW )
+{
+ ImplInitData();
+ ImplInit( pParent, nStyle, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+WorkWindow::WorkWindow( Window* pParent, const ResId& rResId ) :
+ SystemWindow( WINDOW_WORKWINDOW )
+{
+ ImplInitData();
+ rResId.SetRT( RSC_WORKWIN );
+ ImplInit( pParent, ImplInitRes( rResId ) );
+ ImplLoadRes( rResId );
+}
+
+// -----------------------------------------------------------------------
+
+WorkWindow::WorkWindow( Window* pParent, const ::com::sun::star::uno::Any& aSystemWorkWindowToken, WinBits nStyle ) :
+ SystemWindow( WINDOW_WORKWINDOW )
+{
+ ImplInitData();
+ mbSysChild = TRUE;
+ ImplInit( pParent, nStyle, aSystemWorkWindowToken );
+}
+
+// -----------------------------------------------------------------------
+
+WorkWindow::WorkWindow( SystemParentData* pParent ) :
+ SystemWindow( WINDOW_WORKWINDOW )
+{
+ ImplInitData();
+ mbSysChild = TRUE;
+ ImplInit( NULL, 0, pParent );
+}
+
+// -----------------------------------------------------------------------
+
+void WorkWindow::ImplLoadRes( const ResId& rResId )
+{
+ SystemWindow::ImplLoadRes( rResId );
+
+ USHORT nShowStyle = ReadShortRes();
+ if ( !(rResId.aWinBits & WB_HIDE) && (RSC_WORKWIN == rResId.GetRT()) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+WorkWindow::~WorkWindow()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maWinData.mpAppWin == this )
+ {
+ pSVData->maWinData.mpAppWin = NULL;
+ Application::Quit();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WorkWindow::SetIcon( USHORT nIcon )
+{
+ if ( mnIcon == nIcon )
+ return;
+
+ mnIcon = nIcon;
+ if ( !mbSysChild )
+ mpFrame->SetIcon( nIcon );
+}
+
+// -----------------------------------------------------------------------
+
+void WorkWindow::SetWindowState( const ByteString& rStr )
+{
+ if ( mbSysChild )
+ return;
+
+#ifndef REMOTE_APPSERVER
+ SalFrameState aState;
+ USHORT nIndex = 0;
+ aState.mnX = rStr.GetToken( 0, ',', nIndex ).ToInt32();
+ aState.mnY = rStr.GetToken( 0, ',', nIndex ).ToInt32();
+ aState.mnWidth = rStr.GetToken( 0, ',', nIndex ).ToInt32();
+ aState.mnHeight = rStr.GetToken( 0, ';', nIndex ).ToInt32();
+ if ( nIndex != STRING_NOTFOUND )
+ {
+ if ( IsFullScreenMode() )
+ ShowFullScreenMode( FALSE );
+
+ ULONG nState = rStr.Copy( nIndex ).ToInt32();
+ aState.mnState = nState & ~WORKWIN_WINDOWSTATE_ALL;
+ mpFrame->SetWindowState( &aState );
+
+ if ( nState & WORKWIN_WINDOWSTATE_FULLSCREEN )
+ ShowFullScreenMode( TRUE );
+ }
+#else
+ mpFrame->SetWindowState( String::CreateFromAscii(rStr.GetBuffer()) );
+#endif
+
+ // Syncrones Resize ausloesen, damit wir nach Moeglichkeit gleich
+ // mit der richtigen Groesse rechnen
+ // Oberstes BorderWindow ist das Window, welches positioniert werden soll
+ Window* pWindow = this;
+ while ( pWindow->mpBorderWindow )
+ pWindow = pWindow->mpBorderWindow;
+
+ // Syncrones Resize ausloesen, damit wir nach Moeglichkeit gleich
+ // mit der richtigen Groesse rechnen
+ long nNewWidth;
+ long nNewHeight;
+ pWindow->mpFrame->GetClientSize( nNewWidth, nNewHeight );
+ ImplHandleResize( pWindow, nNewWidth, nNewHeight );
+}
+
+// -----------------------------------------------------------------------
+
+ByteString WorkWindow::GetWindowState() const
+{
+ if ( mbSysChild )
+ return ImplGetSVEmptyByteStr();
+
+#ifndef REMOTE_APPSERVER
+ ByteString aStr;
+ SalFrameState aState;
+ if ( mpFrame->GetWindowState( &aState ) )
+ {
+ // FullScreen merken wir uns auch
+ if ( IsFullScreenMode() )
+ aState.mnState |= WORKWIN_WINDOWSTATE_FULLSCREEN;
+
+ aStr.Append( ByteString::CreateFromInt32( aState.mnX ) );
+ aStr.Append( ',' );
+ aStr.Append( ByteString::CreateFromInt32( aState.mnY ) );
+ aStr.Append( ',' );
+ aStr.Append( ByteString::CreateFromInt32( aState.mnWidth ) );
+ aStr.Append( ',' );
+ aStr.Append( ByteString::CreateFromInt32( aState.mnHeight ) );
+ aStr.Append( ';' );
+ aStr.Append( ByteString::CreateFromInt32( aState.mnState ) );
+ }
+ return aStr;
+#else
+ return (ByteString)::rtl::OUStringToOString( mpFrame->GetWindowState() , RTL_TEXTENCODING_ASCII_US );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void WorkWindow::ShowFullScreenMode( BOOL bFullScreenMode )
+{
+ if ( !mbFullScreenMode == !bFullScreenMode )
+ return;
+
+ mbFullScreenMode = bFullScreenMode != 0;
+ if ( !mbSysChild )
+ {
+ mpFrameWindow->mbWaitSystemResize = TRUE;
+ ImplGetFrame()->ShowFullScreen( bFullScreenMode );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WorkWindow::StartPresentationMode( BOOL bPresentation, USHORT nFlags )
+{
+ if ( !bPresentation == !mbPresentationMode )
+ return;
+
+ if ( bPresentation )
+ {
+ mbPresentationMode = TRUE;
+ mbPresentationVisible = IsVisible();
+ mbPresentationFull = mbFullScreenMode;
+ mnPresentationFlags = nFlags;
+
+ if ( !(mnPresentationFlags & PRESENTATION_NOFULLSCREEN) )
+ ShowFullScreenMode( TRUE );
+#ifndef REMOTE_APPSERVER
+ if ( !mbSysChild )
+ {
+ if ( mnPresentationFlags & PRESENTATION_HIDEALLAPPS )
+ mpFrame->SetAlwaysOnTop( TRUE );
+ if ( !(mnPresentationFlags & PRESENTATION_NOAUTOSHOW) )
+ ToTop();
+ mpFrame->StartPresentation( TRUE );
+ }
+#else
+ if ( !mbSysChild )
+ mpFrame->StartPresentation( TRUE, nFlags | PRESENTATION_NOFULLSCREEN | PRESENTATION_NOAUTOSHOW );
+#endif
+
+ if ( !(mnPresentationFlags & PRESENTATION_NOAUTOSHOW) )
+ Show();
+ }
+ else
+ {
+ Show( mbPresentationVisible );
+#ifndef REMOTE_APPSERVER
+ if ( !mbSysChild )
+ {
+ mpFrame->StartPresentation( FALSE );
+ if ( mnPresentationFlags & PRESENTATION_HIDEALLAPPS )
+ mpFrame->SetAlwaysOnTop( FALSE );
+ }
+#else
+ if ( !mbSysChild )
+ mpFrame->StartPresentation( FALSE, mnPresentationFlags | PRESENTATION_NOFULLSCREEN | PRESENTATION_NOAUTOSHOW );
+#endif
+ ShowFullScreenMode( mbPresentationFull );
+
+ mbPresentationMode = FALSE;
+ mbPresentationVisible = FALSE;
+ mbPresentationFull = FALSE;
+ mnPresentationFlags = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL WorkWindow::IsMinimized() const
+{
+ return mpFrameData->mbMinimized;
+}
diff --git a/vcl/unx/inc/XIM.h b/vcl/unx/inc/XIM.h
new file mode 100644
index 000000000000..f77ae54d51df
--- /dev/null
+++ b/vcl/unx/inc/XIM.h
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * $RCSfile: XIM.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _XIM_h
+#define _XIM_h
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+
+#ifdef __cplusplus
+extern "C"
+#endif
+XIM XvaOpenIM( Display*, XrmDatabase, char*, char*, ... );
+
+extern Status XCloseIM(XIM);
+
+#ifndef XIMCallback1
+typedef int (*XIMProc1)(XIC, XPointer, XPointer);
+typedef struct {
+ XPointer client_data;
+ XIMProc1 callback;
+} XIMCallback1;
+#endif
+
+typedef struct _XIMAnnotation {
+ int start_position;
+ int end_position;
+ XPointer data;
+} XIMAnnotation;
+
+/*
+ XIMUText: XIMText extention for UTF16
+ */
+typedef struct _XIMUnicodeText {
+ unsigned short length;
+ XIMFeedback *feedback;
+ Bool encoding_is_wchar;
+ union {
+ char *multi_byte;
+ wchar_t *wide_char;
+ unsigned short *utf16_char;
+ } string;
+ unsigned int count_annotations;
+ XIMAnnotation *annotations;
+} XIMUnicodeText;
+
+/* lookup choice */
+typedef enum {
+ XIMDrawUpHorizontally = 0 ,
+ XIMDrawUpVertically = 1
+} XIMDrawUpDirection ;
+
+typedef struct _XIMLookupStartCallbackStruct {
+ int choice_per_window; /* Number of choices can be display
+ * in the region
+ */
+ int nrows;
+ int ncolumns;
+ XIMDrawUpDirection draw_up_direction;
+} XIMLookupStartCallbackStruct;
+
+typedef struct _XIMUnicodeChoiceObject {
+ XIMUnicodeText *label;
+ XIMUnicodeText *value;
+} XIMUnicodeChoiceObject;
+
+typedef struct _XIMLookupDrawCallbackStruct {
+ XIMUnicodeChoiceObject *choices; /* the lookup choices */
+ int n_choices; /* Total number of lookup choices */
+ int first_index;
+ int last_index;
+ int current_index;
+ XIMUnicodeText *title;
+} XIMLookupDrawCallbackStruct;
+
+/* Unicode Subset */
+typedef enum {
+ XIMKatakana, XIMHanzi
+} XIMUnicodeCharacterSubsetID;
+
+typedef struct _XIMUncodeSubset {
+ XIMUnicodeCharacterSubsetID index;
+ XIMUnicodeCharacterSubsetID subset_id;
+ char *name;
+ Bool is_active;
+} XIMUnicodeCharacterSubset;
+
+typedef struct _XIMUncodeSubsets {
+ unsigned short count_subsets;
+ XIMUnicodeCharacterSubset *supported_subsets;
+} XIMUnicodeCharacterSubsets;
+
+typedef struct _XIMSwitchIMNotifyCallbackStruct {
+ XIMUnicodeCharacterSubset *from;
+ XIMUnicodeCharacterSubset *to;
+} XIMSwitchIMNotifyCallbackStruct;
+
+/* XIM attributes for multilingual IM extension */
+#define XNMultiLingualInput "multiLingualInput"
+#define XNQueryUnicodeCharacterSubset "unicodeCharacterSubset"
+
+/* XIC attributes for multilingual IM extension */
+
+#define XNUnicodeCharacterSubset "UnicodeChararcterSubset"
+
+#define XNSwitchIMNotifyCallback "switchIMNotifyCallback"
+#define XNCommitStringCallback "commitStringCallback"
+#define XNForwardEventCallback "forwardEventCallback"
+
+#define XNLookupStartCallback "lookupStartCallback"
+#define XNLookupDrawCallback "lookupDrawCallback"
+#define XNLookupDoneCallback "lookupDoneCallback"
+
+#endif
diff --git a/vcl/unx/inc/cdeint.hxx b/vcl/unx/inc/cdeint.hxx
new file mode 100644
index 000000000000..4ce7eef4c28b
--- /dev/null
+++ b/vcl/unx/inc/cdeint.hxx
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * $RCSfile: cdeint.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SV_CDEINT_HXX
+#define _SV_CDEINT_HXX
+
+#ifndef _SV_DTINT_HXX
+#include <dtint.hxx>
+#endif
+
+#include <prex.h>
+#define Boolean XLIB_Boolean
+#define Window XLIB_Window
+#include <X11/Intrinsic.h>
+#include <dt/dt.h>
+#include <dt/action.h>
+#include <dt/wsm.h>
+#undef Boolean
+#undef Window
+#include <postx.h>
+
+#ifndef _STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+class CDEIntegrator : public DtIntegrator
+{
+ friend DtIntegrator* DtIntegrator::CreateDtIntegrator( SalFrame* );
+private:
+ static void* pDtSvcLib;
+ static void* pXmLib;
+ static void* pMrmLib;
+ static void* pXtLib;
+ static void* pttLib;
+ static int nRefCount;
+ static char* pFallbackRes[];
+
+ // function pointers
+ // from DtSvc
+ static XLIB_Boolean (*pDtAppInitialize)
+ ( XtAppContext, Display*, Widget, char*, char* );
+ static void (*pDtDtsLoadDataTypes)();
+ static void (*pDtDtsRelease)();
+ static char* (*pDtDtsFileToAttributeValue)
+ (const char*,const char*);
+ static void (*pDtDtsFreeAttributeValue)( char* );
+ static DtActionInvocationID (*pDtActionInvoke)
+ ( Widget, char*, DtActionArg*, int, char*, char*, char*, int,
+ DtActionCallbackProc, XtPointer );
+ static Status (*pDtWsmGetWorkspaceInfo)( Display*, XLIB_Window, Atom,
+ DtWsmWorkspaceInfo** );
+ static void (*pDtWsmFreeWorkspaceInfo)( DtWsmWorkspaceInfo* );
+ static Status (*pDtWsmGetWorkspaceList)( Display*, XLIB_Window, Atom**,
+ int* );
+ static Status (*pDtWsmGetCurrentWorkspace)( Display*, XLIB_Window root, Atom* );
+ static Status (*pDtWsmGetWorkspacesOccupied)( Display*, XLIB_Window, Atom**, unsigned long* );
+
+ // from Mrm
+ static void (*pMrmInitialize)();
+
+ // from Xm
+ static WidgetClass* CDEIntegrator::pxmDrawingAreaWidgetClass;
+ static WidgetClass* CDEIntegrator::pxmRowColumnWidgetClass;
+ static WidgetClass* CDEIntegrator::pxmPushButtonWidgetClass;
+
+ // from Xt
+ static void (*pXtToolkitInitialize)();
+ static XtAppContext (*pXtCreateApplicationContext)();
+ static Widget (*pXtAppCreateShell)( char*, char*, WidgetClass,
+ Display*, ArgList, Cardinal );
+ static Widget (*pXtVaCreateManagedWidget)( char*, WidgetClass,
+ Widget, ... );
+ static void (*pXtDisplayInitialize)( XtAppContext, Display*,
+ char*, char*,
+ XrmOptionDescRec*, Cardinal,
+ int*, char**);
+ static Widget (*pXtSetLanguageProc)( XtAppContext, XtLanguageProc, XtPointer );
+ static void (*pXtAppSetFallbackResources)( XtAppContext, char** );
+ static Widget (*pXtAppInitialize)(XtAppContext*, char*,
+ XrmOptionDescList,
+ Cardinal, int*, char**, char**,
+ ArgList, Cardinal );
+ static void (*pXtRealizeWidget)( Widget );
+ static void (*pXtUnrealizeWidget)( Widget );
+ static XLIB_Boolean (*pXtIsRealized)( Widget );
+ static void (*pXtConfigureWidget)
+ ( Widget, Position, Position, Dimension, Dimension, Dimension );
+ static void (*pXtAppProcessEvent)( XtAppContext, XtInputMask );
+ static XtInputMask (*pXtAppPending)( XtAppContext );
+ static WidgetClass* pAppShellClass;
+
+
+ XtAppContext maAppContext;
+ Widget maAppWidget;
+
+ CDEIntegrator( SalFrame* );
+
+ void GlobalInit();
+ void GlobalDeInit();
+
+ void InvokeAction( const String&, const String& );
+
+public:
+ virtual ~CDEIntegrator();
+
+ virtual BOOL StartProcess( String&, String&, const String& rDir = String() );
+ virtual BOOL GetSystemLook( SystemLookInfo& rInfo );
+};
+
+#endif
diff --git a/vcl/unx/inc/dtint.hxx b/vcl/unx/inc/dtint.hxx
new file mode 100644
index 000000000000..1eb55abc787a
--- /dev/null
+++ b/vcl/unx/inc/dtint.hxx
@@ -0,0 +1,397 @@
+/*************************************************************************
+ *
+ * $RCSfile: dtint.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SV_DTINT_HXX
+#define _SV_DTINT_HXX
+
+#include <cstdio>
+#include <dlfcn.h>
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _LINK_HXX
+#include <tools/link.hxx>
+#endif
+#ifndef _STRING_HXX
+#include <tools/string.hxx>
+#endif
+#include <tools/color.hxx>
+
+class SalFrame;
+class SalBitmap;
+class String;
+class SalDisplay;
+class FastItemInfo;
+
+#ifndef _XLIB_H_
+// forwards from X
+struct Display;
+struct XEvent;
+#define Atom UINT32
+#define XLIB_Window UINT32
+#endif
+
+#define XDND_PROTOCOL_VERSION 3
+
+// NETBSD has no RTLD_GLOBAL
+#ifndef RTLD_GLOBAL
+#define DLOPEN_MODE (RTLD_LAZY)
+#else
+#define DLOPEN_MODE (RTLD_GLOBAL | RTLD_LAZY)
+#endif
+
+class DtIntegrator;
+
+DECLARE_LIST( DtIntegratorList, DtIntegrator* );
+DECLARE_LIST( DtSalFrameList, SalFrame* );
+DECLARE_LIST( StringList, String* );
+
+struct SystemLookInfo
+{
+ /** system foreground color */
+ Color foreground;
+ /** system background color */
+ Color background;
+ /** system foreground color for a selection */
+ Color selectForeground;
+ /** system background color for a selection */
+ Color selectBackground;
+
+ /** gradient for an active window */
+ Color windowActiveStart;
+ Color windowActiveEnd;
+ /** border color for active window */
+ Color activeBorder;
+ /** text color for active window bar */
+ Color activeForeground;
+ /** gradient of an inactive window */
+ Color windowInactiveStart;
+ Color windowInactiveEnd;
+ /** border color for inactive window */
+ Color inactiveBorder;
+ /** text color for inactive window bar */
+ Color inactiveForeground;
+
+ /** font to use for controls. Empty if not set. */
+ String controlFont;
+ /** font to use for dragbars. Empty if not set. */
+ String windowFont;
+
+ SystemLookInfo()
+ {
+ foreground.SetColor( COL_TRANSPARENT );
+ background.SetColor( COL_TRANSPARENT );
+ selectBackground.SetColor( COL_TRANSPARENT );
+ selectForeground.SetColor( COL_TRANSPARENT );
+
+ windowActiveStart.SetColor( COL_TRANSPARENT );
+ windowActiveEnd.SetColor( COL_TRANSPARENT );
+ activeBorder.SetColor( COL_TRANSPARENT );
+ activeForeground.SetColor( COL_TRANSPARENT );
+
+ windowInactiveStart.SetColor( COL_TRANSPARENT );
+ windowInactiveEnd.SetColor( COL_TRANSPARENT );
+ inactiveBorder.SetColor( COL_TRANSPARENT );
+ inactiveForeground.SetColor( COL_TRANSPARENT );
+ }
+};
+
+enum DtType {
+ DtGeneric,
+ DtCDE,
+ DtKDE,
+ DtGNOME,
+ DtSCO,
+ DtIRIX
+};
+
+enum DtDataType {
+ DtTypeUrl,
+ DtTypeText,
+ DtTypeKnown
+};
+
+struct DtData
+{
+ DtDataType meType;
+ int mnX, mnY; // used for Drop data
+ void* mpFrame; // dito
+ int mnBytes;
+ unsigned char* mpBytes;
+ unsigned char* mpType;
+
+ DtData() : meType( DtTypeText ), mnX( -1 ), mnY( -1 ), mpFrame( 0 ),
+ mnBytes( 0 ), mpBytes( 0 ), mpType( NULL ) {}
+ ~DtData()
+ {
+ if( mpBytes )
+ delete mpBytes;
+ }
+};
+
+enum DtDropAction
+{
+ DtDropNone = 0,
+ DtDropCopy = 1,
+ DtDropMove = 2,
+ DtDropLink = 4,
+ DtDropAny = 7
+};
+
+struct DtDropQuery
+{
+ int m_nX;
+ int m_nY;
+ DtDropAction m_eAction;
+ void* m_pFrame; // really a SalFrame*
+};
+
+class DtIntegrator
+{
+protected:
+ enum DtDragState { DtDragNone = 0, DtDragging, DtWaitForStatus,
+ DtWaitForDataRequest };
+
+ DtType meType;
+ Display* mpDisplay;
+ SalDisplay* mpSalDisplay;
+ SalFrame* mpSalFrame;
+ int mnRefCount;
+
+ XLIB_Window maSelectionWindow;
+ Atom maExPropertyAtom;
+
+ Atom mnXdndAware;
+ Atom mnXdndSelection;
+ Atom mnXdndEnter;
+ Atom mnXdndLeave;
+ Atom mnXdndStatus;
+ Atom mnXdndTypeList;
+ Atom mnXdndPosition;
+ Atom mnXdndDrop;
+ Atom mnXdndActionCopy;
+ Atom mnXdndActionMove;
+ Atom mnXdndActionLink;
+ Atom mnXdndActionAsk;
+ Atom mnXdndActionPrivate;
+ Atom mnXdndActionList;
+ Atom mnXdndActionDescription;
+ Atom mnXdndFinished;
+
+ int mnDropDataTime;
+ int mnLastDropX;
+ int mnLastDropY;
+ XLIB_Window maDropSource;
+ SalFrame* mpDropTarget;
+ StringList maDropTypes;
+
+ Link maDropFinishHdl;
+ Link maQueryDropHdl;
+ Link maBeginDropHdl;
+
+ DtDragState meDragState;
+ int mnLastDragX;
+ int mnLastDragY;
+ int mnLastDragTimestamp;
+ int mnWaitTimestamp;
+ Link maQueryDragDataHdl;
+ XLIB_Window maDragSource;
+ XLIB_Window maDragTarget;
+ StringList maDragTypes;
+
+ DtIntegrator( SalFrame* );
+
+ DtSalFrameList maDropzones;
+
+ Link maClipboardChangedHdl;
+ Atom mnClipboardAtom;
+ Atom mnTargetsAtom;
+ Atom mnCompoundAtom;
+ DtData* mpLastData;
+
+ virtual void ImplRegisterDropzone( SalFrame* );
+ virtual void ImplUnregisterDropzone( SalFrame* );
+ virtual void ImplHandleXEvent( XEvent* );
+
+ BOOL LaunchProcess( const String&, const String& rDirectory = String() );
+
+ static DtIntegratorList aIntegratorList;
+ static String aHomeDir;
+
+ // helper functions
+ XLIB_Window GetXdndAwareWindowBeneathPointer( int& rVersion, XEvent* );
+ void SendXdndLeave();
+ void SendXdndEnter();
+ void SendXdndPosition( XEvent* );
+ void CheckXdndTimeout( int );
+
+public:
+ static DtIntegrator* CreateDtIntegrator( SalFrame* );
+
+ static void HandleXEvent( XEvent* );
+
+ virtual ~DtIntegrator();
+
+ virtual BOOL StartProcess( String&, String&, const String& rDir = String() );
+
+ // functions for Clipboard
+ inline Link SetClipboardChangedHdl( const Link& );
+ const Link& GetClipboardChangedHdl()
+ { return maClipboardChangedHdl; }
+ void Copy( DtData* ); // copy to system
+ DtData* Paste(); // copy from system
+ BOOL CheckUnxClipboardChanged();
+
+ // functions for Dnd
+ void RegisterDropzone( SalFrame* );
+ void UnregisterDropzone( SalFrame* );
+ DtDropAction ExecuteDrag( const StringList &, SalFrame* pFrame );
+ DtData* DropFinish( const String& rType );
+ StringList& GetDropTypes() { return maDropTypes; }
+
+ const Link& GetDropFinishHdl() { return maDropFinishHdl; }
+ Link SetDropFinishHdl( const Link& rNewLink )
+ {
+ Link aRet = maDropFinishHdl;
+ maDropFinishHdl = rNewLink;
+ return aRet;
+ }
+ const Link& GetQueryDropHdl() { return maDropFinishHdl; }
+ Link SetQueryDropHdl( const Link& rNewLink )
+ {
+ Link aRet = maQueryDropHdl;
+ maQueryDropHdl = rNewLink;
+ return aRet;
+ }
+ const Link& GetBeginDropHdl() { return maBeginDropHdl; }
+ Link SetBeginDropHdl( const Link& rNewLink )
+ {
+ Link aRet = maBeginDropHdl;
+ maBeginDropHdl = rNewLink;
+ return aRet;
+ }
+ const Link& GetQueryDragDataHdl() { return maQueryDragDataHdl; }
+ Link SetQueryDragDataHdl( const Link& rNewLink )
+ {
+ Link aRet = maQueryDragDataHdl;
+ maQueryDragDataHdl = rNewLink;
+ return aRet;
+ }
+
+ // SystemLook
+ virtual BOOL GetSystemLook( SystemLookInfo& rInfo );
+
+ DtType GetDtType() { return meType; }
+ SalFrame* GetFrame() { return mpSalFrame; }
+ SalDisplay* GetSalDisplay() { return mpSalDisplay; }
+ Display* GetDisplay() { return mpDisplay; }
+
+ void Acquire() { mnRefCount++; }
+ inline void Release();
+};
+
+inline void DtIntegrator::Release()
+{
+ mnRefCount--;
+ if( ! mnRefCount )
+ {
+ aIntegratorList.Remove( this );
+ delete this;
+ }
+}
+
+inline Link DtIntegrator::SetClipboardChangedHdl( const Link& rLink )
+{
+ Link aOldLink = maClipboardChangedHdl;
+ maClipboardChangedHdl = rLink;
+ return aOldLink;
+}
+
+// helper funktions for dynamic loading
+extern BOOL bSymbolLoadFailed;
+
+inline void* _LoadSymbol( void* pLibrary, char* pSymbolname )
+{
+ void *pRet = dlsym( pLibrary, pSymbolname );
+ if( ! pRet )
+ {
+ fprintf( stderr, "Could not load symbol %s: %s\n",
+ pSymbolname, dlerror() );
+ bSymbolLoadFailed = TRUE;
+ }
+ return pRet;
+}
+inline void* _LoadLibrary( char* pLibname )
+{
+ bSymbolLoadFailed = FALSE;
+ void *pRet = dlopen( pLibname, DLOPEN_MODE );
+ if( ! pRet )
+ {
+#ifdef DEBUG
+ fprintf( stderr, "%s could not be opened: %s\n",
+ pLibname, dlerror() );
+#endif
+ bSymbolLoadFailed = TRUE;
+ }
+ return pRet;
+}
+
+#endif
diff --git a/vcl/unx/inc/i18n_cb.hxx b/vcl/unx/inc/i18n_cb.hxx
new file mode 100644
index 000000000000..a18a2eb4a7c7
--- /dev/null
+++ b/vcl/unx/inc/i18n_cb.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * $RCSfile: i18n_cb.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SAL_I18N_CALLBACK_HXX
+#define _SAL_I18N_CALLBACK_HXX
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// for iiimp / ml input
+int CommitStringCallback( XIC ic, XPointer client_data, XPointer call_data);
+
+// xim callbacks
+void PreeditDoneCallback ( XIC ic, XPointer client_data, XPointer call_data);
+int PreeditStartCallback( XIC ic, XPointer client_data, XPointer call_data);
+void PreeditDoneCallback ( XIC ic, XPointer client_data, XPointer call_data);
+void PreeditDrawCallback ( XIC ic, XPointer client_data,
+ XIMPreeditDrawCallbackStruct *call_data );
+void PreeditCaretCallback( XIC ic, XPointer client_data,
+ XIMPreeditCaretCallbackStruct *call_data );
+
+/* private hook to prevent from sending further edit events */
+void PreeditCancelCallback( XPointer client_data );
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+typedef struct {
+ sal_Unicode *pUnicodeBuffer;
+ XIMFeedback *pCharStyle;
+ unsigned int nCursorPos;
+ unsigned int nLength;
+ unsigned int nSize;
+} preedit_text_t;
+
+class SalFrame;
+
+typedef enum {
+ ePreeditStatusDontKnow = 0,
+ ePreeditStatusActive,
+ ePreeditStatusActivationRequired,
+ ePreeditStatusStartPending
+} preedit_status_t;
+
+typedef struct {
+ SalFrame *pFrame;
+ Bool bIsMultilingual;
+ preedit_status_t eState;
+ preedit_text_t aText;
+} preedit_data_t;
+
+#endif /* _SAL_I18N_CALLBACK_HXX */
diff --git a/vcl/unx/inc/i18n_ic.hxx b/vcl/unx/inc/i18n_ic.hxx
new file mode 100644
index 000000000000..4212bee79782
--- /dev/null
+++ b/vcl/unx/inc/i18n_ic.hxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * $RCSfile: i18n_ic.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SAL_I18N_INPUTCONTEXT_HXX
+#define _SAL_I18N_INPUTCONTEXT_HXX
+
+#ifndef _SAL_I18N_CALLBACK_HXX
+#include "i18n_cb.hxx"
+#endif
+
+class SalI18N_InputContext
+{
+
+private:
+
+ Bool mbUseable; // system supports current locale ?
+ Bool mbMultiLingual; // system supports iiimp ?
+ XIC maContext;
+
+ XIMStyle mnSupportedStatusStyle;
+ XIMStyle mnSupportedPreeditStyle;
+ XIMStyle mnStatusStyle;
+ XIMStyle mnPreeditStyle;
+
+ preedit_data_t maClientData;
+ XIMCallback maPreeditStartCallback;
+ XIMCallback maPreeditDoneCallback;
+ XIMCallback maPreeditDrawCallback;
+ XIMCallback maPreeditCaretCallback;
+ XIMCallback maCommitStringCallback;
+
+ XVaNestedList mpAttributes;
+ XVaNestedList mpStatusAttributes;
+ XVaNestedList mpPreeditAttributes;
+ #ifdef SOLARIS
+ XFontSet mpFontSet;
+ Display *mpDisplay;
+ #endif
+
+ Bool SupportInputMethodStyle( XIMStyles *pIMStyles );
+ unsigned int GetWeightingOfIMStyle( XIMStyle n_style ) const ;
+ Bool IsSupportedIMStyle( XIMStyle n_style ) const ;
+
+public:
+
+ Bool UseContext() { return mbUseable; }
+ Bool IsMultiLingual() { return mbMultiLingual; }
+ XIC GetContext() { return maContext; }
+
+ void ExtendEventMask( XLIB_Window aFocusWindow );
+ void SetICFocus();
+ void UnsetICFocus();
+ int HandleKeyEvent( XKeyEvent *pEvent, SalFrame *pFrame ); // unused
+ void EndExtTextInput( USHORT nFlags ); // unused
+ int CommitStringCallback( sal_Unicode* pText, sal_Size nLength );
+
+ void Map( SalFrame *pFrame );
+ void Unmap();
+
+ SalI18N_InputContext( SalFrame *pFrame );
+ ~SalI18N_InputContext();
+
+private:
+
+ SalI18N_InputContext(); // do not use this
+
+};
+
+#endif _SAL_I18N_INPUTCONTEXT_HXX
+
+
diff --git a/vcl/unx/inc/i18n_im.hxx b/vcl/unx/inc/i18n_im.hxx
new file mode 100644
index 000000000000..a81dc7eba6dd
--- /dev/null
+++ b/vcl/unx/inc/i18n_im.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * $RCSfile: i18n_im.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SAL_I18N_INPUTMETHOD_HXX
+#define _SAL_I18N_INPUTMETHOD_HXX
+
+extern "C" char*
+GetMethodName( XIMStyle nStyle, char *pBuf, int nBufSize);
+
+#if (1)
+ #define bUseInputMethodDefault True
+#else
+ #define bUseInputMethodDefault False
+#endif
+
+class SalI18N_InputMethod
+{
+ Bool mbUseable; // system supports locale as well as status
+ // and preedit style ?
+ Bool mbMultiLingual; // system supports iiimp
+ XIM maMethod;
+ XIMStyles *mpStyles;
+
+public:
+
+ Bool IsMultiLingual() { return mbMultiLingual; }
+ Bool UseMethod() { return mbUseable; }
+ XIM GetMethod() { return maMethod; }
+ Bool CreateMethod( Display *pDisplay );
+ XIMStyles *GetSupportedStyles() { return mpStyles; }
+ Bool SetLocale( const char* pLocale = "" );
+ Bool FilterEvent( XEvent *pEvent );
+
+
+ SalI18N_InputMethod();
+ ~SalI18N_InputMethod();
+};
+
+#endif _SAL_I18N_INPUTMETHOD_HXX
+
+
diff --git a/vcl/unx/inc/i18n_xkb.hxx b/vcl/unx/inc/i18n_xkb.hxx
new file mode 100644
index 000000000000..5eb59ff0c235
--- /dev/null
+++ b/vcl/unx/inc/i18n_xkb.hxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * $RCSfile: i18n_xkb.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SAL_I18N_XKBDEXTENSION_HXX
+#define _SAL_I18N_XKBDEXTENSION_HXX
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+class SalI18N_KeyboardExtension
+{
+private:
+
+ sal_Bool mbUseExtension;
+ sal_uInt32 mnDefaultGroup;
+ sal_uInt32 mnGroup;
+ sal_uInt32 mnEventBase;
+ sal_uInt32 mnErrorBase;
+ Display* mpDisplay;
+
+public:
+
+ SalI18N_KeyboardExtension( Display *pDisplay );
+ inline ~SalI18N_KeyboardExtension();
+
+ inline sal_Bool UseExtension() const ; // server and client support the
+ // extension
+ inline void UseExtension( sal_Bool bState );// used to disable the Extension
+
+ void Dispatch( XEvent *pEvent ); // keep track of group changes
+
+ sal_uInt32 LookupKeysymInGroup( sal_uInt32 nKeyCode,
+ sal_uInt32 nShiftState,
+ sal_uInt32 nGroup ) const ;
+
+ inline sal_uInt32 LookupKeysymInDefaultGroup(
+ sal_uInt32 nKeyCode,
+ sal_uInt32 nShiftState ) const ;
+ inline sal_uInt32 GetGroup() const ; // the current keyboard group
+ inline sal_uInt32 GetDefaultGroup() const ; // base group, usually group 1
+ inline sal_uInt32 GetEventBase() const ;
+
+protected:
+
+ SalI18N_KeyboardExtension(); // disabled
+};
+
+inline
+SalI18N_KeyboardExtension::~SalI18N_KeyboardExtension()
+{
+}
+
+inline sal_Bool
+SalI18N_KeyboardExtension::UseExtension() const
+{
+ return mbUseExtension;
+}
+
+inline void
+SalI18N_KeyboardExtension::UseExtension( sal_Bool bState )
+{
+ mbUseExtension = mbUseExtension && bState;
+}
+
+inline sal_uInt32
+SalI18N_KeyboardExtension::LookupKeysymInDefaultGroup( sal_uInt32 nKeyCode,
+ sal_uInt32 nShiftState ) const
+{
+ return LookupKeysymInGroup( nKeyCode, nShiftState, mnDefaultGroup );
+}
+
+inline sal_uInt32
+SalI18N_KeyboardExtension::GetGroup() const
+{
+ return mnGroup;
+}
+
+inline sal_uInt32
+SalI18N_KeyboardExtension::GetDefaultGroup() const
+{
+ return mnDefaultGroup;
+}
+
+inline sal_uInt32
+SalI18N_KeyboardExtension::GetEventBase() const
+{
+ return mnEventBase;
+}
+
+#endif // _SAL_I18N_XKBDEXTENSION_HXX
+
diff --git a/vcl/unx/inc/postx.h b/vcl/unx/inc/postx.h
new file mode 100644
index 000000000000..db89e7822dcb
--- /dev/null
+++ b/vcl/unx/inc/postx.h
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * $RCSfile: postx.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+// //
+// (C) 1997 Star Division GmbH, Hamburg, Germany //
+// //
+// $Revision: 1.1.1.1 $ $Author: hr $ $Date: 2000-09-18 17:05:41 $ //
+// //
+// $Workfile: postx.h $ //
+// $Modtime: 08 Aug 1997 10:13:36 $ //
+// //
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+
+#ifndef _POSTX_H
+#define _POSTX_H
+
+#if defined __cplusplus && ! defined LINUX
+}
+#endif
+
+/* X-Types */
+#undef Window
+#undef BYTE
+#undef INT8
+#undef BOOL
+#undef Font
+#undef Cursor
+#undef String
+#undef KeyCode
+#undef Region
+#undef Icon
+#undef Time
+#undef Boolean
+
+#undef Min
+#undef Max
+#undef class
+#undef new
+#undef DestroyAll
+#undef Success
+
+#undef Printer
+/* #undef FontInfo */
+#undef Orientation
+
+#undef GetToken
+#undef ReleaseToken
+#undef InitializeToken
+#undef NextRequest
+
+/* Network Audio System */
+#undef Sound
+
+#ifdef KeyPress
+#if KeyPress != 2
+Error KeyPress must be Equal 2
+#endif
+#undef KeyPress
+#endif
+#define XLIB_KeyPress 2
+
+#endif
+
diff --git a/vcl/unx/inc/prex.h b/vcl/unx/inc/prex.h
new file mode 100644
index 000000000000..2046be74aa81
--- /dev/null
+++ b/vcl/unx/inc/prex.h
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * $RCSfile: prex.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+// //
+// (C) 1997 Star Division GmbH, Hamburg, Germany //
+// //
+// $Revision: 1.1.1.1 $ $Author: hr $ $Date: 2000-09-18 17:05:41 $ //
+// //
+// $Workfile: prex.h $ //
+// $Modtime: 08 Aug 1997 10:13:54 $ //
+// //
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+
+#ifndef _PREX_H
+#define _PREX_H
+
+#define Window XLIB_Window
+#define BYTE XLIB_BYTE
+#define INT8 XLIB_INT8
+#define BOOL XLIB_BOOL
+#define Font XLIB_Font
+#define Cursor XLIB_Cursor
+#define String XLIB_String
+#define KeyCode XLIB_KeyCode
+#define Region XLIB_Region
+#define Icon XLIB_Icon
+#define class XLIB_class
+#define new XLIB_new
+#define Time XLIB_Time
+#define Region XLIB_Region
+#define Boolean XLIB_Boolean
+
+/* fuer Network Audio System */
+#define Sound XLIB_Sound
+
+#if defined( MTF12 ) || defined( ALPHA )
+#define XLIB_ILLEGAL_ACCESS
+#endif
+#if defined( RS6000 ) || defined( ALPHA )
+struct _XDisplay;
+#endif
+
+#if defined __cplusplus && ! defined LINUX
+extern "C" {
+#endif
+
+#include <X11/StringDefs.h>
+#include <X11/Intrinsic.h>
+
+#ifdef SOLARIS
+#define USE_MOTIF
+#else
+#define USE_ATHENA
+#endif
+
+#undef DestroyAll
+#define DestroyAll XLIB_DestroyAll
+#define XLIB_DestroyAll 0
+#undef String
+#define String XLIB_String
+#include <X11/IntrinsicP.h>
+#include <X11/Shell.h>
+#ifdef USE_MOTIF
+#include <Xm/BulletinB.h>
+#define SAL_COMPOSITE_WIDGET xmBulletinBoardWidgetClass
+#endif
+#ifdef USE_ATHENA
+#include <X11/Xaw/Box.h>
+#define SAL_COMPOSITE_WIDGET boxWidgetClass
+#endif
+#undef XtInheritTranslations
+#define XtInheritTranslations ((XLIB_String) (&_XtInheritTranslations))
+
+#undef KeyCode
+#define KeyCode XLIB_KeyCode //undef in intrinsics
+
+#define __Ol_OlXlibExt_h__
+
+#include <salpdecl.h>
+#include <salpmacr.h>
+
+#endif
+
diff --git a/vcl/unx/inc/saldata.hxx b/vcl/unx/inc/saldata.hxx
new file mode 100644
index 000000000000..99273531b565
--- /dev/null
+++ b/vcl/unx/inc/saldata.hxx
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldata.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALDATA_HXX
+#define _SV_SALDATA_HXX
+
+// -=-= includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <signal.h>
+
+#ifndef _SALSTD_HXX
+#include <salstd.hxx>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SALWTYPE_HXX
+#include <salwtype.hxx>
+#endif
+
+// -=-= forwards -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalXLib;
+class SalDisplay;
+class SalInstance;
+class SalFrame;
+class SalPrinter;
+
+// -=-= typedefs -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef SIG_PF
+typedef void SIG_FUNC_TYP(int);
+typedef SIG_FUNC_TYP *SIG_TYP;
+#define SIG_PF SIG_TYP
+#endif
+
+DECLARE_LIST( SalDisplays, SalDisplay* )
+
+#if defined SCO || defined LINUX || defined NETBSD || defined AIX || defined HPUX || defined FREEBSD
+#include <pthread.h>
+#else
+typedef unsigned int pthread_t;
+#endif
+
+// -=-= SalData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalData
+{
+ char** argv_;
+ int argc_;
+ String aBinaryPath_;
+
+ SALTIMERPROC pTimerProc_; // timer callback proc
+
+ SIG_TYP sig_[30];
+ BOOL bNoExceptions_;
+
+ SalXLib *pXLib_;
+
+ SalDisplays SalDisplays_;
+ SalDisplay *pDefDisp_;
+ SalDisplay *pCurDisp_;
+
+ pthread_t hMainThread_;
+public:
+ SalInstance *pFirstInstance_; // pointer of first instance
+ SalFrame *pFirstFrame_; // pointer of first frame
+
+public:
+ SalData();
+ ~SalData();
+
+ void Init( int *pArgc, char *ppArgv[] );
+
+ inline const XubString &GetFileName() const { return aBinaryPath_; }
+ inline USHORT GetCommandLineParamCount() const
+ { return argc_; }
+ XubString GetCommandLineParam( USHORT nParam ) const;
+
+ long ShutDown() const;
+ long Close() const;
+ inline void XError( Display *pDisplay,
+ XErrorEvent *pEvent ) const;
+
+ SalDisplay *GetDisplay( Display *pDisplay );
+ inline SalDisplay *GetDisplay( long nDisplay ) const
+ { return SalDisplays_.GetObject(nDisplay); }
+ inline SalDisplay *GetDefDisp() const { return pDefDisp_; }
+ inline SalDisplay *GetCurDisp() const { return pCurDisp_; }
+ inline void SetDefDisp( SalDisplay *pDisp )
+ { pDefDisp_ = pDisp; }
+ inline void SetCurDisp( SalDisplay *pDisp )
+ { pCurDisp_ = pDisp; }
+ inline void Insert( SalDisplay *pDisplay );
+ inline void Remove( SalDisplay *pDisplay );
+
+ inline SalXLib *GetLib() const { return pXLib_; }
+ inline pthread_t GetMainThread() const { return hMainThread_; }
+
+ void StartTimer( ULONG nMS );
+ inline void StopTimer();
+ inline void SetCallback( SALTIMERPROC pProc )
+ { pTimerProc_ = pProc; }
+ void Timeout() const;
+
+};
+
+// -=-= inlines =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+inline void SetSalData( SalData* pData )
+{ ImplGetSVData()->mpSalData = (void*)pData; }
+
+inline SalData* GetSalData()
+{ return (SalData*)ImplGetSVData()->mpSalData; }
+
+inline void SalData::Insert( SalDisplay *pDisplay )
+{ SalDisplays_.Insert( pDisplay ); }
+
+inline void SalData::Remove( SalDisplay *pDisplay )
+{ SalDisplays_.Remove( pDisplay ); }
+
+#ifdef _SV_SALDISP_HXX
+inline void SalData::XError( Display *pDisplay, XErrorEvent *pEvent ) const
+{ pXLib_->XError( pDisplay, pEvent ); }
+#endif
+#endif // _SV_SALDATA_HXX
+
diff --git a/vcl/unx/inc/saldisp.hxx b/vcl/unx/inc/saldisp.hxx
new file mode 100644
index 000000000000..40cafa2f54fd
--- /dev/null
+++ b/vcl/unx/inc/saldisp.hxx
@@ -0,0 +1,589 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldisp.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALDISP_HXX
+#define _SV_SALDISP_HXX
+
+// -=-= exports =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+struct SalAppXResource;
+class SalDisplay;
+class SalICCCM;
+class SalColormap;
+class SalColormapRef;
+class SalTrueColorConverter;
+class SalVisual;
+class SalXLib;
+class SalImageList;
+class SalBitmapList;
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef _SALUNX_H
+#include <salunx.h>
+#endif
+#ifndef _SV_SALGTYPE_HXX
+#include <salgtype.hxx>
+#endif
+#ifndef _SV_PTRSTYLE_HXX
+#include <ptrstyle.hxx>
+#endif
+
+// -=-= forwards -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class BitmapPalette;
+class SalImage;
+class SalBitmap;
+class SalFrameData;
+class ColorMask;
+class SalSystemData;
+
+#ifndef _XSHM_H_
+struct XShmSegmentInfo;
+#endif
+
+// -=-= typedefs -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+typedef struct _oslMutexImpl *oslThreadMutex;
+
+DECLARE_LIST( SalImageList, SalImage* )
+DECLARE_LIST( SalBitmapList,SalBitmap*)
+
+// -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#define PROPERTY_SUPPORT_WM_SetPos 0x00000001
+#define PROPERTY_SUPPORT_WM_Screen 0x00000002
+#define PROPERTY_SUPPORT_WM_Parent_Pixmap_None 0x00000004
+#define PROPERTY_SUPPORT_WM_ClientPos 0x00000008
+#define PROPERTY_SUPPORT_XSetClipMask 0x00000010 // for bitmap ops.
+#define PROPERTY_SUPPORT_3ButtonMouse 0x00000020
+
+#define PROPERTY_BUG_XA_FAMILY_NAME_nil 0x00001000
+#define PROPERTY_BUG_XCopyArea_GXxor 0x00002000 // from window
+#define PROPERTY_BUG_Stipple 0x00004000 // 0/1 inverted
+#define PROPERTY_BUG_Tile 0x00008000 // Recreate the
+ // dither brush each time
+#define PROPERTY_BUG_FillPolygon_Tile 0x00010000 // always Toggle Fillstyle
+#define PROPERTY_BUG_DrawLine 0x00020000 // a DrawLine is one point to short
+#define PROPERTY_BUG_CopyPlane_RevertBWPixel 0x00040000 // revert fg and bg for xcopyplane
+#define PROPERTY_BUG_CopyArea_OnlySmallSlices 0x00080000
+#define PROPERTY_BUG_Bitmap_Bit_Order 0x00100000
+
+#define PROPERTY_FEATURE_Maximize 0x01000000
+#define PROPERTY_FEATURE_SharedMemory 0x02000000
+
+#define PROPERTY_DEFAULT 0x00000FCB
+
+// ------------------------------------------------------------------------
+// server vendor
+
+typedef enum {
+ vendor_none = 0,
+ vendor_attachmate,
+ vendor_excursion,
+ vendor_hp,
+ vendor_hummingbird,
+ vendor_ibm,
+ vendor_sco,
+ vendor_sgi,
+ vendor_sun,
+ vendor_xfree,
+ vendor_xinside,
+ vendor_xprinter,
+ vendor_unknown
+} srv_vendor_t;
+
+extern "C" srv_vendor_t sal_GetServerVendor( Display *p_display );
+
+// -=-= SalWM =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+enum SalWM { olwm, // Open Look
+ mwm, // Motif
+ kwm, // KDE Desktop Environment
+ _4Dwm, // SGI
+ vuewm, // HP
+ dtwm, // CDE
+ winmgr, // Oracle NC
+ twm,
+ fvwm, // ...
+ pmwm, // SCO
+ otherwm };
+
+// -=-= SalICCCM =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+class SalICCCM
+{
+ unknown STDAPI( SalICCCM )
+
+public:
+ Atom aWM_Protocols_; // Window manager
+ Atom aWM_State_;
+ Atom aWM_DeleteWindow_;
+ Atom aWM_SaveYourself_;
+ Atom aWM_Command_;
+
+ Atom aQuitEvent_; // client message events
+ Atom aUserEvent_;
+
+ inline int IsQuitEvent( Atom a ) const
+ { return aQuitEvent_ == a; }
+ inline int IsUserEvent( Atom a ) const
+ { return aUserEvent_ == a; }
+ inline int IsWM_State( Atom a ) const
+ { return aWM_State_ == a; }
+ inline int IsWM_DeleteWindow( Atom a ) const
+ { return aWM_DeleteWindow_ == a; }
+ inline int IsWM_Protocols( Atom a ) const
+ { return aWM_Protocols_ == a; }
+ inline int IsWM_SaveYourself( Atom a ) const
+ { return aWM_SaveYourself_ == a; }
+ inline int IsWM_Command( Atom a ) const
+ { return aWM_Command_ == a; }
+
+ SalICCCM( SalDisplay *pDisplay );
+};
+
+// -=-= SalRGB -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// MSB/Bigendian Sicht (SalColor == RGB, r=0xFF0000, g=0xFF00, b=0xFF)
+
+enum SalRGB { RGB, RBG,
+ GBR, GRB,
+ BGR, BRG,
+ RGBA, RBGA,
+ GBRA, GRBA,
+ BGRA, BRGA,
+ other };
+
+// -=-= SalVisual =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalVisual : public XVisualInfo
+{
+ unknown STDAPI( SalVisual )
+
+ SalRGB eRGBMode_;
+ int nRedShift_;
+ int nGreenShift_;
+ int nBlueShift_;
+public:
+ ~SalVisual();
+ SalVisual( const XVisualInfo* pXVI );
+
+ inline VisualID GetVisualId() const { return visualid; }
+ inline Visual *GetVisual() const { return visual; }
+ inline int GetClass() const { return c_class; }
+ inline int GetDepth() const { return depth; }
+ inline SalRGB GetMode() const { return eRGBMode_; }
+
+ Pixel GetTCPixel( SalColor nColor ) const;
+ SalColor GetTCColor( Pixel nPixel ) const;
+ BOOL Convert( int &n0, int &n1, int &n2, int &n3 ); // 32bit
+ BOOL Convert( int &n0, int &n1, int &n2 ); // 24bit
+};
+
+// -=-= SalColormap/SalColormapRef=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalColormap : public SvRefBase
+{
+ unknown STDAPI( SalColormap )
+
+ SalDisplay *pDisplay_;
+ Colormap hColormap_;
+ SalColor *pPalette_; // Pseudocolor
+ SalVisual *pVisual_;
+ USHORT *pLookupTable_; // Pseudocolor: 12bit reduction
+ Pixel nWhitePixel_;
+ Pixel nBlackPixel_;
+ Pixel nUsed_; // Pseudocolor
+
+ void GetPalette();
+ void GetLookupTable();
+public:
+ SalColormap( SalDisplay *pSalDisplay,
+ Colormap hColormap );
+ SalColormap( const BitmapPalette &rpPalette );
+ SalColormap( USHORT nDepth );
+ SalColormap();
+ virtual ~SalColormap();
+
+ inline Colormap GetXColormap() const { return hColormap_; }
+ inline SalDisplay *GetDisplay() const { return pDisplay_; }
+ inline Display *GetXDisplay() const;
+ inline SalVisual *GetVisual() const;
+ inline Visual *GetXVisual() const;
+ inline Pixel GetWhitePixel() const { return nWhitePixel_; }
+ inline Pixel GetBlackPixel() const { return nBlackPixel_; }
+ inline Pixel GetUsed() const { return nUsed_; }
+ inline int GetClass() const;
+
+ BOOL GetXPixels( XColor &rColor,
+ int r,
+ int g,
+ int b ) const;
+ inline BOOL GetXPixel( XColor &rColor,
+ int r,
+ int g,
+ int b ) const;
+ Pixel GetPixel( SalColor nColor ) const;
+ SalColor GetColor( Pixel nPixel ) const;
+ void SetPalette( const BitmapPalette &rPalette );
+};
+
+SV_DECL_IMPL_REF( SalColormap )
+
+// -=-= SalXLib =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+typedef int(*YieldFunc)(int fd, void* data);
+struct YieldEntry;
+
+class SalXLib
+{
+ unknown STDAPI( SalXLib )
+
+ XtAppContext pApplicationContext_;
+ timeval Timeout_;
+ ULONG nTimeoutMS_;
+ int nStateOfYield_;
+ BOOL bWasXError_;
+ BOOL bIgnoreXErrors_;
+ int nFDs_;
+ fd_set *pReadFDS_;
+ fd_set *pExceptionFDS_;
+ YieldEntry *pYieldEntries_;
+public:
+ SalXLib();
+ ~SalXLib();
+ void Init( int *pArgc, char *ppArgv[] );
+
+ void Yield( BOOL bWait );
+
+ void Insert( int fd, void* data,
+ YieldFunc pending,
+ YieldFunc queued,
+ YieldFunc handle );
+ void Remove( int fd );
+
+ void XError( Display *pDisp, XErrorEvent *pEvent );
+ inline BOOL WasXError() const { return bWasXError_; }
+ inline BOOL GetIgnoreXErrors() const { return bIgnoreXErrors_; }
+ inline void SetIgnoreXErrors( BOOL b )
+ { bIgnoreXErrors_ = b; bWasXError_ = FALSE; }
+
+ inline void StartTimer( ULONG nMS );
+ inline void StopTimer();
+
+ inline XtAppContext GetAppContext() const
+ { return pApplicationContext_; }
+};
+
+// -=-= SalXEvent =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+struct SalXEvent
+{
+ SalXEvent *pNext_; // Stack
+ XEvent event_;
+};
+
+// -=-= SalDisplay -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+class SalI18N_InputMethod;
+class SalI18N_KeyboardExtension;
+class XlfdStorage;
+class ExtendedFontStruct;
+class ExtendedXlfd;
+class AttributeProvider;
+class SalUnicodeConverter;
+class SalConverterCache;
+
+DECLARE_LIST( SalFontCache, ExtendedFontStruct* )
+
+class SalDisplay
+{
+ unknown STDAPI( SalDisplay )
+
+ SalXLib *pXLib_;
+ SalI18N_InputMethod *mpInputMethod;
+ SalI18N_KeyboardExtension *mpKbdExtension;
+
+ AttributeProvider *mpFactory;
+ XlfdStorage *mpFontList;
+ SalConverterCache *mpCvtCache;
+
+ SalSystemData *mpSalSystemData;
+ // the one to get create and destroy notify events
+
+ SalICCCM *pICCCM_; // Atoms
+ Display *pDisp_; // X Display
+ Screen *pScreen_; // XDefaultScreenOfDisplay
+ int nScreen_; // XDefaultScreen
+ SalVisual *pRootVisual_; // default visual of screen
+ XLIB_Window hRootWindow_;
+ Size aSize_; // Screen Size [pixel]
+ Pair aResolution_; // [dpi]
+ ULONG nMaxRequestSize_; // [byte]
+
+ srv_vendor_t meServerVendor;
+ SalWM eWindowManager_;
+ ULONG nProperties_; // PROPERTY_SUPPORT, BUG, FEATURE
+ BOOL bLocal_; // Server==Client? Init
+ // in SalDisplay::IsLocal()
+ BOOL mbLocalIsValid; // bLocal_ is valid ?
+ ULONG nImageDepths_; // Supported Image Depths
+ ULONG nSharedImages_; // Supports MIT-SHM Extension
+ // until x bytes
+
+ int nStateOfYield_;
+ int nStateOfSendEvent_;
+ oslThreadMutex hEventGuard_;
+ SalXEvent *pEventQueue_; // threaded user event queue
+ SalXEvent *pDispatchStack_; // Dispatch/Yield
+
+ // SalFrame
+ Widget hShell_; // Application Shell Widget
+ Widget hComposite_; // the composite child of the shell
+
+ XLIB_Cursor aPointerCache_[POINTER_COUNT];
+ SalFrameData *pCapture_;
+
+ // GDI
+ SalVisual *pVisual_; // Visual
+ XLIB_Window hRefWindow_;
+ GC pMonoGC_;
+ GC pCopyGC_;
+ GC pAndInvertedGC_;
+ GC pAndGC_;
+ GC pOrGC_;
+ GC pStippleGC_;
+ Pixmap hInvert50_;
+ SalColormapRef xColor_;
+
+ SalFontCache *pFontCache_;
+
+ int nBeepVolume_; // Sound
+
+ // Keyboard
+ BOOL bNumLockFromXS_; // Num Lock handled by X Server
+ int nNumLockIndex_; // modifier index in modmap
+ int nNumLockMask_; // keyevent state mask for
+ KeySym nShiftKeySym_; // first shift modifier
+ KeySym nCtrlKeySym_; // first control modifier
+ KeySym nMod1KeySym_; // first mod1 modifier
+ ByteString m_aKeyboardName;
+
+ SalBitmapList Bitmaps_; // to destroy bitmap resources;
+
+ SalImageList SharedImages_;
+
+ void DestroyFontCache();
+ long Dispatch( XEvent *pEvent );
+
+public:
+ static SalDisplay *GetSalDisplay( Display* display );
+ static BOOL BestVisual( Display *pDisp,
+ int nScreen,
+ XVisualInfo &rVI );
+
+ SalDisplay( Widget w );
+ SalDisplay( Display* pDisp,
+ Visual* pVisual = NULL,
+ Colormap aColMap = None );
+
+ ~SalDisplay();
+
+ void Init( Colormap hXColmap, const XVisualInfo* pXVI );
+
+ BOOL IsEvent();
+ void SendEvent( Atom aEvent,
+ void *pData,
+ XLIB_Window hReceiver = 0 ) const;
+ void SendEvent( Atom aEvent,
+ UINT32 *pData = 0,
+ XLIB_Window hReceiver = 0 ) const;
+ void Yield( BOOL bWait );
+ void PrintInfo() const;
+
+ void PrintEvent( const ByteString &rComment,
+ XEvent *pEvent ) const;
+
+ void AddFontPath( const ByteString &rPath ) const;
+ XlfdStorage* GetXlfdList();
+ ExtendedFontStruct*
+ GetFont( ExtendedXlfd *pFont, int nPixelSize );
+
+ void Beep() const;
+
+ void ModifierMapping();
+ String GetKeyNameFromKeySym( KeySym keysym ) const;
+ XubString GetKeyName( USHORT nKeyCode ) const;
+ USHORT GetKeyCode( KeySym keysym, char*pcPrintable ) const;
+ KeySym GetKeySym( XKeyEvent *pEvent,
+ unsigned char *pPrintable,
+ int *pLen,
+ Status *pStatus,
+ XIC = NULL ) const;
+
+ XLIB_Cursor GetPointer( int ePointerStyle );
+ int CaptureMouse( SalFrameData *pCapture );
+
+ BOOL IsLocal();
+ inline void Insert( SalBitmap *pBitmap );
+ inline void Remove( SalBitmap *pBitmap );
+
+ inline SalImage *Seek( SalImage *pImage );
+ inline void Insert( SalImage *pImage );
+ inline void Remove( SalImage *pImage );
+ void Remove( XEvent *pEvent );
+
+ inline XLIB_Window GetWindow() const
+ { return XtWindow( hComposite_ ); }
+ inline Widget GetWidget() const { return hComposite_; }
+ inline XLIB_Window GetShellWindow() const
+ { return XtWindow( hShell_ ); }
+ inline Widget GetShellWidget() const { return hShell_; }
+
+ inline XLIB_Window GetRootWindow() const
+ { return hRootWindow_; }
+ inline XLIB_Window GetDrawable() const { return hRefWindow_; }
+ inline Display *GetDisplay() const { return pDisp_; }
+ inline int GetScreenNumber() const { return nScreen_; }
+ inline srv_vendor_t GetServerVendor() const { return meServerVendor; }
+ inline void SetServerVendor() {
+ meServerVendor = sal_GetServerVendor(pDisp_); }
+ inline BOOL IsDisplay() const { return !!pXLib_; }
+ inline SalICCCM &GetICCCM() const { return *pICCCM_; }
+ inline GC GetMonoGC() const { return pMonoGC_; }
+ inline GC GetCopyGC() const { return pCopyGC_; }
+ inline GC GetAndInvertedGC() const { return pAndInvertedGC_; }
+ inline GC GetAndGC() const { return pAndGC_; }
+ inline GC GetOrGC() const { return pOrGC_; }
+ inline GC GetStippleGC() const { return pStippleGC_; }
+ inline GC GetGC( USHORT nDepth ) const;
+ inline Pixmap GetInvert50() const { return hInvert50_; }
+ inline SalColormap &GetColormap() const { return *xColor_; }
+ inline SalVisual *GetVisual() const { return pVisual_; }
+ inline SalVisual *GetRootVisual() const { return pRootVisual_; }
+ inline const Size &GetScreenSize() const { return aSize_; }
+ inline const Pair &GetResolution() const { return aResolution_; }
+ inline ULONG GetProperties() const { return nProperties_; }
+ inline ULONG GetMaxRequestSize() const { return nMaxRequestSize_; }
+ inline ULONG GetImageDepths() const { return nImageDepths_; }
+ inline ULONG SupportsShm() const { return nSharedImages_; }
+ inline void DisableShm() { nSharedImages_ /= 2; } // = 0
+
+ inline BOOL MouseCaptured( const SalFrameData *pFrameData ) const
+ { return pCapture_ == pFrameData; }
+ inline SalXLib* GetXLib() { return pXLib_; }
+
+ inline SalI18N_InputMethod* GetInputMethod() { return mpInputMethod; }
+ inline SalI18N_KeyboardExtension* GetKbdExtension() { return mpKbdExtension; }
+ inline void SetInputMethod( SalI18N_InputMethod *pInputMethod )
+ { mpInputMethod = pInputMethod; }
+ inline void SetKbdExtension(SalI18N_KeyboardExtension *pKbdExtension)
+ { mpKbdExtension = pKbdExtension; }
+ const char* GetKeyboardName( BOOL bRefresh = FALSE );
+ SalConverterCache* GetConverter() { return mpCvtCache; }
+};
+
+// -=-= inlines =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+inline void SalDisplay::Remove( SalBitmap *pBitmap )
+{ Bitmaps_.Remove( pBitmap ); }
+
+inline void SalDisplay::Insert( SalBitmap *pBitmap )
+{ Bitmaps_.Insert( pBitmap ); }
+
+inline SalImage *SalDisplay::Seek( SalImage *pImage )
+{ return SharedImages_.Seek( pImage ); }
+
+inline void SalDisplay::Remove( SalImage *pImage )
+{ SharedImages_.Remove( pImage ); }
+
+inline void SalDisplay::Insert( SalImage *pImage )
+{ SharedImages_.Insert( pImage ); }
+
+inline GC SalDisplay::GetGC( USHORT nDepth ) const
+{ return 1 == nDepth
+ ? pMonoGC_
+ : pVisual_->GetDepth() == nDepth
+ ? pCopyGC_
+ : NULL; }
+
+inline Display *SalColormap::GetXDisplay() const
+{ return pDisplay_->GetDisplay(); }
+
+inline SalVisual *SalColormap::GetVisual() const
+{ return pVisual_ ? pVisual_ : pDisplay_->GetVisual(); }
+
+inline Visual *SalColormap::GetXVisual() const
+{ return GetVisual()->GetVisual(); }
+
+inline int SalColormap::GetClass() const
+{ return pVisual_ ? pVisual_->GetClass() : PseudoColor; }
+
+/*----------------------------------------------------------
+ keep track of correct size of the initial window
+ */
+extern "C" {
+
+void MarkWindowAsBadPositioned ( unsigned int nWindow );
+void MarkWindowAsGoodPositioned ( unsigned int nWindow );
+Bool WindowNeedGoodPosition ( unsigned int nWindow );
+
+} /* extern "C" */
+
+// get foreign key names
+namespace vcl_sal {
+ String getKeysymReplacementName(
+ const char* pKeyboard,
+ KeySym nSymbol );
+}
+
+
+#endif // _SV_SALDISP_HXX
+
diff --git a/vcl/unx/inc/salfont.h b/vcl/unx/inc/salfont.h
new file mode 100644
index 000000000000..aa6b2583e73c
--- /dev/null
+++ b/vcl/unx/inc/salfont.h
@@ -0,0 +1,228 @@
+/*************************************************************************
+ *
+ * $RCSfile: salfont.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+// //
+// (C) 1997 Star Division GmbH, Hamburg, Germany //
+// //
+// $Revision: 1.1.1.1 $ $Author: hr $ $Date: 2000-09-18 17:05:41 $ //
+// //
+// $Workfile: salfont.h $ //
+// $Modtime: 06 Sep 1997 15:11:06 $ //
+// //
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+
+#ifndef _SV_SALFONT_H
+#define _SV_SALFONT_H
+
+// -=-= exports =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalFontCache;
+struct SalFontDimension;
+class SalFontFamily;
+class SalFontFamilyList;
+class SalFontStruct;
+class SalFontStructList;
+class SalFonts;
+
+// -=-= includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef _SALSTD_HXX
+#include <salstd.hxx>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+
+// -=-= forwards =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+typedef ULONG XFP_FLAGS;
+
+class SalDisplay;
+class SalFontCacheItem;
+
+// -=-= SalFontCache -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+DECLARE_LIST( SalFontCache, SalFontCacheItem* )
+
+// -=-= SalFontDimension -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+struct SalFontDimension
+{
+ USHORT nHeight_; // [pixel]
+ USHORT nPtHeight_; // [point/10]
+ USHORT nAverage_; // [pixel/10]
+ USHORT nXRes_; // [dpi]
+ USHORT nYRes_; // [dpi]
+ USHORT nSlant_; // [pixel]
+// size_t nUnderlineThickness_; // [pixel]
+// size_t nUnderlinePosition_; // [pixel]
+// size_t nStrikeoutAscent_; // [pixel]
+// size_t nStrikeoutDescent_; // [pixel]
+// Subscript, Superscript, Capital, Space ...
+
+ inline SalFontDimension( USHORT nA = 0, USHORT nH = 0 );
+
+ inline BOOL IsScalable() const;
+ inline USHORT GetWidth() const { return (nAverage_ + 5) / 10; }
+ inline Size GetSize() const;
+ inline void SetSize( const Size & rSize );
+ inline BOOL operator == ( const SalFontDimension &r ) const;
+ inline BOOL operator != ( const SalFontDimension &r ) const;
+ inline BOOL operator >= ( const SalFontDimension &r ) const;
+};
+
+inline SalFontDimension::SalFontDimension( USHORT nA, USHORT nH )
+ : nHeight_( nH ), nAverage_( nA )
+{ nPtHeight_ = nXRes_ = nYRes_ = nSlant_ = 0; }
+
+inline BOOL SalFontDimension::IsScalable() const
+{ return !nHeight_ && !nPtHeight_ && !nAverage_; }
+
+inline Size SalFontDimension::GetSize() const
+{ return Size( (nAverage_ + 5) / 10, nHeight_ ); }
+
+inline void SalFontDimension::SetSize( const Size & rSize )
+{ nAverage_ = (USHORT)rSize.Width() * 10; nHeight_ = (USHORT)rSize.Height(); }
+
+inline BOOL SalFontDimension::operator == ( const SalFontDimension &r ) const
+{ return nHeight_ == r.nHeight_ && (!r.nAverage_ || nAverage_ == r.nAverage_); }
+
+inline BOOL SalFontDimension::operator != ( const SalFontDimension &r ) const
+{ return !(*this == r); }
+
+inline BOOL SalFontDimension::operator >= ( const SalFontDimension &r ) const
+{ return nHeight_ > r.nHeight_
+ || (nHeight_ == r.nHeight_ && nAverage_ >= r.nAverage_); }
+
+// -=-= SalFontStruct =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalFontStruct : public ImplFontMetricData
+{
+ friend class SalDisplay;
+ friend class SalGraphicsData;
+
+ SalFontCacheItem*pCache_;
+
+#if defined DEBUG || defined DBG_UTIL
+ ByteString aFontName_;
+#endif
+ USHORT nHeightCount_; // Anzahl der Hoehen-Eintraege
+ SalFontDimension*pDimensions_; // Hoehen-Array
+ USHORT nWeight_;
+
+ USHORT nFoundry_; // properties indexies
+ USHORT nFamily_;
+ USHORT nWeightName_;
+ USHORT nSlant_;
+ USHORT nSetWidthName_;
+ ByteString aAddStyleName_;
+ USHORT nSpacing_;
+ USHORT nCharSet_;
+ USHORT nFaceName_;
+ BOOL mbValidFontDescription; // valid xlfd entries
+
+ void Init();
+ BOOL Init( SalDisplay* pDisp,
+ const char* pFontName,
+ SalFontDimension& rDim );
+
+ ByteString GetXFontName( const SalFontDimension& );
+
+ inline void SetFoundry( USHORT n )
+ { nFoundry_ = n; }
+ inline void SetFamily( USHORT n )
+ { meFamily = sal_FamilyToSal( nFamily_ = n ); }
+ inline void SetWeightName( USHORT n )
+ { meWeight = sal_WeightToSal( nWeightName_ = n ); }
+ inline void SetSlant( USHORT n )
+ { meItalic = sal_ItalicToSal( nSlant_ = n ); }
+ inline void SetSetWidthName( USHORT n )
+ { nSetWidthName_ = n; }
+ inline void SetAddStyleName( const ByteString& rAddStyle )
+ { aAddStyleName_ = rAddStyle; aAddStyleName_.ToLowerAscii(); }
+ inline void SetSpacing( USHORT n )
+ { mePitch = sal_PitchToSal( nSpacing_ = n ); }
+ inline void SetAverage( long n )
+ { mnWidth = (n + 5) / 10; }
+ void SetCharSet( USHORT n );
+
+ SalFontStruct( const SalFontStruct& rFont );
+public:
+ SalFontStruct( SalDisplay* pDisp,
+ const char* pFontName,
+ SalFontDimension& rDim );
+
+ ~SalFontStruct();
+
+ inline void Cache( SalFontCacheItem *p ) { pCache_ = p; }
+ inline SalFontCacheItem*IsCache() const { return pCache_; }
+ inline BOOL IsScalable() const { return TYPE_SCALABLE==meType; }
+ inline SalFontDimension*GetDim() const { return pDimensions_; }
+ inline BOOL IsValid() const { return mbValidFontDescription; }
+#ifdef DBG_UTIL
+ const ByteString& GetName() const { return aFontName_; }
+#endif
+
+ ImplFontData *GetDevFontData();
+ SalFontCacheItem*Load( SalDisplay *pDisp, const SalFontDimension &rDim );
+ CharSet GetCharSet() { return meCharSet; }
+
+};
+
+// -=-= SalFontStructList =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+DECLARE_LIST( SalFontStructList, SalFontStruct* )
+
+#endif // _SV_SALFONT_H
+
diff --git a/vcl/unx/inc/salframe.h b/vcl/unx/inc/salframe.h
new file mode 100644
index 000000000000..f9bd325556e6
--- /dev/null
+++ b/vcl/unx/inc/salframe.h
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * $RCSfile: salframe.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+//-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+// //
+// (C) 1997 Star Division GmbH, Hamburg, Germany //
+// //
+// $Revision: 1.1.1.1 $ $Author: hr $ $Date: 2000-09-18 17:05:41 $ //
+// //
+// $Workfile: salframe.h $ //
+// $Modtime: 09 Sep 1997 17:29:12 $ //
+// //
+//-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+
+#ifndef _SV_SALFRAME_H
+#define _SV_SALFRAME_H
+
+// -=-= #includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+#ifndef _SALSTD_HXX
+#include <salstd.hxx>
+#endif
+#ifndef _SV_SALWTYPE_HXX
+#include <salwtype.hxx>
+#endif
+#ifndef _SV_PTRSTYLE_HXX
+#include <ptrstyle.hxx>
+#endif
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+#include <salunx.h>
+
+// -=-= forwards -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalDisplay;
+class SalGraphics;
+class SalFrame;
+class SalColormap;
+class SalI18N_InputContext;
+
+// -=-= SalFrameData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+DECLARE_LIST( SalFrameList, SalFrame *);
+class SalFrameData
+{
+ friend class SalFrame;
+ friend SalFrame* SalInstance::CreateFrame( SalFrame*, ULONG );
+ friend SalFrame* SalInstance::CreateChildFrame( SystemParentData*, ULONG );
+
+ static Bool checkKeyReleaseForRepeat( Display*, XEvent*, XPointer pSalFrameData );
+
+ STDAPI( SalFrameData )
+
+ SalFrame *pNextFrame_; // pointer to next frame
+ SalFrame *pFrame_;
+
+ SalFrame* mpParent; // pointer to parent frame
+ // which should never obscur this frame
+ SalFrameList maChildren; // List of child frames
+
+ SALFRAMEPROC pProc_; // callback proc
+ void *pInst_; // instance handle for callback
+
+ SalDisplay *pDisplay_;
+ Widget hShell_;
+ Widget hComposite_;
+ XLIB_Window hForeignParent_;
+ XLIB_Window hForeignTopLevelWindow_;
+ Widget hNoFullscreenShell_;
+ Widget hNoFullscreenComposite_;
+ // window to fall back to when no longer in fullscreen mode
+
+ XLIB_Cursor hCursor_;
+ int nCaptured_; // is captured
+
+ SalGraphics *pGraphics_; // current frame graphics
+ SalGraphics *pFreeGraphics_; // first free frame graphics
+ XLIB_Region pPaintRegion_;
+
+ XLIB_Time nReleaseTime_; // timestamp of last key release
+ USHORT nKeyCode_; // last key code
+ USHORT nKeyState_; // last key state
+ int nCompose_; // compose state
+
+ int nShowState_; // show state
+ int nLeft_; // left decoration size
+ int nTop_; // top decoration size
+ int nRight_; // right decoration size
+ int nBottom_; // bottom decoration size
+ int nMaxWidth_; // client max width
+ int nMaxHeight_; // client max height
+ int nWidth_; // client width
+ int nHeight_; // client height
+ Rectangle aPosSize_; // Shells Pos&Size
+ Rectangle aRestoreFullScreen_;
+ Rectangle aRestoreMaximize_;
+ USHORT nStyle_;
+ BOOL bAlwaysOnTop_;
+ BOOL bViewable_;
+ BOOL bMapped_;
+ BOOL bDefaultPosition_; // client is centered initially
+ int nVisibility_;
+
+ int nScreenSaversTimeout_;
+
+ SystemChildData maSystemChildData;
+
+ SalI18N_InputContext *mpInputContext;
+
+ SalGraphics *GetGraphics();
+
+ void GetPosSize( Rectangle &rPosSize );
+ void SetSize ( const Size &rSize );
+ void SetPosSize( const Rectangle &rPosSize );
+ void Minimize();
+ void Maximize();
+ void Restore();
+ void ShowFullScreen( BOOL bFullScreen );
+
+ void RepositionFloatChildren();
+
+ long HandleKeyEvent ( XKeyEvent *pEvent );
+ long HandleMouseEvent ( XEvent *pEvent );
+ long HandleFocusEvent ( XFocusChangeEvent *pEvent );
+ long HandleExposeEvent ( XEvent *pEvent );
+ long HandleSizeEvent ( XConfigureEvent *pEvent );
+ long HandleColormapEvent ( XColormapEvent *pEvent );
+ long HandleMapUnmapEvent ( XEvent *pEvent );
+ long HandleStateEvent ( XPropertyEvent *pEvent );
+ long HandleReparentEvent ( XReparentEvent *pEvent );
+ long HandleClientMessage ( XClientMessageEvent*pEvent );
+
+ inline void CaptureMouse( BOOL bCapture );
+ inline void SetPointer( PointerStyle ePointerStyle );
+
+ inline SalFrameData( SalFrame *pFrame );
+ inline ~SalFrameData();
+public:
+ long Dispatch( XEvent *pEvent );
+ void Init( USHORT nSalFrameStyle, SystemParentData* pParentData = NULL );
+
+ SalDisplay *GetDisplay() const { return pDisplay_; }
+ inline Display *GetXDisplay() const;
+ inline XLIB_Window GetDrawable() const;
+ inline XLIB_Window GetWindow() const { return XtWindow( hComposite_ ); }
+ inline Widget GetWidget() const { return hComposite_; }
+ inline XLIB_Window GetShellWindow() const { return XtWindow( hShell_ ); }
+ inline Widget GetShellWidget() const { return hShell_; }
+ inline XLIB_Window GetForeignParent() const { return hForeignParent_; }
+ inline XLIB_Window GetForeignTopLevelWindow() const { return hForeignTopLevelWindow_; }
+ inline long ShutDown() const
+ { return pProc_( pInst_, pFrame_, SALEVENT_SHUTDOWN, 0 ); }
+ inline long Close() const
+ { return pProc_( pInst_, pFrame_, SALEVENT_CLOSE, 0 ); }
+ inline long Call( USHORT nEvent, const void *pEvent ) const
+ { return pProc_( pInst_, pFrame_, nEvent, pEvent ); }
+ inline SalFrame *GetNextFrame() const { return pNextFrame_; }
+ inline XLIB_Cursor GetCursor() const { return hCursor_; }
+ inline BOOL IsCaptured() const { return nCaptured_ == 1; }
+ inline BOOL IsWaitingForExpose() const
+ { return !!pPaintRegion_; }
+ inline SalColormap &GetColormap() const;
+};
+
+#ifdef _SV_SALDISP_HXX
+
+inline void SalFrameData::CaptureMouse( BOOL bCapture )
+{ nCaptured_ = pDisplay_->CaptureMouse( bCapture ? this : NULL ); }
+
+inline Display *SalFrameData::GetXDisplay() const
+{ return pDisplay_->GetDisplay(); }
+
+inline XLIB_Window SalFrameData::GetDrawable() const
+{ return GetWindow(); }
+
+inline SalColormap &SalFrameData::GetColormap() const
+{ return pDisplay_->GetColormap(); }
+
+#endif
+
+#endif // _SV_SALFRAME_H
+
diff --git a/vcl/unx/inc/salgdi.h b/vcl/unx/inc/salgdi.h
new file mode 100644
index 000000000000..eaa0651a3cd7
--- /dev/null
+++ b/vcl/unx/inc/salgdi.h
@@ -0,0 +1,320 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+// *=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+// //
+// (C) 1997 Star Division GmbH, Hamburg, Germany //
+// //
+// $Revision: 1.1.1.1 $ $Author: hr $ $Date: 2000-09-18 17:05:41 $ //
+// //
+// $Workfile: salgdi.h $ //
+// $Modtime: 10 Sep 1997 11:55:36 $ //
+// //
+// *=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+
+#ifndef _SV_SALGDI_H
+#define _SV_SALGDI_H
+
+// -=-= exports -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+class SalFontCacheItem;
+class SalGraphicsContext;
+class SalGraphicsData;
+
+// -=-= includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef _SALSTD_HXX
+#include <salstd.hxx>
+#endif
+#ifndef _SV_SALGTYPE_HXX
+#include <salgtype.hxx>
+#endif
+#ifndef _FRACT_HXX
+#include <tools/fract.hxx>
+#endif
+
+#include "xfont.hxx"
+
+// -=-= forwards -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+struct ImplFontMetricData;
+struct ImplFontSelectData;
+class SalBitmap;
+class SalColormap;
+class SalDisplay;
+class SalFrame;
+class SalVirtualDevice;
+class SalPolyLine;
+
+#ifndef _SV_SALDISP_HXX
+typedef SalColormap *SalColormapRef;
+#endif
+
+// -=-= SalGraphicsData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+class SalGraphicsData
+{
+ friend class SalGraphics;
+
+ STDAPI( SalGraphicsData )
+
+ SalColormapRef xColormap_;
+ Drawable hDrawable_; // use
+
+ XLIB_Region pPaintRegion_;
+ XLIB_Region pClipRegion_;
+
+ GC pPenGC_; // Pen attributes
+ SalColor nPenColor_;
+ Pixel nPenPixel_;
+
+ GC pFontGC_; // Font attributes
+ ExtendedFontStructRef xFont_;
+ Fraction aScale_;
+ SalColor nTextColor_;
+ Pixel nTextPixel_;
+ short nFontOrientation_;
+
+ GC pBrushGC_; // Brush attributes
+ SalColor nBrushColor_;
+ Pixel nBrushPixel_;
+ Pixmap hBrush_; // Dither
+
+ GC pMonoGC_;
+ GC pCopyGC_;
+ GC pMaskGC_;
+ GC pInvertGC_;
+ GC pInvert50GC_;
+ GC pStippleGC_;
+ GC pTrackingGC_;
+
+ BOOL bWindow_ : 1; // is Window
+ BOOL bPrinter_ : 1; // is Printer
+ BOOL bVirDev_ : 1; // is VirDev
+ BOOL bPenGC_ : 1; // is Pen GC valid
+ BOOL bFontGC_ : 1; // is Font GC valid
+ BOOL bBrushGC_ : 1; // is Brush GC valid
+ BOOL bMonoGC_ : 1; // is Mono GC valid
+ BOOL bCopyGC_ : 1; // is Copy GC valid
+ BOOL bInvertGC_ : 1; // is Invert GC valid
+ BOOL bInvert50GC_ : 1; // is Invert50 GC valid
+ BOOL bStippleGC_ : 1; // is Stipple GC valid
+ BOOL bTrackingGC_ : 1; // is Tracking GC valid
+ BOOL bXORMode_ : 1; // is ROP XOR Mode set
+ BOOL bDitherBrush_ : 1; // is solid or tile
+
+ void SetClipRegion( GC pGC,
+ XLIB_Region pXReg = NULL ) const;
+
+
+#if defined(_SV_SALGDI_CXX) || defined (_SV_SALGDI2_CXX)
+ GC GetTrackingGC();
+ GC GetInvertGC();
+ GC GetInvert50GC();
+ GC CreateGC( Drawable hDrawable,
+ unsigned long nMask = GCGraphicsExposures );
+#endif
+
+#if defined _SV_SALGDI_CXX
+ GC SelectPen();
+ GC SelectBrush();
+ void DrawLines( ULONG nPoints,
+ const SalPolyLine &rPoints,
+ GC pGC );
+ BOOL GetDitherPixmap ( SalColor nSalColor );
+#endif
+
+#if defined _SV_SALGDI2_CXX
+
+ inline GC GetMonoGC( Pixmap hPixmap );
+ inline GC GetCopyGC();
+ inline GC GetStippleGC();
+
+ int Clip ( XLIB_Region pRegion,
+ int &nX,
+ int &nY,
+ unsigned int &nDX,
+ unsigned int &nDY,
+ int &nSrcX,
+ int &nSrcY ) const;
+ int Clip ( int &nX,
+ int &nY,
+ unsigned int &nDX,
+ unsigned int &nDY,
+ int &nSrcX,
+ int &nSrcY ) const;
+ GC SetMask ( int &nX,
+ int &nY,
+ unsigned int &nDX,
+ unsigned int &nDY,
+ int &nSrcX,
+ int &nSrcY,
+ Pixmap hClipMask );
+ void DrawBitmap( const SalTwoRect *pPosAry,
+ SalGraphics *pThis,
+ const SalBitmap &rSalBitmap,
+ const SalBitmap &rTransparentBitmap,
+ SalColor nTransparentColor );
+#endif
+
+#if defined _SV_SALGDI3_CXX
+ GC SelectFont();
+
+ void SetFont( const ImplFontSelectData* pEntry );
+ void DrawText( long nX,
+ long nY,
+ const xub_Unicode* pStr,
+ USHORT nLen,
+ const long* pDXAry );
+ void DrawText( long nX,
+ long nY,
+ const xub_Unicode* pStr,
+ USHORT nLen );
+#endif
+public:
+ SalGraphicsData();
+ ~SalGraphicsData();
+
+ void Init( SalFrame *pFrame );
+ void Init( SalVirtualDevice *pVirtualDevice,
+ SalGraphics *pSalGraphics );
+ void Init( class ImplSalPrinterData *pPrinter );
+ void DeInit();
+
+ inline SalDisplay *GetDisplay() const;
+ inline Display *GetXDisplay() const;
+ inline Drawable GetDrawable() const { return hDrawable_; }
+ inline void SetDrawable( Drawable d ) { hDrawable_ = d; }
+ inline SalColormap &GetColormap() const { return *xColormap_; }
+ inline BOOL IsCompatible( USHORT nDepth,
+ SalColormap *pMap ) const;
+ inline Pixel GetPixel( SalColor nSalColor ) const;
+};
+
+#ifdef _SV_SALDATA_HXX
+
+inline SalDisplay *SalGraphicsData::GetDisplay() const
+{ return GetColormap().GetDisplay(); }
+
+inline Display *SalGraphicsData::GetXDisplay() const
+{ return GetColormap().GetXDisplay(); }
+
+inline BOOL SalGraphicsData::IsCompatible( USHORT nDepth,
+ SalColormap *pMap ) const
+{
+ return (GetDisplay()->GetImageDepths() & (1 << (nDepth-1))) != 0
+ && &xColormap_ == pMap;
+}
+
+inline Pixel SalGraphicsData::GetPixel( SalColor nSalColor ) const
+{ return GetColormap().GetPixel( nSalColor ); }
+
+#endif
+
+// -=-= Shortcuts =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#if defined _SV_SALGDI_CXX || defined _SV_SALGDI2_CXX || defined _SV_SALGDI3_CXX
+#define _GetXDisplay() maGraphicsData.GetXDisplay()
+#define _GetDisplay() maGraphicsData.GetDisplay()
+#define _GetVisual() maGraphicsData.GetDisplay()->GetVisual()
+#define _GetDrawable() maGraphicsData.hDrawable_
+#define _GetColormap() maGraphicsData.GetColormap()
+#define _GetClipRegion() maGraphicsData.pClipRegion_
+#define _GetPenPixel() maGraphicsData.nPenPixel_
+#define _GetTextPixel() maGraphicsData.nTextPixel_
+#define _GetBrushPixel() maGraphicsData.nBrushPixel_
+#define _GetPenColor() maGraphicsData.nPenColor_
+#define _GetTextColor() maGraphicsData.nTextColor_
+#define _GetBrushColor() maGraphicsData.nBrushColor_
+#define _GetPixel(n) maGraphicsData.GetPixel( n )
+#define _GetColor(n) maGraphicsData.GetColormap().GetColor( n )
+#define _IsPenGC() maGraphicsData.bPenGC_
+#define _IsFontGC() maGraphicsData.bFontGC_
+#define _IsBrushGC() maGraphicsData.bBrushGC_
+#define _IsMonoGC() maGraphicsData.bMonoGC_
+#define _IsCopyGC() maGraphicsData.bCopyGC_
+#define _IsInvertGC() maGraphicsData.bInvertGC_
+#define _IsInvert50GC() maGraphicsData.bInvert50GC_
+#define _IsStippleGC() maGraphicsData.bStippleGC_
+#define _IsTrackingGC() maGraphicsData.bTrackingGC_
+#define _IsXORMode() maGraphicsData.bXORMode_
+#define _IsWindow() maGraphicsData.bWindow_
+#define _IsPrinter() maGraphicsData.bPrinter_
+#define _IsVirtualDevice() maGraphicsData.bVirDev_
+#define _IsDitherBrush() maGraphicsData.bDitherBrush_
+#define _SelectPen() maGraphicsData.SelectPen()
+#define _SelectBrush() maGraphicsData.SelectBrush()
+#define _GetTrackingGC() maGraphicsData.GetTrackingGC()
+#endif
+
+#ifdef DBG_UTIL
+#define stderr0( s ) fprintf( stderr, s )
+#define stderr1( s, a ) fprintf( stderr, s, a )
+#define stderr2( s, a, b ) fprintf( stderr, s, a, b )
+#define stderr3( s, a, b, c ) fprintf( stderr, s, a, b, c )
+#define stdass0( b ) (void)( !(b) \
+ ? fprintf( stderr, "\"%s\" (%s line %d)\n", \
+ #b, __FILE__, __LINE__ ) \
+ : 0 )
+#else
+#define stderr0( s ) nop
+#define stderr1( s, a ) nop
+#define stderr2( s, a, b ) nop
+#define stderr3( s, a, b, c ) nop
+#define stdass0( b ) nop
+#endif
+#endif // _SV_SALGDI_H
+
diff --git a/vcl/unx/inc/salinst.h b/vcl/unx/inc/salinst.h
new file mode 100644
index 000000000000..88d471eeae6d
--- /dev/null
+++ b/vcl/unx/inc/salinst.h
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+// //
+// (C) 1997 Star Division GmbH, Hamburg, Germany //
+// //
+// $Revision: 1.1.1.1 $ $Author: hr $ $Date: 2000-09-18 17:05:41 $ //
+// //
+// $Workfile: salinst.h $ //
+// $Modtime: 17 Jul 1997 17:21:10 $ //
+// //
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+
+// -=-= includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef _SV_SALINST_H
+#define _SV_SALINST_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+#ifndef _VOS_THREAD_HXX
+#include <vos/thread.hxx>
+#endif
+
+class SalYieldMutex : public NAMESPACE_VOS(OMutex)
+{
+ ULONG mnCount;
+ NAMESPACE_VOS(OThread)::TThreadIdentifier mnThreadId;
+
+public:
+ SalYieldMutex();
+
+ virtual void acquire();
+ virtual void release();
+ virtual sal_Bool tryToAcquire();
+
+ ULONG GetAcquireCount() const { return mnCount; }
+ NAMESPACE_VOS(OThread)::TThreadIdentifier GetThreadId() const { return mnThreadId; }
+};
+
+// -=-= SalInstanceData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalInstanceData
+{
+ friend class SalInstance;
+
+public:
+
+ void* mpFilterInst;
+ void* mpFilterCallback;
+ SalYieldMutex* mpSalYieldMutex;
+};
+
+#endif // _SV_SALINST_H
+
diff --git a/vcl/unx/inc/salobj.h b/vcl/unx/inc/salobj.h
new file mode 100644
index 000000000000..6e0823261644
--- /dev/null
+++ b/vcl/unx/inc/salobj.h
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * $RCSfile: salobj.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALOBJ_H
+#define _SV_SALOBJ_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+
+
+// -----------------
+// - SalObjectData -
+// -----------------
+
+class SalObject;
+
+DECLARE_LIST( SalObjectList, SalObject* );
+
+class SalClipRegion
+{
+
+public:
+
+ SalClipRegion();
+ ~SalClipRegion();
+
+ void BeginSetClipRegion( ULONG nRects );
+ void UnionClipRegion( long nX, long nY, long nWidth, long nHeight );
+
+ XRectangle *EndSetClipRegion() {
+ return ClipRectangleList; }
+ void ResetClipRegion() {
+ numClipRectangles = 0; }
+ USHORT GetClipRegionType() {
+ return nClipRegionType; }
+ void SetClipRegionType( USHORT nType ) {
+ nClipRegionType = nType; }
+ int GetRectangleCount() {
+ return numClipRectangles; }
+
+private:
+
+ XRectangle* ClipRectangleList;
+ int numClipRectangles;
+ int maxClipRectangles;
+ USHORT nClipRegionType;
+};
+
+
+class SalObjectData
+{
+ friend class SalObject;
+ friend class SalDisplay;
+ friend class SalInstance;
+
+ static SalObjectList aAllObjects;
+
+ SystemChildData maSystemChildData;
+ Widget maPrimary;
+ Widget maSecondary;
+ SalClipRegion maClipRegion;
+ void* mpInst;
+ SALOBJECTPROC mpProc;
+ SalObject* mpSalObject;
+ BOOL mbVisible;
+
+ static long Dispatch( XEvent* pEvent );
+};
+
+#endif // _SV_SALOBJ_H
diff --git a/vcl/unx/inc/salprn.h b/vcl/unx/inc/salprn.h
new file mode 100644
index 000000000000..d51174f52f72
--- /dev/null
+++ b/vcl/unx/inc/salprn.h
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * $RCSfile: salprn.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALPRN_H
+#define _SV_SALPRN_H
+
+#ifndef _SALSTD_HXX
+#include <salstd.hxx>
+#endif
+
+#ifndef _SV_PRNTYPES_HXX
+#include <prntypes.hxx>
+#endif
+
+#include <ppdparser.hxx>
+
+// forward declarations
+class SalInfoPrinter;
+
+class SalPrinterQueueInfo;
+class ImplJobSetup;
+
+class ImplSalPrinterData;
+
+
+// class declarations
+
+
+class SalInfoPrinterData
+{
+ friend class SalInfoPrinter;
+ friend class SalPrinterData;
+
+ ImplSalPrinterData* mpImplData;
+
+ inline SalInfoPrinterData();
+ inline ~SalInfoPrinterData();
+
+public:
+
+ inline void Init( SalPrinterQueueInfo* pQueueInfo,
+ ImplJobSetup* pJobSetup);
+};
+
+
+// -=-= SalPrinterData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+class SalPrinterData
+{
+ friend class SalPrinter;
+
+ ImplSalPrinterData* mpImplData;
+
+ BOOL mbJobStarted; // is job started
+ BOOL mbPageStarted; // is page started
+ XubString* mpFileName; // print to file
+ int mnError; // error code
+ BOOL mbAbort:1; // is job aborted
+ BOOL mbFirstPage:1; // false after first startpage
+ int mnDelTime; // time in h to wait before disposing temp file
+
+ inline SalPrinterData();
+ inline ~SalPrinterData();
+
+public:
+ inline void Init( SalInfoPrinter* pInfoPrinter );
+};
+
+
+// necessary to get changes in Xpdefaults
+void StartPrinterListening();
+void StopPrinterListening();
+
+#endif // _SV_SALPRN_H
+
+
diff --git a/vcl/unx/inc/salstd.hxx b/vcl/unx/inc/salstd.hxx
new file mode 100644
index 000000000000..dea0c8f4fd9b
--- /dev/null
+++ b/vcl/unx/inc/salstd.hxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * $RCSfile: salstd.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SALSTD_HXX
+#define _SALSTD_HXX
+
+// -=-= includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef _REF_HXX
+#include <tools/ref.hxx>
+#endif
+#ifndef _STRING_HXX
+#include <tools/string.hxx>
+#endif
+#ifndef _GEN_HXX
+#include <tools/gen.hxx>
+#endif
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+// -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef STDAPI
+#define STDAPI(Class) int operator != ( const Class& ) const; \
+ int operator == ( const Class& ) const; \
+ Class &operator = ( const Class& ); \
+ Class( const Class& );
+#endif
+
+// -=-= X-Lib forwards -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef _SVUNX_H
+typedef unsigned long Pixel;
+typedef unsigned long XID;
+typedef unsigned long XLIB_Time;
+typedef unsigned long XtIntervalId;
+
+typedef XID Colormap;
+typedef XID Drawable;
+typedef XID Pixmap;
+typedef XID XLIB_Cursor;
+typedef XID XLIB_Font;
+typedef XID XLIB_Window;
+
+typedef struct _XDisplay Display;
+typedef struct _XGC *GC;
+typedef struct _XImage XImage;
+typedef struct _XRegion *XLIB_Region;
+
+typedef union _XEvent XEvent;
+
+typedef struct _XConfigureEvent XConfigureEvent;
+typedef struct _XReparentEvent XReparentEvent;
+typedef struct _XClientMessageEvent XClientMessageEvent;
+typedef struct _XErrorEvent XErrorEvent;
+
+struct Screen;
+struct Visual;
+struct XColormapEvent;
+struct XFocusChangeEvent;
+struct XFontStruct;
+struct XKeyEvent;
+struct XPropertyEvent;
+struct XTextItem;
+struct XWindowChanges;
+
+#define None 0L
+#endif
+
+#endif
+
diff --git a/vcl/unx/inc/salsys.h b/vcl/unx/inc/salsys.h
new file mode 100644
index 000000000000..8c35029d38e7
--- /dev/null
+++ b/vcl/unx/inc/salsys.h
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * $RCSfile: salsys.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALSYS_H
+#define _SV_SALSYS_H
+
+class DtIntegrator;
+class SalSystemData;
+class SalFrame;
+class SalDisplay;
+
+// -----------------
+// - SalSystemData -
+// -----------------
+
+class SalSystemData
+{
+ friend class SalSystem;
+ private:
+ SalDisplay* m_pSalDisplay;
+ DtIntegrator* m_pDtIntegrator;
+ void CreateDtIntegrator( SalFrame* );
+ public:
+ SalSystemData() : m_pSalDisplay( 0 ) {}
+ ~SalSystemData();
+
+ void SetSalDisplay( SalDisplay * );
+};
+
+
+#endif // _SV_SALSYS_H
diff --git a/vcl/unx/inc/salunx.h b/vcl/unx/inc/salunx.h
new file mode 100644
index 000000000000..14aa26f70945
--- /dev/null
+++ b/vcl/unx/inc/salunx.h
@@ -0,0 +1,190 @@
+/*************************************************************************
+ *
+ * $RCSfile: salunx.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+// //
+// (C) 1997 Star Division GmbH, Hamburg, Germany //
+// //
+// $Revision: 1.1.1.1 $ $Author: hr $ $Date: 2000-09-18 17:05:41 $ //
+// //
+// $Workfile: salunx.h $ //
+// $Modtime: 14 Aug 1997 13:51:48 $ //
+// //
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+
+#ifndef _SALUNX_H
+#define _SALUNX_H
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#if defined SCO || defined LINUX || defined HPUX || defined FREEBSD
+#include <sys/time.h>
+#elif defined NETBSD
+#include <unistd.h>
+#elif defined AIX
+#include <time.h>
+#include <sys/time.h>
+#include <strings.h>
+#elif defined IRIX
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#ifndef _SVUNX_H
+#include <svunx.h>
+#endif
+#ifndef _SALSTD_HXX
+#include <salstd.hxx>
+#endif
+
+// -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#define persist
+#define final
+#define beta
+#define alpha
+#define unknown
+#define nop ((void*)0)
+#define nobreak ((void*)0)
+
+#define capacityof(a) (sizeof(a)/sizeof(*a))
+
+// -=-= inlines =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+inline long Divide( long nDividend, long nDivisor )
+{ return (nDividend + nDivisor/2) / nDivisor; }
+
+inline long DPI( long pixel, long mm )
+{ return Divide( pixel*254, mm*10 ); }
+
+// -=-= timeval =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+inline int operator >= ( const timeval &t1, const timeval &t2 )
+{
+ if( t1.tv_sec == t2.tv_sec )
+ return t1.tv_usec >= t2.tv_usec;
+ return t1.tv_sec > t2.tv_sec;
+}
+
+inline int operator > ( const timeval &t1, const timeval &t2 )
+{
+ if( t1.tv_sec == t2.tv_sec )
+ return t1.tv_usec > t2.tv_usec;
+ return t1.tv_sec > t2.tv_sec;
+}
+
+inline int operator == ( const timeval &t1, const timeval &t2 )
+{
+ if( t1.tv_sec == t2.tv_sec )
+ return t1.tv_usec == t2.tv_usec;
+ return FALSE;
+}
+
+inline timeval &operator -= ( timeval &t1, const timeval &t2 )
+{
+ if( t1.tv_usec < t2.tv_usec )
+ {
+ t1.tv_sec--;
+ t1.tv_usec += 1000000;
+ }
+ t1.tv_sec -= t2.tv_sec;
+ t1.tv_usec -= t2.tv_usec;
+ return t1;
+}
+
+inline timeval &operator += ( timeval &t1, const timeval &t2 )
+{
+ t1.tv_sec += t2.tv_sec;
+ t1.tv_usec += t2.tv_usec;
+ if( t1.tv_usec > 1000000 )
+ {
+ t1.tv_sec++;
+ t1.tv_usec -= 1000000;
+ }
+ return t1;
+}
+
+inline timeval &operator += ( timeval &t1, ULONG t2 )
+{
+ t1.tv_sec += t2 / 1000;
+ t1.tv_usec += t2 ? (t2 % 1000) * 1000 : 500;
+ if( t1.tv_usec > 1000000 )
+ {
+ t1.tv_sec++;
+ t1.tv_usec -= 1000000;
+ }
+ return t1;
+}
+
+inline timeval operator + ( const timeval &t1, const timeval &t2 )
+{
+ timeval t0 = t1;
+ return t0 += t2;
+}
+
+inline timeval operator + ( const timeval &t1, ULONG t2 )
+{
+ timeval t0 = t1;
+ return t0 += t2;
+}
+
+inline timeval operator - ( const timeval &t1, const timeval &t2 )
+{
+ timeval t0 = t1;
+ return t0 -= t2;
+}
+#endif
+
diff --git a/vcl/unx/inc/salvd.h b/vcl/unx/inc/salvd.h
new file mode 100644
index 000000000000..5f51d6009f31
--- /dev/null
+++ b/vcl/unx/inc/salvd.h
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * $RCSfile: salvd.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+// //
+// (C) 1997 Star Division GmbH, Hamburg, Germany //
+// //
+// $Revision: 1.1.1.1 $ $Author: hr $ $Date: 2000-09-18 17:05:41 $ //
+// //
+// $Workfile: salvd.h $ //
+// $Modtime: 09 Aug 1997 00:15:48 $ //
+// //
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+
+#ifndef _SV_SALVD_H
+#define _SV_SALVD_H
+
+// -=-= #includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+#ifndef _SALSTD_HXX
+#include <salstd.hxx>
+#endif
+
+// -=-= forwards -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalDisplay;
+class SalGraphics;
+class SalVirtualDevice;
+
+// -=-= SalVirDevData -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+class SalVirDevData
+{
+ friend class SalVirtualDevice;
+
+ SalDisplay *pDisplay_;
+ SalGraphics *pGraphics_; // current frame graphics
+
+ Pixmap hDrawable_;
+
+ int nDX_;
+ int nDY_;
+ USHORT nDepth_;
+ BOOL bGraphics_; // is Graphics used
+
+ inline SalVirDevData();
+ inline ~SalVirDevData();
+
+public:
+ BOOL Init( SalDisplay *pDisplay,
+ long nDX, long nDY,
+ USHORT nBitCount );
+ inline void InitGraphics( SalVirtualDevice *pVD,
+ SalGraphics *pGraphics );
+
+ inline Display *GetXDisplay() const;
+ inline SalDisplay *GetDisplay() const;
+ inline BOOL IsDisplay() const;
+ inline Pixmap GetDrawable() const { return hDrawable_; }
+ inline USHORT GetDepth() const { return nDepth_; }
+};
+
+#ifdef _SV_SALDISP_HXX
+
+inline void SalVirDevData::InitGraphics( SalVirtualDevice *pVD,
+ SalGraphics *pGraphics )
+{ pGraphics_->maGraphicsData.Init( pVD, pGraphics ); }
+
+inline Display *SalVirDevData::GetXDisplay() const
+{ return pDisplay_->GetDisplay(); }
+
+inline SalDisplay *SalVirDevData::GetDisplay() const
+{ return pDisplay_; }
+
+inline BOOL SalVirDevData::IsDisplay() const
+{ return pDisplay_->IsDisplay(); }
+
+#endif
+
+#endif // _SV_SALVD_H
+
diff --git a/vcl/unx/inc/sm.hxx b/vcl/unx/inc/sm.hxx
new file mode 100644
index 000000000000..aae6fe6311e7
--- /dev/null
+++ b/vcl/unx/inc/sm.hxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * $RCSfile: sm.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _VCL_SM_HXX
+#define _VCL_SM_HXX
+
+#include <salunx.h>
+#include <X11/SM/SMlib.h>
+
+class ICEConnectionObserver
+{
+ static BOOL bIsWatching;
+
+ static void ICEWatchProc( IceConn connection, IcePointer client_data,
+ Bool opening, IcePointer* watch_data );
+public:
+
+ // YieldProcs for SalDisplay
+ static int Pending( int fd, void* data );
+ static int Queued( int fd, void* data );
+ static int HandleEvents( int fd, void* data );
+
+ static void activate();
+ static void deactivate();
+};
+
+class SessionManagerClient
+{
+ static SmcConn aSmcConnection;
+ static char* pClientID;
+
+ static void SaveYourselfProc( SmcConn connection,
+ SmPointer client_data,
+ int save_type,
+ Bool shutdown,
+ int interact_style,
+ Bool fast );
+ static void DieProc( SmcConn connection,
+ SmPointer client_data );
+ static void SaveCompleteProc( SmcConn connection,
+ SmPointer client_data );
+ static void ShutdownCanceledProc( SmcConn connection,
+ SmPointer client_data );
+
+ static char* getPreviousSessionID();
+ static void setPreviousSessionID( const ByteString& );
+public:
+ static void open();
+ static void close();
+
+ static String getExecName();
+ static char* getSessionID() { return pClientID; }
+};
+
+#endif
diff --git a/vcl/unx/inc/soicon.hxx b/vcl/unx/inc/soicon.hxx
new file mode 100644
index 000000000000..d282f5bb5b61
--- /dev/null
+++ b/vcl/unx/inc/soicon.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: soicon.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SV_SOICON_HXX
+#define _SV_SOICON_HXX
+
+class SalDisplay;
+class SalBitmap;
+class Bitmap;
+
+Pixmap GetAppIconPixmap( SalDisplay* );
+Pixmap GetAppIconMask( SalDisplay* );
+
+BOOL ReadXPMFile( Display*, const String&, SalBitmap*&, SalBitmap*& );
+BOOL ReadXBMFile( Display*, const String&, SalBitmap*& );
+
+#endif
diff --git a/vcl/unx/inc/strhelper.hxx b/vcl/unx/inc/strhelper.hxx
new file mode 100644
index 000000000000..dbfce8794143
--- /dev/null
+++ b/vcl/unx/inc/strhelper.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * $RCSfile: strhelper.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SV_STRHELPER_HXX
+#define _SV_STRHELPER_HXX
+#ifndef _STRING_HXX
+#include <tools/string.hxx>
+#endif
+
+String GetCommandLineToken( int, const String& );
+// gets one token of a unix command line style string
+// doublequote, singlequote and singleleftquote protect their respective
+// contents
+
+int GetCommandLineTokenCount( const String& );
+// returns number of tokens (zero if empty or whitespace only)
+
+String WhitespaceToSpace( const String&, BOOL bProtect = TRUE );
+
+#endif
diff --git a/vcl/unx/inc/svsys.h b/vcl/unx/inc/svsys.h
new file mode 100644
index 000000000000..b20e1b39328f
--- /dev/null
+++ b/vcl/unx/inc/svsys.h
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * $RCSfile: svsys.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _SV_SVSYS_H
+#define _SV_SVSYS_H
+
+#ifndef _SVUNX_H
+#include <svunx.h>
+#endif
+
+#endif // _SV_SVSYS_H
diff --git a/vcl/unx/inc/svunx.h b/vcl/unx/inc/svunx.h
new file mode 100644
index 000000000000..5517045a4d9b
--- /dev/null
+++ b/vcl/unx/inc/svunx.h
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * $RCSfile: svunx.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+// //
+// (C) 1997 Star Division GmbH, Hamburg, Germany //
+// //
+// $Revision: 1.1.1.1 $ $Author: hr $ $Date: 2000-09-18 17:05:41 $ //
+// //
+// $Workfile: svunx.h $ //
+// $Modtime: 17 Jul 1997 17:20:22 $ //
+// //
+//*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-//
+
+#ifndef _SVUNX_H
+#define _SVUNX_H
+
+#ifndef _PREX_H
+#include <prex.h>
+#endif
+#ifndef _POSTX_H
+#include <postx.h>
+#endif
+
+#endif
+
diff --git a/vcl/unx/inc/xfont.hxx b/vcl/unx/inc/xfont.hxx
new file mode 100644
index 000000000000..b89612b57e67
--- /dev/null
+++ b/vcl/unx/inc/xfont.hxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * $RCSfile: xfont.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef EXTENDED_FONTSTRUCT_HXX
+#define EXTENDED_FONTSTRUCT_HXX
+
+#ifndef _XLIB_H_
+#include <X11/Xlib.h>
+#endif
+#ifndef _REF_HXX
+#include <tools/ref.hxx>
+#endif
+#ifndef _RTL_TENCINFO_H
+#include <rtl/tencinfo.h>
+#endif
+#ifndef _VCL_VCLENUM_HXX
+#include <vclenum.hxx>
+#endif
+
+typedef unsigned short sal_MultiByte;
+
+class ImplFontMetricData;
+class SalConverterCache;
+class ExtendedXlfd;
+
+class ExtendedFontStruct : public SvRefBase
+{
+ private:
+
+ Display* mpDisplay;
+ unsigned short mnPixelSize;
+ ExtendedXlfd* mpXlfd;
+ XFontStruct** mpXFontStruct;
+ sal_Size mnDefaultWidth;
+
+ int LoadEncoding( rtl_TextEncoding nEncoding );
+ Bool GetFontBoundingBox( XCharStruct *pCharStruct,
+ int *pAscent, int *pDescent ) ;
+
+ sal_Size GetDefaultWidth( SalConverterCache* pCvt );
+ sal_Size GetCharWidth8( sal_Unicode nFrom, sal_Unicode nTo,
+ long *pWidthArray,
+ rtl_TextEncoding nEncoding );
+ sal_Size GetCharWidthUTF16(
+ sal_Unicode nFrom, sal_Unicode nTo,
+ long *pWidthArray );
+ sal_Size GetCharWidth16( SalConverterCache *pCvt,
+ sal_Unicode nFrom, sal_Unicode nTo,
+ long *pWidthArray );
+
+ public:
+ ExtendedFontStruct( Display* pDisplay,
+ unsigned short nPixelSize,
+ ExtendedXlfd* pXlfd,
+ SalConverterCache* pCvt );
+ ~ExtendedFontStruct();
+ Bool Match( const ExtendedXlfd *pXlfd,
+ int nPixelSize) const;
+ XFontStruct* GetFontStruct( rtl_TextEncoding nEncoding );
+ Bool GetFontStruct( sal_Unicode nChar,
+ rtl_TextEncoding *pEncodingInOut,
+ XFontStruct **pFontInOut,
+ SalConverterCache *pCvt );
+ Bool ToImplFontMetricData( ImplFontMetricData *pMetric );
+ rtl_TextEncoding GetAsciiEncoding( int *pAsciiRange = NULL ) const;
+ sal_Size GetCharWidth( SalConverterCache *pCvt,
+ sal_Unicode nFrom, sal_Unicode nTo,
+ long *pWidthArray );
+};
+
+// Declaration and Implementation for ExtendedFontStructRef: Add RefCounting
+// to ExtendedFontStruct (it's not possible to separate decl and impl into
+// a separate source file: all ref member functions are inline
+SV_DECL_IMPL_REF( ExtendedFontStruct );
+
+#endif /* EXTENDED_FONTSTRUCT_HXX */
diff --git a/vcl/unx/inc/xsalprn.h b/vcl/unx/inc/xsalprn.h
new file mode 100644
index 000000000000..f0d0d2951bd8
--- /dev/null
+++ b/vcl/unx/inc/xsalprn.h
@@ -0,0 +1,223 @@
+/*************************************************************************
+ *
+ * $RCSfile: xsalprn.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef __salprint_h
+#define __salprint_h
+
+
+class String;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* printer interface */
+extern int XSalIsDisplay( const Display * );
+extern int XSalIsPrinter( const Display * );
+
+/* error handling */
+typedef int (*XSalPrinterErrorHandler)( XErrorEvent * );
+
+extern XSalPrinterErrorHandler XSalSetPrinterErrorHandler( XSalPrinterErrorHandler );
+
+/* common callbacks */
+typedef void* XSalPointer;
+typedef int (*XSalPrinterCallback)( XSalPointer cb_data, XSalPointer client_data );
+
+#ifndef _SV_SV_H
+#define _SV_SV_H
+#define USHORT unsigned short
+#include <prntypes.hxx>
+#undef USHORT
+#undef _SV_SV_H
+#else
+#include <prntypes.hxx>
+#endif
+
+typedef enum Orientation Orientation;
+
+/* initialize before first use */
+extern void XSalPrinterInit( const String& installPath );
+
+typedef unsigned short XSalEnum;
+typedef unsigned char XSalBool;
+
+#define COLOR_SPACE_COLOR 1
+#define COLOR_SPACE_GRAY 0
+
+typedef struct
+{
+ unsigned int nMagic; /* internal data */
+ unsigned short nVersion; /* internal data */
+ unsigned short nFlags; /* internal data */
+ XSalEnum eDriver; /* PostScript, PCL, ... */
+ unsigned short nCopies; /* number of copies */
+ unsigned short nPaperBin; /* paper bin to use */
+ XSalEnum ePaper; /* A4, A5, ... */
+ unsigned int nPaperWidth; /* paper width if PAPER_USER */
+ unsigned int nPaperHeight; /* paper height if PAPER_USER */
+ XSalEnum eOrientation; /* portrait / landscape */
+ unsigned int nScale; /* [%] ( 100 => 1:1 ) */
+ unsigned short nResolutionX; /* [dots per inch] */
+ unsigned short nResolutionY; /* [dots per inch] */
+ char sCompatCommand[256];/* current shell command */
+ char sPort[256]; /* default shell command */
+ char cDriverName[32]; /* Druckertreibername */
+ unsigned int nTrailingBytes; /* trailing bytes appended to this structure */
+} XSalPrinterSetup;
+
+#define XSAL_PRINTER_SETUP_MAGIC 0x0000ede1
+#define WRONG_ENDIANESS_MAGIC 0xe1ed0000
+
+/* definition for XSalPrinterSetup.nFlags */
+#define XSALPRINTERSETUP_FLAG_LEVEL_DEFAULT 0x0000
+#define XSALPRINTERSETUP_FLAG_LEVEL 0x000f
+#define XSALPRINTERSETUP_FLAG_LEVEL_SHIFT 0
+#define XSALPRINTERSETUP_FLAG_COLOR 0x0010 /* colored bitmaps */
+#define XSALPRINTERSETUP_FLAG_COLOR_DEFAULT 0x0020
+#define XSALPRINTERSETUP_FLAG_COMPRESS 0x0040 /* compress bitmaps */
+#define XSALPRINTERSETUP_FLAG_COMPRESS_DEFAULT 0x0080 /* compress bitmaps */
+#define XSALPRINTERSETUP_FLAG_DEPTH_DEFAULT 0x0700
+#define XSALPRINTERSETUP_FLAG_DEPTH 0x0700 /* depth n = depth 2^n, 6 = 24Bit, 7 = default */
+#define XSALPRINTERSETUP_FLAG_DEPTH_SHIFT 8
+
+#define XSALPRINTERSETUP_FLAG_DEFAULT\
+ (XSALPRINTERSETUP_FLAG_LEVEL_DEFAULT | \
+ XSALPRINTERSETUP_FLAG_COMPRESS_DEFAULT | \
+ XSALPRINTERSETUP_FLAG_COLOR_DEFAULT | \
+ XSALPRINTERSETUP_FLAG_DEPTH_DEFAULT )
+
+
+/* XSalPrinterSetup access */
+extern unsigned short XSalGetPrinterDriverId( const char* driverName );
+extern const char* XSalGetPrinterDriverName( unsigned short driverId );
+
+extern unsigned short XSalGetLanguageLevel( const XSalPrinterSetup* pSetup );
+extern void XSalGetLanguageLevels(
+ const XSalPrinterSetup* pSetup,
+ unsigned short* minLevel,
+ unsigned short* maxLevel );
+extern void XSalSetLanguageLevel( XSalPrinterSetup* pSetup, unsigned short);
+
+extern unsigned short XSalGetDepth( const XSalPrinterSetup* pSetup );
+extern void XSalSetDepth( XSalPrinterSetup* pSetup, unsigned short depth );
+
+extern XSalEnum XSalGetColorSpace( const XSalPrinterSetup* pSetup );
+extern void XSalSetColorSpace( XSalPrinterSetup* pSetup, XSalEnum space );
+
+extern XSalBool XSalGetBmpCompression( const XSalPrinterSetup* pSetup );
+extern void XSalSetBmpCompression( XSalPrinterSetup* pSetup, XSalBool compress );
+
+extern XSalEnum XSalGetOrientation( const char* string );
+extern const char* XSalGetOrientationName( XSalEnum eOrientation );
+
+extern XSalEnum XSalGetPaper( const char* sPaperName );
+extern const char* XSalGetPaperName( XSalEnum ePaper );
+
+/* use XSalInitPrinterSetup to initialize internal data */
+extern void XSalInitPrinterSetup( XSalPrinterSetup* );
+extern void XSalCorrectEndianess( XSalPrinterSetup* );
+extern void XSalSetupPrinterSetup( XSalPrinterSetup*, Display* display, XLIB_Window parent);
+
+
+/* the following two functions set defaults of the profile */
+extern void XSalReadPrinterSetup( XSalPrinterSetup*, const String& rPrinter );
+extern void XSalReadPrinterSetupDefaults( XSalPrinterSetup* );
+
+
+typedef Display XSalPrinter; /* an XSalPrinter is a Display. Draw into RootWindow */
+
+
+/* open, change setup and close printer */
+extern XSalPrinter* XSalOpenPrinter( const XSalPrinterSetup * pSetup, const String& rPrinterName, const String& rPrintFile );
+/* XSalSetupPrinter() can setup: Orientation, Copies, Page, PaperBin */
+extern void XSalSetupPrinter( XSalPrinter *, const XSalPrinterSetup * pSetup );
+extern void XSalClosePrinter( XSalPrinter * );
+
+typedef struct
+{
+ int nWidth; /* [dots] drawable area */
+ int nHeight; /* [dots] drawable area */
+ int nMarginLeft; /* [dots] left margin */
+ int nMarginTop; /* [dots] top margin */
+ int nMarginRight; /* [dots] right margin */
+ int nMarginBottom; /* [dots] bottom margin */
+ int nResolutionX; /* [dpi] resolution x */
+ int nResolutionY; /* [dpi] resolution y */
+} XSalPageInfo;
+
+extern void XSalGetPageInfo(
+ const XSalPrinter* printer,
+ const XSalPrinterSetup* pSetup,
+ XSalPageInfo* pPageInfo );
+
+
+/* printer job control */
+extern int XSalStartDoc( XSalPrinter * printer, const String& jobName );
+extern int XSalStartPage( XSalPrinter * printer );
+extern int XSalEndPage( XSalPrinter * printer );
+extern int XSalEndDoc( XSalPrinter * printer );
+extern int XSalAbortDoc( XSalPrinter * printer );
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/vcl/unx/source/app/i18n_cb.cxx b/vcl/unx/source/app/i18n_cb.cxx
new file mode 100644
index 000000000000..434b356054fd
--- /dev/null
+++ b/vcl/unx/source/app/i18n_cb.cxx
@@ -0,0 +1,547 @@
+/*************************************************************************
+ *
+ * $RCSfile: i18n_cb.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#ifdef SOLARIS
+#include <alloca.h>
+#endif
+#include <prex.h>
+#include <X11/Xlocale.h>
+#include <X11/Xlib.h>
+#include <postx.h>
+
+#include <salunx.h>
+#include "XIM.h"
+
+#ifndef _SAL_I18N_CALLBACK_HXX
+#include "i18n_cb.hxx"
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+
+// -------------------------------------------------------------------------
+//
+// i. preedit start callback
+//
+// -------------------------------------------------------------------------
+
+int
+PreeditStartCallback ( XIC ic, XPointer client_data, XPointer call_data )
+{
+ #define PREEDIT_BUFSZ 16
+
+ preedit_data_t* pPreeditData = (preedit_data_t*)client_data;
+
+ if ( pPreeditData->eState == ePreeditStatusActivationRequired )
+ {
+ pPreeditData->eState = ePreeditStatusActive;
+
+ pPreeditData->aText.pUnicodeBuffer =
+ (sal_Unicode*)malloc(PREEDIT_BUFSZ * sizeof(sal_Unicode));
+ pPreeditData->aText.pCharStyle =
+ (XIMFeedback*)malloc(PREEDIT_BUFSZ * sizeof(XIMFeedback));
+ pPreeditData->aText.nCursorPos = 0;
+ pPreeditData->aText.nLength = 0;
+ pPreeditData->aText.nSize = PREEDIT_BUFSZ;
+
+ pPreeditData->pFrame->maFrameData.Call(SALEVENT_STARTEXTTEXTINPUT,
+ (void*)NULL );
+ }
+
+ return -1;
+}
+
+// -------------------------------------------------------------------------
+//
+// ii. preedit done callback
+//
+// -------------------------------------------------------------------------
+
+void
+PreeditDoneCallback ( XIC ic, XPointer client_data, XPointer call_data )
+{
+ preedit_data_t* pPreeditData = (preedit_data_t*)client_data;
+
+ if (pPreeditData->eState == ePreeditStatusActive )
+ pPreeditData->pFrame->maFrameData.Call(
+ SALEVENT_ENDEXTTEXTINPUT, (void*)NULL );
+ pPreeditData->eState = ePreeditStatusStartPending;
+
+ if ( pPreeditData->aText.pUnicodeBuffer != NULL )
+ {
+ free (pPreeditData->aText.pUnicodeBuffer);
+ pPreeditData->aText.pUnicodeBuffer = NULL;
+ }
+ if ( pPreeditData->aText.pCharStyle != NULL )
+ {
+ free (pPreeditData->aText.pCharStyle);
+ pPreeditData->aText.pCharStyle = NULL;
+ }
+}
+
+// -------------------------------------------------------------------------
+//
+// iii. preedit draw callback
+//
+// -------------------------------------------------------------------------
+
+//
+// Handle deletion of text in a preedit_draw_callback
+// from and howmuch are guaranteed to be nonnegative
+//
+
+void
+Preedit_DeleteText(preedit_text_t *ptext, int from, int howmuch)
+{
+ int to = from + howmuch;
+
+ if (to == ptext->nLength)
+ {
+ // delete from the end of the text
+ ptext->nLength = from;
+ }
+ else
+ if (to < ptext->nLength)
+ {
+ // cut out of the middle of the text
+ memmove( (void*)(ptext->pUnicodeBuffer + from),
+ (void*)(ptext->pUnicodeBuffer + to),
+ (ptext->nLength - to) * sizeof(sal_Unicode));
+ memmove( (void*)(ptext->pCharStyle + from),
+ (void*)(ptext->pCharStyle + to),
+ (ptext->nLength - to) * sizeof(sal_Unicode));
+ ptext->nLength -= howmuch;
+ }
+ else
+ // if ( to > pText->nLength )
+ {
+ // XXX this indicates an error, are we out of sync ?
+ fprintf(stderr, "Preedit_DeleteText( from=%i to=%i length=%i )\n",
+ from, to, ptext->nLength );
+ fprintf (stderr, "\t XXX internal error, out of sync XXX\n");
+
+ ptext->nLength = from;
+ }
+
+ // NULL-terminate the string
+ ptext->pUnicodeBuffer[ptext->nLength] = (sal_Unicode)0;
+}
+
+// reallocate the textbuffer with sufficiently large size 2^x
+// nnewlimit is presupposed to be larger than ptext->size
+void
+enlarge_buffer ( preedit_text_t *ptext, int nnewlimit )
+{
+ size_t nnewsize = ptext->nSize;
+
+ while ( nnewsize <= nnewlimit )
+ nnewsize *= 2;
+
+ ptext->nSize = nnewsize;
+ ptext->pUnicodeBuffer = (sal_Unicode*)realloc((void*)ptext->pUnicodeBuffer,
+ nnewsize * sizeof(sal_Unicode));
+ ptext->pCharStyle = (XIMFeedback*)realloc((void*)ptext->pCharStyle,
+ nnewsize * sizeof(XIMFeedback));
+}
+
+//
+// Handle insertion of text in a preedit_draw_callback
+// string field of XIMText struct is guaranteed to be != NULL
+//
+
+void
+Preedit_InsertText(preedit_text_t *pText, XIMText *pInsertText, int where,
+ Bool isMultilingual)
+{
+ sal_Unicode *pInsertTextString;
+ int nInsertTextLength = 0;
+ XIMFeedback *pInsertTextCharStyle = pInsertText->feedback;
+
+ nInsertTextLength = pInsertText->length;
+
+ if (isMultilingual)
+ {
+ XIMUnicodeText *pUniText = (XIMUnicodeText*)pInsertText;
+ pInsertTextString = pUniText->string.utf16_char;
+ }
+ else
+ {
+ // can't handle wchar_t strings, so convert to multibyte chars first
+ char *pMBString;
+ size_t nMBLength;
+ if (pInsertText->encoding_is_wchar)
+ {
+ wchar_t *pWCString = pInsertText->string.wide_char;
+ size_t nBytes = wcstombs ( NULL, pWCString, 1024 /* dont care */);
+ pMBString = (char*)alloca( nBytes + 1 );
+ nMBLength = wcstombs ( pMBString, pWCString, nBytes + 1);
+ }
+ else
+ {
+ pMBString = pInsertText->string.multi_byte;
+ nMBLength = strlen(pMBString); // xxx
+ }
+
+ // convert multibyte chars to unicode
+ rtl_TextEncoding nEncoding = gsl_getSystemTextEncoding();
+
+ if (nEncoding != RTL_TEXTENCODING_UNICODE)
+ {
+ rtl_TextToUnicodeConverter aConverter =
+ rtl_createTextToUnicodeConverter( nEncoding );
+ rtl_TextToUnicodeContext aContext =
+ rtl_createTextToUnicodeContext(aConverter);
+
+ sal_Size nBufferSize = nInsertTextLength * 2;
+
+ pInsertTextString = (sal_Unicode*)alloca(nBufferSize);
+
+ sal_uInt32 nConversionInfo;
+ sal_Size nConvertedChars;
+
+ sal_Size nSize =
+ rtl_convertTextToUnicode( aConverter, aContext,
+ pMBString, nMBLength,
+ pInsertTextString, nBufferSize,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE,
+ &nConversionInfo, &nConvertedChars );
+
+ rtl_destroyTextToUnicodeContext(aConverter, aContext);
+ rtl_destroyTextToUnicodeConverter(aConverter);
+
+ }
+ else
+ {
+ pInsertTextString = (sal_Unicode*)pMBString;
+ }
+ }
+
+ // enlarge target text-buffer if necessary
+ if (pText->nSize <= (pText->nLength + nInsertTextLength))
+ enlarge_buffer(pText, pText->nLength + nInsertTextLength);
+
+ // insert text: displace old mem and put new bytes in
+ int from = where;
+ int to = where + nInsertTextLength;
+ int howmany = pText->nLength - where;
+
+ memmove((void*)(pText->pUnicodeBuffer + to),
+ (void*)(pText->pUnicodeBuffer + from),
+ howmany * sizeof(sal_Unicode));
+ memmove((void*)(pText->pCharStyle + to),
+ (void*)(pText->pCharStyle + from),
+ howmany * sizeof(XIMFeedback));
+
+ to = from;
+ howmany = nInsertTextLength;
+
+ memcpy((void*)(pText->pUnicodeBuffer + to), (void*)pInsertTextString,
+ howmany * sizeof(sal_Unicode));
+ memcpy((void*)(pText->pCharStyle + to), (void*)pInsertTextCharStyle,
+ howmany * sizeof(XIMFeedback));
+
+ pText->nLength += howmany;
+
+ // NULL-terminate the string
+ pText->pUnicodeBuffer[pText->nLength] = (sal_Unicode)0;
+}
+
+//
+// Handle the change of attributes in a preedit_draw_callback
+//
+void
+Preedit_UpdateAttributes ( preedit_text_t* ptext, XIMFeedback* feedback,
+ int from, int amount )
+{
+ if ( (from + amount) > ptext->nLength )
+ {
+ // XXX this indicates an error, are we out of sync ?
+ fprintf (stderr, "Preedit_UpdateAttributes( %i + %i > %i )\n",
+ from, amount, ptext->nLength );
+ fprintf (stderr, "\t XXX internal error, out of sync XXX\n");
+
+ return;
+ }
+
+ memcpy ( ptext->pCharStyle + from,
+ feedback, amount * sizeof(XIMFeedback) );
+}
+
+// Convert the XIM feedback values into appropriate VCL
+// SAL_EXTTEXTINPUT_ATTR values
+// returns an allocate list of attributes, which must be freed by caller
+USHORT*
+Preedit_FeedbackToSAL ( XIMFeedback* pfeedback, int nlength )
+{
+ USHORT *psalattr;
+ USHORT nval;
+ USHORT noldval = 0;
+ XIMFeedback nfeedback;
+
+ // only work with reasonable length
+ if (nlength > 0)
+ psalattr = (USHORT*)malloc(nlength * sizeof(USHORT));
+ else
+ return (USHORT*)NULL;
+
+ for (int npos = 0; npos < nlength; npos++)
+ {
+ nval = 0;
+ nfeedback = pfeedback[npos];
+
+ // means to use the feedback of the previous char
+ if (nfeedback == 0)
+ {
+ nval = noldval;
+ }
+ // convert feedback to attributes
+ else
+ {
+ if (nfeedback & XIMReverse)
+ nval |= SAL_EXTTEXTINPUT_ATTR_REDTEXT;
+ if (nfeedback & XIMUnderline)
+ nval |= SAL_EXTTEXTINPUT_ATTR_UNDERLINE;
+ if (nfeedback & XIMHighlight)
+ nval |= SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
+ if (nfeedback & XIMPrimary)
+ nval |= SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ if (nfeedback & XIMSecondary)
+ nval |= SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE;
+ if (nfeedback & XIMTertiary) // same as 2ery
+ nval |= SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE;
+
+ #if 0 // visibility feedback not supported now
+ if ( (nfeedback & XIMVisibleToForward)
+ || (nfeedback & XIMVisibleToBackward)
+ || (nfeedback & XIMVisibleCenter) )
+ { }
+ #endif
+ }
+ // copy in list
+ psalattr[npos] = nval;
+ noldval = nval;
+ }
+ // return list of sal attributes
+ return psalattr;
+}
+
+void
+PreeditDrawCallback(XIC ic, XPointer client_data,
+ XIMPreeditDrawCallbackStruct *call_data)
+{
+ preedit_data_t* pPreeditData = (preedit_data_t*)client_data;
+
+ // if there's nothing to change then change nothing
+ if ( (call_data->text == NULL) && (call_data->chg_length == 0) )
+ return;
+
+ if ( pPreeditData->eState == ePreeditStatusStartPending )
+ pPreeditData->eState = ePreeditStatusActivationRequired;
+ PreeditStartCallback( ic, client_data, NULL );
+
+ // Edit the internal textbuffer as indicated by the call_data,
+ // chg_first and chg_length are guaranteed to be nonnegative
+
+ // handle text deletion
+ if (call_data->text == NULL)
+ {
+ Preedit_DeleteText(&(pPreeditData->aText),
+ call_data->chg_first, call_data->chg_length );
+ }
+ else
+ {
+ // handle text insertion
+ if ( (call_data->chg_length == 0)
+ && (call_data->text->string.wide_char != NULL))
+ {
+ Preedit_InsertText(&(pPreeditData->aText), call_data->text,
+ call_data->chg_first, pPreeditData->bIsMultilingual);
+ }
+ else
+ // handle text replacement by deletion and insertion of text,
+ // not smart, just good enough
+ if ( (call_data->chg_length != 0)
+ && (call_data->text->string.wide_char != NULL))
+ {
+ Preedit_DeleteText(&(pPreeditData->aText),
+ call_data->chg_first, call_data->chg_length);
+ Preedit_InsertText(&(pPreeditData->aText), call_data->text,
+ call_data->chg_first, pPreeditData->bIsMultilingual);
+ }
+ else
+ // not really a text update, only attributes are concerned
+ if ( (call_data->chg_length != 0)
+ && (call_data->text->string.wide_char == NULL))
+ {
+ Preedit_UpdateAttributes(&(pPreeditData->aText),
+ call_data->text->feedback,
+ call_data->chg_first, call_data->chg_length);
+ }
+ }
+
+ //
+ // build the SalExtTextInputEvent and send it up
+ //
+
+ SalExtTextInputEvent aTextEvent;
+
+ aTextEvent.mnTime = 0;
+ aTextEvent.mpTextAttr = Preedit_FeedbackToSAL(
+ pPreeditData->aText.pCharStyle, pPreeditData->aText.nLength);
+ aTextEvent.mnCursorPos = call_data->caret;
+ aTextEvent.maText = pPreeditData->aText.pUnicodeBuffer;
+ aTextEvent.mbCursorVisible = True;
+ aTextEvent.mnDeltaStart = 0; // call_data->chg_first;
+ aTextEvent.mbOnlyCursor = False;
+
+ if ( pPreeditData->eState == ePreeditStatusActive )
+ pPreeditData->pFrame->maFrameData.Call(SALEVENT_EXTTEXTINPUT,
+ (void*)&aTextEvent);
+ if (aTextEvent.mpTextAttr)
+ free((void*)aTextEvent.mpTextAttr);
+}
+
+// -------------------------------------------------------------------------
+//
+// iv. preedit caret callback
+//
+// -------------------------------------------------------------------------
+
+void
+PreeditCaretCallback ( XIC ic, XPointer client_data,
+ XIMPreeditCaretCallbackStruct *call_data )
+{
+ // XXX PreeditCaretCallback is pure debug code for now
+ char *direction = "?";
+ char *style = "?";
+
+ switch ( call_data->style )
+ {
+ case XIMIsInvisible: style = "Invisible"; break;
+ case XIMIsPrimary: style = "Primary"; break;
+ case XIMIsSecondary: style = "Secondary"; break;
+ }
+ switch ( call_data->direction )
+ {
+ case XIMForwardChar: direction = "Forward char"; break;
+ case XIMBackwardChar: direction = "Backward char"; break;
+ case XIMForwardWord: direction = "Forward word"; break;
+ case XIMBackwardWord: direction = "Backward word"; break;
+ case XIMCaretUp: direction = "Caret up"; break;
+ case XIMCaretDown: direction = "Caret down"; break;
+ case XIMNextLine: direction = "Next line"; break;
+ case XIMPreviousLine: direction = "Previous line"; break;
+ case XIMLineStart: direction = "Line start"; break;
+ case XIMLineEnd: direction = "Line end"; break;
+ case XIMAbsolutePosition: direction = "Absolute"; break;
+ case XIMDontChange: direction = "Dont change"; break;
+ }
+
+ fprintf (stderr, "PreeditCaretCallback( ic=%i, client=%i,\n",
+ (unsigned int)ic, (unsigned int)client_data );
+ fprintf (stderr, "\t position=%i, direction=\"%s\", style=\"%s\" )\n",
+ call_data->position, direction, style );
+
+ // XXX
+}
+
+// -----------------------------------------------------------------------
+//
+// v. commit string callback: convert an extended text input (iiimp ... )
+// into an ordinary key-event
+//
+// -----------------------------------------------------------------------
+
+int
+CommitStringCallback( XIC ic, XPointer client_data, XPointer call_data )
+{
+ preedit_data_t* pPreeditData = (preedit_data_t*)client_data;
+
+ XIMUnicodeText *cbtext = (XIMUnicodeText *)call_data;
+ sal_Unicode *p_unicode_data = (sal_Unicode*)cbtext->string.utf16_char;
+ p_unicode_data[cbtext->length] = (sal_Unicode)0;
+
+ if ( pPreeditData->eState == ePreeditStatusActive )
+ PreeditDoneCallback( ic, client_data, call_data );
+
+ pPreeditData->pFrame->maFrameData.Call( SALEVENT_STARTEXTTEXTINPUT,
+ (void*)NULL );
+
+ SalExtTextInputEvent aTextEvent;
+
+ aTextEvent.mnTime = 0;
+ aTextEvent.mpTextAttr = 0;
+ aTextEvent.mnCursorPos = cbtext->length;
+ aTextEvent.maText = p_unicode_data;
+ aTextEvent.mbCursorVisible = True;
+ aTextEvent.mnDeltaStart = 0;
+ aTextEvent.mbOnlyCursor = False;
+
+ pPreeditData->pFrame->maFrameData.Call( SALEVENT_EXTTEXTINPUT,
+ (void*)&aTextEvent);
+ pPreeditData->pFrame->maFrameData.Call( SALEVENT_ENDEXTTEXTINPUT,
+ (void*)NULL );
+
+ return 0;
+}
+
diff --git a/vcl/unx/source/app/i18n_ic.cxx b/vcl/unx/source/app/i18n_ic.cxx
new file mode 100644
index 000000000000..4e2f34b77d22
--- /dev/null
+++ b/vcl/unx/source/app/i18n_ic.cxx
@@ -0,0 +1,686 @@
+/*************************************************************************
+ *
+ * $RCSfile: i18n_ic.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <alloca.h>
+
+#include <prex.h>
+#include <X11/Xlocale.h>
+#include <X11/Xlib.h>
+#include <postx.h>
+
+#include <salunx.h>
+
+#include <XIM.h>
+
+#ifndef _SAL_I18N_INPUTCONTEXT_HXX
+#include "i18n_ic.hxx"
+#endif
+#ifndef _SAL_I18N_INPUTMETHOD_HXX
+#include "i18n_im.hxx"
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+
+// ---------------------------------------------------------------------------
+//
+// Constructor / Destructor, the InputContext is bound to the SalFrame, as it
+// needs the shell window as a focus window
+//
+// ----------------------------------------------------------------------------
+
+SalI18N_InputContext::~SalI18N_InputContext()
+{
+ if ( maContext != NULL )
+ XDestroyIC( maContext );
+ if ( mpAttributes != NULL )
+ XFree( mpAttributes );
+ if ( mpStatusAttributes != NULL )
+ XFree( mpStatusAttributes );
+ if ( mpPreeditAttributes != NULL )
+ XFree( mpPreeditAttributes );
+ #ifdef SOLARIS
+ if ( mpFontSet != NULL )
+ XFreeFontSet( mpDisplay, mpFontSet );
+ #endif
+}
+
+#ifdef DEBUG
+
+// ----------------------------------------------------------------------------
+// debug routines, that keep track of fonts we've chosen in a fontset
+// ----------------------------------------------------------------------------
+
+// report which fonts are missing for the requested
+// basefont and which fonts are actually selected
+
+static void
+v_print_missing_fonts( char **pp_list, int n_listsz, const char *p_pattern )
+{
+ if ( !(n_listsz > 0) || (pp_list == NULL) || (p_pattern == NULL) )
+ return;
+
+ for (int i = 0; i < n_listsz; i++ )
+ fprintf(stderr, "missing charset@%s:\"%s\"\n", p_pattern, pp_list[i] );
+}
+
+static void
+v_print_chosen_fonts( XFontSet a_fontset )
+{
+ if ( a_fontset == 0 )
+ return;
+
+ char *p_locale_name;
+ XFontStruct **pp_font_struct_list;
+ char **pp_font_name_list;
+ int n_listsz;
+
+ p_locale_name = XLocaleOfFontSet( a_fontset );
+ n_listsz = XFontsOfFontSet( a_fontset,
+ &pp_font_struct_list,
+ &pp_font_name_list );
+ for ( int i = 0; i < n_listsz; i++ )
+ {
+ fprintf( stderr, "font@%s:\"%s\"\n",
+ p_locale_name, pp_font_name_list[i] );
+ }
+}
+
+#endif // DEBUG
+
+// Wrapper for XCreateFontSet to create a default font set
+static XFontSet
+p_create_fontset( Display *p_display )
+{
+ // a fontset, as there is no valid default for russian and all other
+ // eastern european locales in solaris 8
+ const char *p_base_font[] = {
+ "-*-application-medium-r-*-sans-12-*",
+ "-*-application-*-r-*-*-12-*",
+ "-*-*-*-r-*-*-12-*",
+ "-*" };
+ char **pp_missing_charset_list = NULL;
+ int n_missing_charset_count = 0;
+ char *p_def_string = NULL;
+
+ XFontSet a_fontset;
+
+ for (int i = 0; i < (sizeof(p_base_font) / sizeof(char*)); i++ )
+ {
+ a_fontset = XCreateFontSet( p_display, p_base_font[i],
+ &pp_missing_charset_list,
+ &n_missing_charset_count, &p_def_string);
+ #ifdef DEBUG
+ v_print_missing_fonts ( pp_missing_charset_list,
+ n_missing_charset_count, p_base_font[i] );
+ #endif
+
+ if ( a_fontset != 0 )
+ break;
+ }
+
+ #ifdef DEBUG
+ v_print_chosen_fonts( a_fontset );
+ #endif
+
+ return a_fontset;
+}
+
+// ----------------------------------------------------------------------------
+// convenience routine to add items to a XVaNestedList
+// ----------------------------------------------------------------------------
+
+static XVaNestedList
+XVaAddToNestedList( XVaNestedList a_srclist, char* name, XPointer value )
+{
+ XVaNestedList a_dstlist;
+
+ // if ( value == NULL )
+ // return a_srclist;
+
+ if ( a_srclist == NULL )
+ {
+ a_dstlist = XVaCreateNestedList(
+ 0,
+ name, value,
+ 0 );
+ }
+ else
+ {
+ a_dstlist = XVaCreateNestedList(
+ 0,
+ XNVaNestedList, a_srclist,
+ name, value,
+ 0 );
+ }
+
+ return a_dstlist != NULL ? a_dstlist : a_srclist ;
+}
+
+// ---------------------------------------------------------------------------
+//
+// Constructor for a InputContext (IC)
+//
+// ----------------------------------------------------------------------------
+
+SalI18N_InputContext::SalI18N_InputContext ( SalFrame *pFrame ) :
+ mbUseable( True ),
+ maContext( (XIC)NULL ),
+ mpAttributes( NULL ),
+ mpStatusAttributes( NULL ),
+ mpPreeditAttributes( NULL ),
+ #ifdef SOLARIS
+ mpFontSet( NULL ),
+ #endif
+ mnStatusStyle( 0 ),
+ mnPreeditStyle( 0 ),
+ mnSupportedPreeditStyle( XIMPreeditCallbacks |
+ XIMPreeditNothing | XIMPreeditNone
+ /* | XIMPreeditCallbacks
+ | XIMPreeditArea
+ | XIMPreeditPosition */ ),
+ mnSupportedStatusStyle( // XIMStatusCallbacks |
+ XIMStatusNothing | XIMStatusNone
+ /* | XIMStatusCallbacks
+ | XIMStatusArea */ )
+{
+ SalI18N_InputMethod *pInputMethod;
+ pInputMethod = pFrame->maFrameData.GetDisplay()->GetInputMethod();
+ mbMultiLingual = pInputMethod->IsMultiLingual();
+
+ if ( pInputMethod->UseMethod()
+ && SupportInputMethodStyle( pInputMethod->GetSupportedStyles() ) )
+ {
+ XLIB_Window aClientWindow= pFrame->maFrameData.GetShellWindow();
+ XLIB_Window aFocusWindow= pFrame->maFrameData.GetWindow();
+ Display *pDisplay = XDisplayOfIM( pInputMethod->GetMethod() );
+
+ // for status callbacks and commit string callbacks
+ maClientData.bIsMultilingual = mbMultiLingual;
+ maClientData.eState = ePreeditStatusStartPending;
+ maClientData.pFrame = pFrame;
+ maClientData.aText.pUnicodeBuffer = NULL;
+ maClientData.aText.pCharStyle = NULL;
+ maClientData.aText.nCursorPos = 0;
+ maClientData.aText.nLength = 0;
+ maClientData.aText.nSize = 0;
+
+ // set status attributes
+ // only none and nothing are supported which do not need special
+ // arguments, area and position are just hacks, preedit callback
+ // does work but cannot be connected without unicode/multibyte
+ // support of independent vcl layer
+
+ switch ( mnStatusStyle )
+ {
+ case XIMStatusArea:
+ {
+ XRectangle *pStatusArea = new XRectangle;
+ pStatusArea->x = 0;
+ pStatusArea->y = 64;
+ pStatusArea->width = 256;
+ pStatusArea->height = 64;
+
+ mpStatusAttributes = XVaCreateNestedList (
+ 0,
+ XNAreaNeeded, pStatusArea,
+ XNArea, pStatusArea,
+ 0 );
+
+ break;
+ }
+
+ case XIMStatusNone:
+ case XIMStatusNothing:
+ default:
+
+ break;
+ }
+
+ //
+ // set preedit attributes
+ //
+
+ switch ( mnPreeditStyle )
+ {
+ case XIMPreeditCallbacks:
+
+ maPreeditCaretCallback.callback = (XIMProc)PreeditCaretCallback;
+ maPreeditStartCallback.callback = (XIMProc)PreeditStartCallback;
+ maPreeditDoneCallback.callback = (XIMProc)PreeditDoneCallback;
+ maPreeditDrawCallback.callback = (XIMProc)PreeditDrawCallback;
+ maPreeditCaretCallback.client_data = (XPointer)&maClientData;
+ maPreeditStartCallback.client_data = (XPointer)&maClientData;
+ maPreeditDoneCallback.client_data = (XPointer)&maClientData;
+ maPreeditDrawCallback.client_data = (XPointer)&maClientData;
+
+ mpPreeditAttributes = XVaCreateNestedList (
+ 0,
+ XNPreeditStartCallback, &maPreeditStartCallback,
+ XNPreeditDoneCallback, &maPreeditDoneCallback,
+ XNPreeditDrawCallback, &maPreeditDrawCallback,
+ XNPreeditCaretCallback, &maPreeditCaretCallback,
+ 0 );
+
+ break;
+
+ case XIMPreeditPosition:
+ case XIMPreeditArea:
+ {
+ XRectangle *pPreeditArea = new XRectangle;
+ XPoint *pSpotLocation = new XPoint;
+
+ pSpotLocation->x = 16;
+ pSpotLocation->y = 32;
+
+ pPreeditArea->x = 0;
+ pPreeditArea->y = 0;
+ pPreeditArea->width = 256;
+ pPreeditArea->height = 64;
+
+ mpPreeditAttributes = XVaCreateNestedList (
+ 0,
+ XNArea, pPreeditArea,
+ XNSpotLocation, pSpotLocation,
+ 0 );
+
+ break;
+ }
+
+ case XIMPreeditNone:
+ case XIMPreeditNothing:
+ default:
+
+ break;
+ }
+
+ // Create the InputContext by given it exact the information it
+ // deserves, because inappropriate attributes
+ // let XCreateIC fail on Solaris (eg. for C locale)
+
+ mpAttributes = XVaCreateNestedList(
+ 0,
+ XNFocusWindow, aFocusWindow,
+ XNClientWindow, aClientWindow,
+ XNInputStyle, mnPreeditStyle | mnStatusStyle,
+ 0 );
+
+ #ifdef SOLARIS
+ mpDisplay = pDisplay;
+ if ( 0 && (mpFontSet = p_create_fontset(mpDisplay)) != NULL )
+ {
+ mpStatusAttributes = XVaAddToNestedList( mpStatusAttributes,
+ XNFontSet, (XPointer)mpFontSet );
+ mpPreeditAttributes = XVaAddToNestedList( mpPreeditAttributes,
+ XNFontSet, (XPointer)mpFontSet );
+ }
+ #endif
+ if ( mnPreeditStyle != XIMPreeditNone )
+ {
+ #ifdef LINUX
+ if ( mpPreeditAttributes != NULL )
+ #endif
+ mpAttributes = XVaAddToNestedList( mpAttributes,
+ XNPreeditAttributes, (XPointer)mpPreeditAttributes );
+ }
+ if ( mnStatusStyle != XIMStatusNone )
+ {
+ #ifdef LINUX
+ if ( mpStatusAttributes != NULL )
+ #endif
+ mpAttributes = XVaAddToNestedList( mpAttributes,
+ XNStatusAttributes, (XPointer)mpStatusAttributes );
+ }
+ maContext = XCreateIC( pInputMethod->GetMethod(),
+ XNVaNestedList, mpAttributes,
+ NULL );
+ }
+
+ if ( maContext == NULL )
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "input context creation failed\n");
+ #endif
+
+ mbUseable = False;
+ mbMultiLingual = False;
+
+ if ( mpAttributes != NULL )
+ XFree( mpAttributes );
+ if ( mpStatusAttributes != NULL )
+ XFree( mpStatusAttributes );
+ if ( mpPreeditAttributes != NULL )
+ XFree( mpPreeditAttributes );
+ }
+
+ if ( maContext != NULL && mbMultiLingual )
+ {
+ maCommitStringCallback.callback = (XIMProc)::CommitStringCallback;
+ maCommitStringCallback.client_data = (XPointer)&maClientData;
+ XSetICValues( maContext,
+ XNCommitStringCallback, &maCommitStringCallback,
+ NULL );
+ }
+
+}
+
+// ---------------------------------------------------------------------------
+//
+// In Solaris 8 the status window does not unmap if the frame unmapps, so
+// unmap it the hard way
+//
+// ---------------------------------------------------------------------------
+
+void
+SalI18N_InputContext::Unmap()
+{
+ if ( maContext != NULL )
+ {
+ XDestroyIC( maContext );
+ maContext = NULL;
+ }
+}
+
+void
+SalI18N_InputContext::Map( SalFrame *pFrame )
+{
+ if ( (maContext == NULL) && mbUseable)
+ {
+ SalI18N_InputMethod *pInputMethod;
+ pInputMethod = pFrame->maFrameData.GetDisplay()->GetInputMethod();
+
+ maContext = XCreateIC( pInputMethod->GetMethod(),
+ XNVaNestedList, mpAttributes,
+ NULL );
+ if ( maContext != NULL && mbMultiLingual )
+ XSetICValues( maContext,
+ XNCommitStringCallback, &maCommitStringCallback,
+ NULL );
+ SetICFocus();
+ }
+}
+
+// ---------------------------------------------------------------------------
+//
+// make sure, the input method gets all the X-Events it needs, this is only
+// called once on each frame, it relys on a valid maContext
+//
+// ---------------------------------------------------------------------------
+
+void
+SalI18N_InputContext::ExtendEventMask( XLIB_Window aFocusWindow )
+{
+ unsigned long nIMEventMask;
+ XWindowAttributes aWindowAttributes;
+
+ if ( mbUseable )
+ {
+ Display *pDisplay = XDisplayOfIM( XIMOfIC(maContext) );
+
+ XGetWindowAttributes( pDisplay, aFocusWindow,
+ &aWindowAttributes );
+ XGetICValues ( maContext,
+ XNFilterEvents, &nIMEventMask,
+ NULL);
+ nIMEventMask |= aWindowAttributes.your_event_mask;
+ XSelectInput ( pDisplay, aFocusWindow, nIMEventMask );
+ }
+}
+
+// ---------------------------------------------------------------------------
+//
+// tune the styles provided by the input method with the supported one
+//
+// ---------------------------------------------------------------------------
+
+unsigned int
+SalI18N_InputContext::GetWeightingOfIMStyle( XIMStyle nStyle ) const
+{
+ struct StyleWeightingT {
+ const XIMStyle nStyle;
+ const unsigned int nWeight;
+ };
+
+ StyleWeightingT const *pWeightPtr;
+ const StyleWeightingT pWeight[] = {
+ { XIMPreeditCallbacks, 0x10000000 },
+ { XIMPreeditPosition, 0x02000000 },
+ { XIMPreeditArea, 0x01000000 },
+ { XIMPreeditNothing, 0x00100000 },
+ { XIMPreeditNone, 0x00010000 },
+ { XIMStatusCallbacks, 0x1000 },
+ { XIMStatusArea, 0x0100 },
+ { XIMStatusNothing, 0x0010 },
+ { XIMStatusNone, 0x0001 },
+ { 0, 0x0 }
+ };
+
+ int nWeight = 0;
+ for ( pWeightPtr = pWeight; pWeightPtr->nStyle != 0; pWeightPtr++ )
+ {
+ if ( (pWeightPtr->nStyle & nStyle) != 0 )
+ nWeight += pWeightPtr->nWeight;
+ }
+ return nWeight;
+}
+
+Bool
+SalI18N_InputContext::IsSupportedIMStyle( XIMStyle nStyle ) const
+{
+ if ( (nStyle & mnSupportedPreeditStyle)
+ && (nStyle & mnSupportedStatusStyle) )
+ {
+ return True;
+ }
+ return False;
+}
+
+Bool
+SalI18N_InputContext::SupportInputMethodStyle( XIMStyles *pIMStyles )
+{
+ int nBestScore = 0;
+ int nActualScore = 0;
+
+ mnPreeditStyle = 0;
+ mnStatusStyle = 0;
+
+ if ( pIMStyles != NULL )
+ {
+ // check whether the XIM supports one of the desired styles
+ // only a single preedit and a single status style must occure
+ // in a inpuut method style. Hideki said so, so i trust him
+ for ( int nStyle = 0; nStyle < pIMStyles->count_styles; nStyle++ )
+ {
+ XIMStyle nProvidedStyle = pIMStyles->supported_styles[ nStyle ];
+ if ( IsSupportedIMStyle(nProvidedStyle) )
+ {
+ nActualScore = GetWeightingOfIMStyle( nProvidedStyle );
+ if ( nActualScore >= nBestScore )
+ {
+ nBestScore = nActualScore;
+ mnPreeditStyle = nProvidedStyle & mnSupportedPreeditStyle;
+ mnStatusStyle = nProvidedStyle & mnSupportedStatusStyle;
+ }
+ }
+ }
+ }
+
+ #ifdef DEBUG
+ char pBuf[ 128 ];
+ fprintf( stderr, "selected inputmethod style = %s\n",
+ GetMethodName(mnPreeditStyle | mnStatusStyle, pBuf, sizeof(pBuf)) );
+ #endif
+
+ return (mnPreeditStyle != 0) && (mnStatusStyle != 0) ;
+}
+
+int
+SalI18N_InputContext::CommitStringCallback( sal_Unicode* pText, sal_Size nLength )
+{
+ XIMUnicodeText call_data;
+
+ call_data.string.utf16_char = pText;
+ call_data.length = nLength;
+ call_data.annotations = NULL;
+ call_data.count_annotations = 0;
+ call_data.feedback = NULL;
+
+ return ::CommitStringCallback( maContext,
+ (XPointer)&maClientData, (XPointer)&call_data );
+}
+
+// ---------------------------------------------------------------------------
+//
+// set and unset the focus for the Input Context
+// the context may be NULL despite it is useable if the framewindow is
+// in unmapped state
+//
+// ---------------------------------------------------------------------------
+
+void
+SalI18N_InputContext::SetICFocus()
+{
+ if ( mbUseable && (maContext != NULL) )
+ XSetICFocus( maContext );
+}
+
+void
+SalI18N_InputContext::UnsetICFocus()
+{
+ if ( mbUseable && (maContext != NULL) )
+ XUnsetICFocus( maContext );
+}
+
+// ---------------------------------------------------------------------------
+//
+// not used, multi byte input method only
+//
+// ---------------------------------------------------------------------------
+
+void
+SalI18N_InputContext::EndExtTextInput( USHORT nFlags )
+{
+ if ( mbUseable && (maContext != NULL) )
+ {
+ char *pPendingChars = XmbResetIC( maContext );
+
+ // text is unicode
+ if ( (pPendingChars != NULL)
+ && (nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE) )
+ {
+ XIMUnicodeText aPendingText;
+ int nLen;
+ sal_Unicode* pPtr;
+ rtl_TextEncoding nEncoding = gsl_getSystemTextEncoding();
+
+ // buffer is already unicode
+ if ( mbMultiLingual || nEncoding == RTL_TEXTENCODING_UNICODE )
+ {
+ pPtr = (sal_Unicode*)pPendingChars;
+ for ( nLen = 0; pPtr[ nLen ] != (sal_Unicode)0; nLen++ )
+ ;
+ }
+ // else convert buffer to unicode
+ else
+ {
+ for ( nLen = 0; pPendingChars[ nLen ] != (char)0; nLen++ )
+ ;
+
+ // create text converter
+ rtl_TextToUnicodeConverter aConverter =
+ rtl_createTextToUnicodeConverter( nEncoding );
+ rtl_TextToUnicodeContext aContext =
+ rtl_createTextToUnicodeContext( aConverter );
+
+ sal_Size nBufferSize = nLen * 2;
+ sal_uInt32 nConversionInfo;
+ sal_Size nConvertedChars;
+
+ pPtr = (sal_Unicode*) alloca( nBufferSize );
+
+ // convert to single byte text stream
+ nLen = rtl_convertTextToUnicode(
+ aConverter, aContext, (char*)pPendingChars,
+ nLen, pPtr, nBufferSize,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE,
+ &nConversionInfo, &nConvertedChars );
+
+ // destroy converter
+ rtl_destroyTextToUnicodeContext( aConverter, aContext );
+ rtl_destroyTextToUnicodeConverter( aConverter );
+ }
+ aPendingText.length = nLen;
+ aPendingText.string.utf16_char = pPtr;
+
+ ::CommitStringCallback( maContext,
+ (XPointer)&maClientData, (XPointer)&aPendingText );
+ }
+ if ( pPendingChars != NULL )
+ XFree ( (void*)pPendingChars );
+ }
+}
+
+
diff --git a/vcl/unx/source/app/i18n_im.cxx b/vcl/unx/source/app/i18n_im.cxx
new file mode 100644
index 000000000000..04c1f9b24ca2
--- /dev/null
+++ b/vcl/unx/source/app/i18n_im.cxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * $RCSfile: i18n_im.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+
+#include <prex.h>
+#include <X11/Xlocale.h>
+#include <X11/Xlib.h>
+#include <XIM.h>
+#include <postx.h>
+
+#include <salunx.h>
+
+#ifndef _SAL_I18N_INPUTMETHOD_HXX
+#include "i18n_im.hxx"
+#endif
+
+// -------------------------------------------------------------------------
+//
+// locale handling
+//
+// -------------------------------------------------------------------------
+
+// Locale handling of the operating system layer
+
+static char*
+SetSystemLocale( const char* p_inlocale )
+{
+ char *p_outlocale;
+ if ( (p_outlocale = setlocale(LC_ALL, p_inlocale)) == NULL )
+ {
+ fprintf( stderr,
+ "I18N: Operating system doesn't support locale \"%s\"\n",
+ p_inlocale );
+ }
+
+ return p_outlocale;
+}
+
+static Bool
+IsPosixLocale( const char* p_locale )
+{
+ if ( p_locale == NULL )
+ return False;
+ if ( (p_locale[ 0 ] == 'C') && (p_locale[ 1 ] == '\0') )
+ return True;
+ if ( strncmp(p_locale, "POSIX", sizeof("POSIX")) == 0 )
+ return True;
+
+ return False;
+}
+
+// Locale handling of the X Window System layer
+
+static Bool
+IsXWindowCompatibleLocale( const char* p_locale )
+{
+ if ( p_locale == NULL )
+ return False;
+
+ if ( !XSupportsLocale() )
+ {
+ if ( p_locale != NULL )
+ fprintf (stderr,
+ "I18N: X Window System doesn't support locale \"%s\"\n",
+ p_locale );
+ return False;
+ }
+ return True;
+}
+
+// Locale setting for the Input Method
+// allways provide a fallback, even if it means falling back to the
+// portable POSIX "C" locale
+
+Bool
+SalI18N_InputMethod::SetLocale( const char* pLocale )
+{
+ // check whether we want an Input Method engine, if we don't we
+ // do not need to set the locale
+ if ( mbUseable )
+ {
+ char *locale;
+
+ // check whether the operating system supports the LANG
+ if ( (locale = SetSystemLocale( pLocale )) == NULL )
+ {
+ if ( (locale = SetSystemLocale( "C" )) == NULL )
+ mbUseable = False;
+ }
+
+ // check whether the XWindow system supports the LANG
+ if ( !IsXWindowCompatibleLocale(locale) )
+ {
+ if ( !IsPosixLocale(locale) )
+ {
+ locale = SetSystemLocale( "C" );
+ if ( !IsXWindowCompatibleLocale(locale) )
+ mbUseable = False;
+ }
+ else
+ {
+ mbUseable = False;
+ }
+ }
+
+ // must not fail if mbUseable since XSupportsLocale() asserts success
+ if ( mbUseable && XSetLocaleModifiers("") == NULL )
+ {
+ fprintf (stderr, "I18N: Can't set X modifiers for locale \"%s\"\n",
+ locale);
+ mbUseable = False;
+ }
+ }
+
+ return mbUseable;
+}
+
+// ------------------------------------------------------------------------
+//
+// Constructor / Destructor / Initialisation
+//
+// ------------------------------------------------------------------------
+
+SalI18N_InputMethod::SalI18N_InputMethod( ) : maMethod( (XIM)NULL ),
+ mpStyles( (XIMStyles*)NULL ),
+ mbUseable( bUseInputMethodDefault ),
+ mbMultiLingual( False )
+{
+ const char *pUseInputMethod = getenv( "SAL_USEINPUTMETHOD" );
+ if ( pUseInputMethod != NULL )
+ mbUseable = pUseInputMethod[0] != '\0' ;
+}
+
+SalI18N_InputMethod::~SalI18N_InputMethod()
+{
+ if ( mpStyles != NULL )
+ XFree( mpStyles );
+ if ( maMethod != NULL )
+ XCloseIM ( maMethod );
+}
+
+//
+// XXX
+// debug routine: lets have a look at the provided method styles
+//
+
+#ifdef DEBUG
+
+extern "C" char*
+GetMethodName( XIMStyle nStyle, char *pBuf, int nBufSize)
+{
+ struct StyleName {
+ const XIMStyle nStyle;
+ const char *pName;
+ const int nNameLen;
+ };
+
+ StyleName *pDescPtr;
+ static const StyleName pDescription[] = {
+ { XIMPreeditArea, "PreeditArea ", sizeof("PreeditArea ") },
+ { XIMPreeditCallbacks, "PreeditCallbacks ",sizeof("PreeditCallbacks ")},
+ { XIMPreeditPosition, "PreeditPosition ", sizeof("PreeditPosition ") },
+ { XIMPreeditNothing, "PreeditNothing ", sizeof("PreeditNothing ") },
+ { XIMPreeditNone, "PreeditNone ", sizeof("PreeditNone ") },
+ { XIMStatusArea, "StatusArea ", sizeof("StatusArea ") },
+ { XIMStatusCallbacks, "StatusCallbacks ", sizeof("StatusCallbacks ") },
+ { XIMStatusNothing, "StatusNothing ", sizeof("StatusNothing ") },
+ { XIMStatusNone, "StatusNone ", sizeof("StatusNone ") },
+ { 0, "NULL", 0 }
+ };
+
+ if ( nBufSize > 0 )
+ pBuf[0] = '\0';
+
+ char *pBufPtr = pBuf;
+ for ( pDescPtr = const_cast<StyleName*>(pDescription); pDescPtr->nStyle != 0; pDescPtr++ )
+ {
+ int nSize = pDescPtr->nNameLen - 1;
+ if ( (nStyle & pDescPtr->nStyle) && (nBufSize > nSize) )
+ {
+ strncpy( pBufPtr, pDescPtr->pName, nSize + 1);
+ pBufPtr += nSize;
+ nBufSize -= nSize;
+ }
+ }
+
+ return pBuf;
+}
+
+extern "C" void
+PrintInputStyle( XIMStyles *pStyle )
+{
+ char pBuf[ 128 ];
+ int nBuf = sizeof( pBuf );
+
+ if ( pStyle == NULL )
+ fprintf( stderr, "no input method styles\n");
+ else
+ for ( int nStyle = 0; nStyle < pStyle->count_styles; nStyle++ )
+ {
+ fprintf( stderr, "style #%i = %s\n", nStyle,
+ GetMethodName(pStyle->supported_styles[nStyle], pBuf, nBuf) );
+ }
+}
+
+#endif
+
+//
+// this is the real constructing routine, since locale setting has to be done
+// prior to xopendisplay, the xopenim call has to be delayed
+//
+
+Bool
+SalI18N_InputMethod::CreateMethod ( Display *pDisplay )
+{
+ if ( mbUseable )
+ {
+ if ( getenv("USE_XOPENIM") == NULL )
+ {
+ mbMultiLingual = True; // set ml-input flag to create input-method
+ maMethod = XvaOpenIM(pDisplay, NULL, NULL, NULL,
+ XNMultiLingualInput, mbMultiLingual, /* dummy */
+ 0);
+ // get ml-input flag from input-method
+ if ( maMethod == (XIM)NULL )
+ mbMultiLingual = False;
+ else
+ if ( XGetIMValues(maMethod,
+ XNMultiLingualInput, &mbMultiLingual, NULL ) != NULL )
+ mbMultiLingual = False;
+ }
+ else
+ {
+ maMethod = XOpenIM(pDisplay, NULL, NULL, NULL);
+ mbMultiLingual = False;
+ }
+
+ if ( maMethod != (XIM)NULL )
+ {
+ if ( XGetIMValues(maMethod, XNQueryInputStyle, &mpStyles, NULL)
+ != NULL)
+ mbUseable = False;
+ #ifdef DEBUG
+ fprintf(stderr, "Creating %s-Lingual InputMethod\n",
+ mbMultiLingual ? "Multi" : "Mono" );
+ PrintInputStyle( mpStyles );
+ #endif
+ }
+ else
+ {
+ mbUseable = False;
+ }
+ }
+
+ #ifdef DEBUG
+ if ( !mbUseable )
+ fprintf(stderr, "input method creation failed\n");
+ #endif
+
+ return mbUseable;
+}
+
+//
+// give IM the opportunity to look at the event, and possibly hide it
+//
+
+Bool
+SalI18N_InputMethod::FilterEvent( XEvent *pEvent )
+{
+ return mbUseable && (Bool)XFilterEvent( pEvent, None );
+}
+
+
diff --git a/vcl/unx/source/app/i18n_wrp.cxx b/vcl/unx/source/app/i18n_wrp.cxx
new file mode 100644
index 000000000000..4ad92b28d3cb
--- /dev/null
+++ b/vcl/unx/source/app/i18n_wrp.cxx
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * $RCSfile: i18n_wrp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+struct XIMArg
+{
+ char *name;
+ char *value;
+};
+
+#if !defined(LINUX)
+#include <varargs.h>
+#else
+#include <stdarg.h>
+#endif
+#include <string.h>
+#include <dlfcn.h>
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include "XIM.h"
+
+
+#ifdef SOLARIS
+#define XIIIMP_PATH "/usr/openwin/lib/locale/common/xiiimp.so.2"
+#else /* Linux */
+#define XIIIMP_PATH "/usr/lib/im/xiiimp.so.2"
+#endif
+
+/* global variables */
+static void *g_dlmodule = 0;
+
+extern "C" {
+typedef XIM (*OpenFunction)(Display*, XrmDatabase, char*, char*, XIMArg*);
+}
+
+static OpenFunction g_open_im = (OpenFunction)NULL;
+
+/* utility function to transform vararg list into an array of XIMArg */
+
+int
+XvaCountArgs( XIMArg *pInArgs )
+{
+ int nArgs = 0;
+ char *pName, *pValue;
+
+ while ( (pName = pInArgs->name) != NULL )
+ {
+ pValue = pInArgs->value;
+
+ if ( strcmp(pName, XNVaNestedList) == 0 )
+ {
+ nArgs += XvaCountArgs( (XIMArg*)pValue );
+ }
+ else
+ {
+ nArgs += 1;
+ }
+ pInArgs++;
+ }
+
+ return nArgs;
+}
+
+int
+XvaCountArgs( va_list pInArgs )
+{
+ int nArgs = 0;
+ char *pName, *pValue;
+
+ while ( (pName = va_arg(pInArgs, char*)) != NULL)
+ {
+ pValue = va_arg(pInArgs, char*);
+
+ if ( strcmp(pName, XNVaNestedList) == 0 )
+ {
+ nArgs += XvaCountArgs( (XIMArg*)pValue );
+ }
+ else
+ {
+ nArgs += 1;
+ }
+ }
+
+ return nArgs;
+}
+
+XIMArg*
+XvaGetArgs( XIMArg *pInArgs, XIMArg *pOutArgs )
+{
+ char *pName, *pValue;
+
+ while ( (pName = pInArgs->name) != NULL )
+ {
+ pValue = pInArgs->value;
+
+ if ( strcmp(pName, XNVaNestedList) == 0 )
+ {
+ pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs );
+ }
+ else
+ {
+ pOutArgs->name = pName;
+ pOutArgs->value = pValue;
+ pOutArgs++;
+ }
+ pInArgs++;
+ }
+
+ return pOutArgs;
+}
+
+void
+XvaGetArgs( va_list pInArgs, XIMArg *pOutArgs )
+{
+ char *pName, *pValue;
+
+ while ((pName = va_arg(pInArgs, char*)) != NULL)
+ {
+ pValue = va_arg(pInArgs, char*);
+
+ if ( strcmp(pName, XNVaNestedList) == 0 )
+ {
+ pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs );
+ }
+ else
+ {
+ pOutArgs->name = pName;
+ pOutArgs->value = pValue;
+ pOutArgs++;
+ }
+ }
+
+ pOutArgs->name = NULL;
+ pOutArgs->value = NULL;
+}
+
+
+/* Puplic functions */
+
+#ifdef __cplusplus
+extern "C"
+#endif
+XIM
+XvaOpenIM(Display *display, XrmDatabase rdb,
+ char *res_name, char *res_class, ...)
+{
+ XIM xim = (XIM)0;
+ va_list variable;
+ int total_count = 0;
+
+ /*
+ * so count the stuff dangling here
+ */
+
+ #ifdef LINUX
+ va_start(variable, res_class);
+ #else
+ va_start(variable);
+ #endif
+ total_count = XvaCountArgs(variable);
+ va_end(variable);
+
+ if (total_count > 0)
+ {
+ /* call a new open IM method */
+
+ XIMArg* args = (XIMArg*)Xmalloc( (total_count + 1) * sizeof(XIMArg) );
+
+ /*
+ * now package it up so we can set it along
+ */
+ #ifdef LINUX
+ va_start(variable, res_class);
+ #else
+ va_start(variable);
+ #endif
+ XvaGetArgs( variable, args );
+ va_end(variable);
+
+ if (!g_dlmodule)
+ {
+ g_dlmodule = dlopen(XIIIMP_PATH, RTLD_LAZY);
+ if (!g_dlmodule)
+ goto legacy_XIM;
+
+ g_open_im = (OpenFunction)(long)dlsym(g_dlmodule, "__XOpenIM");
+ if (!g_open_im)
+ goto legacy_XIM;
+
+ xim = (*g_open_im)(display, (XrmDatabase)rdb,
+ (char*)res_name, (char *)res_class, (XIMArg*)args);
+ }
+ else
+ {
+ goto legacy_XIM;
+ }
+ }
+
+ legacy_XIM:
+
+ if (!xim)
+ xim = XOpenIM(display, rdb, res_name, res_class);
+
+ return xim;
+}
+
+/*
+ * Close the connection to the input manager, and free the XIM structure
+ */
+
+Status
+XvaCloseIM(XIM im)
+{
+ Status s;
+ #if 0
+ XCloseIM(im);
+ s = (im->methods->close)(im); /* we can use the same close module */
+ #endif
+
+ if (!g_dlmodule)
+ {
+ /* assuming one XvaOpenIM call */
+ dlclose(g_dlmodule);
+ g_dlmodule = (void*)0;
+ g_open_im = (OpenFunction)NULL;
+ }
+ #if 0
+ if (im)
+ Xfree((char *)im);
+ #endif
+
+ return (s);
+}
+
+
+
diff --git a/vcl/unx/source/app/i18n_xkb.cxx b/vcl/unx/source/app/i18n_xkb.cxx
new file mode 100644
index 000000000000..b57abd09acc4
--- /dev/null
+++ b/vcl/unx/source/app/i18n_xkb.cxx
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * $RCSfile: i18n_xkb.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#include <stdio.h>
+
+#if defined(LINUX) // should really check for xfree86 or for X11R6.1 and higher
+#define __XKeyboardExtension__ 1
+#else
+#define __XKeyboardExtension__ 0
+#endif
+
+#include <prex.h>
+#include <X11/X.h>
+#if __XKeyboardExtension__
+#include <X11/XKBlib.h>
+#endif
+#include <postx.h>
+
+#ifndef _SAL_I18N_XKBDEXTENSION_HXX
+#include "i18n_xkb.hxx"
+#endif
+
+SalI18N_KeyboardExtension::SalI18N_KeyboardExtension( Display *pDisplay )
+ : mbUseExtension( (sal_Bool)__XKeyboardExtension__ ),
+ mnDefaultGroup( 0 )
+{
+ #if __XKeyboardExtension__
+
+ mpDisplay = pDisplay;
+
+ // allow user to set the default keyboard group idx or to disable the usage
+ // of x keyboard extension at all:
+ // setenv SAL_XKEYBOARDGROUP disables keyboard extension
+ // setenv SAL_XKEYBOARDGROUP 2 sets the keyboard group index to 2
+ // keyboard group index must be in [1,4], may be specified in hex or decimal
+ static char *pUseKeyboardExtension = getenv( "SAL_XKEYBOARDGROUP" );
+ if ( pUseKeyboardExtension != NULL )
+ {
+ mbUseExtension = pUseKeyboardExtension[0] != '\0' ;
+ if ( mbUseExtension )
+ mnDefaultGroup = strtol( pUseKeyboardExtension, NULL, 0 );
+ if ( mnDefaultGroup > XkbMaxKbdGroup )
+ mnDefaultGroup = 0;
+ }
+
+ // query XServer support for XKB Extension,
+ // do not call XQueryExtension() / XInitExtension() due to possible version
+ // clashes !
+ if ( mbUseExtension )
+ {
+ int nMajorExtOpcode;
+ int nExtMajorVersion = XkbMajorVersion;
+ int nExtMinorVersion = XkbMinorVersion;
+
+ mbUseExtension = (sal_Bool)XkbQueryExtension( mpDisplay,
+ &nMajorExtOpcode, (int*)&mnEventBase, (int*)&mnErrorBase,
+ &nExtMajorVersion, &nExtMinorVersion );
+ }
+
+ // query notification for changes of the keyboard group
+ if ( mbUseExtension )
+ {
+ #define XkbGroupMask ( XkbGroupStateMask | XkbGroupBaseMask \
+ | XkbGroupLatchMask | XkbGroupLockMask )
+
+ mbUseExtension = XkbSelectEventDetails( mpDisplay,
+ XkbUseCoreKbd, XkbStateNotify, XkbGroupMask, XkbGroupMask );
+ }
+
+ // query initial keyboard group
+ if ( mbUseExtension )
+ {
+ XkbStateRec aStateRecord;
+ XkbGetState( mpDisplay, XkbUseCoreKbd, &aStateRecord );
+ mnGroup = aStateRecord.group;
+ }
+
+ #endif // __XKeyboardExtension__
+}
+
+void
+SalI18N_KeyboardExtension::Dispatch( XEvent *pEvent )
+{
+ #if __XKeyboardExtension__
+
+ // must the event be handled?
+ if ( !mbUseExtension
+ || (pEvent->type != mnEventBase) )
+ return;
+
+ // only handle state notify events for now, and only interested
+ // in group details
+ sal_uInt32 nXKBType = ((XkbAnyEvent*)pEvent)->xkb_type;
+ switch ( nXKBType )
+ {
+ case XkbStateNotify:
+
+ mnGroup = ((XkbStateNotifyEvent*)pEvent)->group;
+ break;
+
+ default:
+
+ #ifdef DEBUG
+ fprintf(stderr, "Got unrequested XkbAnyEvent %#x/%i\n",
+ nXKBType, nXKBType );
+ #endif
+ break;
+ }
+
+ #endif // __XKeyboardExtension__
+}
+
+sal_uInt32
+SalI18N_KeyboardExtension::LookupKeysymInGroup( sal_uInt32 nKeyCode,
+ sal_uInt32 nShiftState,
+ sal_uInt32 nGroup ) const
+{
+ #if __XKeyboardExtension__
+
+ if ( !mbUseExtension )
+ return NoSymbol;
+
+ nShiftState &= ShiftMask;
+
+ KeySym nKeySymbol;
+ nKeySymbol = XkbKeycodeToKeysym( mpDisplay, nKeyCode, nGroup, nShiftState );
+ return nKeySymbol;
+
+ #else
+
+ return NoSymbol;
+
+ #endif // __XKeyboardExtension__
+}
+
+
diff --git a/vcl/unx/source/app/keysymnames.cxx b/vcl/unx/source/app/keysymnames.cxx
new file mode 100644
index 000000000000..e08804ff371e
--- /dev/null
+++ b/vcl/unx/source/app/keysymnames.cxx
@@ -0,0 +1,545 @@
+/*************************************************************************
+ *
+ * $RCSfile: keysymnames.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef SOLARIS
+#include <prex.h>
+#include <X11/XKBlib.h>
+#include <postx.h>
+#endif
+
+#include <saldisp.hxx>
+#include <X11/keysym.h>
+
+#ifdef SOLARIS
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/kbio.h>
+#include <sys/kbd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <deflt.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#ifndef KB_USB // compile with too old headers
+#define KB_USB 6
+#endif
+#endif
+
+namespace vcl_sal {
+
+ struct KeysymNameReplacement
+ {
+ KeySym aSymbol;
+ const char* pName;
+ };
+
+ struct KeyboardReplacements
+ {
+ const char* pKeyboardName;
+ const KeysymNameReplacement* pReplacements;
+ int nReplacements;
+ rtl_TextEncoding nEncoding;
+ };
+
+ static const struct KeysymNameReplacement aImplReplacements_German[] =
+ {
+ { XK_Control_L, "Strg" },
+ { XK_Control_R, "Strg" },
+ { XK_Shift_L, "Umschalt" },
+ { XK_Shift_R, "Umschalt" },
+ { XK_Alt_L, "Alt" },
+ { XK_Alt_R, "Alt Gr" },
+ { XK_Page_Up, "Bild auf" },
+ { XK_Page_Down, "Bild ab" },
+ { XK_End, "Ende" },
+ { XK_Home, "Pos 1" },
+ { XK_Insert, "Einfg" },
+ { XK_Delete, "Entf" },
+ { XK_Escape, "Esc" },
+ { XK_Right, "Rechts" },
+ { XK_Left, "Links" },
+ { XK_Up, "Oben" },
+ { XK_Down, "Unten" },
+ { XK_BackSpace, "Rckschritt" },
+ { XK_Return, "Eingabe" },
+ { XK_slash, "Schrgstrich" },
+ { XK_space, "Leertaste" }
+ };
+
+ static const struct KeysymNameReplacement aImplReplacements_French[] =
+ {
+ { XK_Shift_L, "Maj" },
+ { XK_Shift_R, "Maj" },
+ { XK_Page_Up, "Pg. Prc" },
+ { XK_Page_Down, "Pg. Suiv" },
+ { XK_End, "Fin" },
+ { XK_Home, "Origine" },
+ { XK_Insert, "Insrer" },
+ { XK_Delete, "Suppr" },
+ { XK_Escape, "Esc" },
+ { XK_Right, "Droite" },
+ { XK_Left, "Gauche" },
+ { XK_Up, "Haut" },
+ { XK_Down, "Bas" },
+ { XK_BackSpace, "Ret. Arr" },
+ { XK_Return, "Retour" },
+ { XK_KP_Enter, "Entre" }
+ };
+
+ static const struct KeysymNameReplacement aImplReplacements_Italian[] =
+ {
+ { XK_Shift_L, "Maiusc" },
+ { XK_Shift_R, "Maiusc" },
+ { XK_Page_Up, "PgSu" },
+ { XK_Page_Down, "PgGiu" },
+ { XK_End, "Fine" },
+ { XK_Insert, "Ins" },
+ { XK_Delete, "Canc" },
+ { XK_Escape, "Esc" },
+ { XK_Right, "A destra" },
+ { XK_Left, "A sinistra" },
+ { XK_Up, "Sposta verso l'alto" },
+ { XK_Down, "Sposta verso il basso" },
+ { XK_BackSpace, "Backspace" },
+ { XK_Return, "Invio" },
+ { XK_space, "Spaziatrice" }
+ };
+
+ static const struct KeysymNameReplacement aImplReplacements_Dutch[] =
+ {
+ { XK_Page_Up, "PageUp" },
+ { XK_Page_Down, "PageDown" },
+ { XK_Escape, "Esc" },
+ { XK_Right, "Rechts" },
+ { XK_Left, "Links" },
+ { XK_Up, "Boven" },
+ { XK_Down, "Onder" },
+ { XK_BackSpace, "Backspace" },
+ { XK_Return, "Return" },
+ { XK_space, "Spatiebalk" }
+ };
+
+ static const struct KeysymNameReplacement aImplReplacements_Norwegian[] =
+ {
+ { XK_Shift_L, "Skift" },
+ { XK_Shift_R, "Skift" },
+ { XK_Page_Up, "PageUp" },
+ { XK_Page_Down, "PageDown" },
+ { XK_Escape, "Esc" },
+ { XK_Right, "Hyre" },
+ { XK_Left, "Venstre" },
+ { XK_Up, "Opp" },
+ { XK_Down, "Ned" },
+ { XK_BackSpace, "Tilbake" },
+ { XK_Return, "Enter" }
+ };
+
+ static const struct KeysymNameReplacement aImplReplacements_Swedish[] =
+ {
+ { XK_Shift_L, "Skift" },
+ { XK_Shift_R, "Skift" },
+ { XK_Page_Up, "PageUp" },
+ { XK_Page_Down, "PageDown" },
+ { XK_Escape, "Esc" },
+ { XK_Right, "Hger" },
+ { XK_Left, "Vnster" },
+ { XK_Up, "Up" },
+ { XK_Down, "Ned" },
+ { XK_BackSpace, "Backsteg" },
+ { XK_Return, "Retur" },
+ { XK_space, "Blank" }
+ };
+
+ static const struct KeysymNameReplacement aImplReplacements_Portuguese[] =
+ {
+ { XK_Page_Up, "PageUp" },
+ { XK_Page_Down, "PageDown" },
+ { XK_Escape, "Esc" },
+ { XK_Right, "Direita" },
+ { XK_Left, "Esquerda" },
+ { XK_Up, "Acima" },
+ { XK_Down, "Abaixo" },
+ { XK_BackSpace, "Rckschritt" },
+ { XK_Return, "Eingabe" },
+ { XK_slash, "Schrgstrich" }
+ };
+
+ static const struct KeysymNameReplacement aImplReplacements_Spanish[] =
+ {
+ { XK_Shift_L, "Mayos" },
+ { XK_Shift_R, "Mayos" },
+ { XK_Page_Up, "RePg" },
+ { XK_Page_Down, "AvPg" },
+ { XK_End, "Fin" },
+ { XK_Home, "Inicio" },
+ { XK_Delete, "Supr" },
+ { XK_Escape, "Esc" },
+ { XK_Right, "Hacia la derecha" },
+ { XK_Left, "Hacia la izquierda" },
+ { XK_Up, "Hacia arriba" },
+ { XK_Down, "Hacia abajo" },
+ { XK_BackSpace, "Ret" },
+ { XK_Return, "Entrada" },
+ { XK_space, "Espacio" },
+ { XK_KP_Enter, "Intro" }
+ };
+
+ static const struct KeyboardReplacements aKeyboards[] =
+ {
+#ifdef SOLARIS
+ { "Germany5", aImplReplacements_German, sizeof(aImplReplacements_German)/sizeof(aImplReplacements_German[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Germany4", aImplReplacements_German, sizeof(aImplReplacements_German)/sizeof(aImplReplacements_German[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "France5", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "France6", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "France_x86", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Italy5", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Italy5-Hobo", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Italy4", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Italy6", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Italy_x86", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Netherland4", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Netherland5", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Netherland5-Hobo", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Netherland6", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Netherland_x86", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Norway5", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Norway5-Hobo", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Norway4", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Norway6", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Norway_x86", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Portugal5", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Portugal5-Hobo", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Portugal4", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Portugal6", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Portugal_x86", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Spain5", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Spain5-Hobo", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Spain4", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Spain6", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Spain_x86", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Sweden5", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Sweden5-Hobo", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Sweden4", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Sweden6", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Sweden_x86", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+#endif
+ { "German", aImplReplacements_German, sizeof(aImplReplacements_German)/sizeof(aImplReplacements_German[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "French", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Norwegian", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Swedish", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Portuguese", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Spanish", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]), RTL_TEXTENCODING_ISO_8859_1 },
+ { "Italian", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]), RTL_TEXTENCODING_ISO_8859_1 }
+ };
+
+ String getKeysymReplacementName( const char* pKeyboard, KeySym nSymbol )
+ {
+ for( int n = 0; n < sizeof(aKeyboards)/sizeof(aKeyboards[0]); n++ )
+ {
+ if( ! strcasecmp( pKeyboard, aKeyboards[n].pKeyboardName ) )
+ {
+ const struct KeysymNameReplacement* pRepl = aKeyboards[n].pReplacements;
+ for( int m = aKeyboards[n].nReplacements ; m ; )
+ {
+ if( nSymbol == pRepl[--m].aSymbol )
+ return String( pRepl[m].pName, aKeyboards[n].nEncoding );
+ }
+ }
+ }
+ return String();
+ }
+
+}
+
+#ifdef SOLARIS
+typedef struct {
+ int n_layout;
+ const char* p_description;
+} keyboard_layout;
+
+static const keyboard_layout type0_layout[] =
+{
+ { 0, "US4" },
+ { -1, NULL }
+};
+
+static const keyboard_layout type3_layout[] =
+{
+ { 0, "US3" },
+ { -1, NULL }
+};
+
+static const keyboard_layout type4_layout[] =
+{
+ { 0, "US4" },
+ { 1, "US4" },
+ { 2, "FranceBelg4" },
+ { 3, "Canada4" },
+ { 4, "Denmark4" },
+ { 5, "Germany4" },
+ { 6, "Italy4" },
+ { 7, "Netherland4" },
+ { 8, "Norway4" },
+ { 9, "Portugal4" },
+ { 10, "SpainLatAm4" },
+ { 11, "SwedenFin4" },
+ { 12, "Switzer_Fr4" },
+ { 13, "Switzer_Ge4" },
+ { 14, "UK4" },
+ { 16, "Korea4" },
+ { 17, "Taiwan4" },
+ { 19, "US101A_PC" },
+ { 19, "US101A_Sun" },
+ { 32, "Japan4" },
+ { 33, "US5" },
+ { 34, "US_UNIX5" },
+ { 35, "France5" },
+ { 36, "Denmark5" },
+ { 37, "Germany5" },
+ { 38, "Italy5" },
+ { 39, "Netherland5" },
+ { 40, "Norway5" },
+ { 41, "Portugal5" },
+ { 42, "Spain5" },
+ { 43, "Sweden5" },
+ { 44, "Switzer_Fr5" },
+ { 45, "Switzer_Ge5" },
+ { 46, "UK5" },
+ { 47, "Korea5" },
+ { 48, "Taiwan5" },
+ { 49, "Japan5" },
+ { 50, "Canada_Fr5" },
+ { 51, "Hungary5" },
+ { 52, "Poland5" },
+ { 53, "Czech5" },
+ { 54, "Russia5" },
+ { 55, "Latvia5" },
+ { 56, "Turkey5" },
+ { 57, "Greece5" },
+ { 58, "Estonia5" },
+ { 59, "Lithuania5" },
+ { 63, "Canada_Fr5_TBITS5" },
+ { 80, "US5_Hobo" },
+ { 81, "US_UNIX5_Hobo" },
+ { 82, "France5_Hobo" },
+ { 83, "Denmark5_Hobo" },
+ { 84, "Germany5_Hobo" },
+ { 85, "Italy5_Hobo" },
+ { 86, "Netherland5_Hobo" },
+ { 87, "Norway5_Hobo" },
+ { 88, "Portugal5_Hobo" },
+ { 89, "Spain5_Hobo" },
+ { 90, "Sweden5_Hobo" },
+ { 91, "Switzer_Fr5_Hobo" },
+ { 92, "Switzer_Ge5_Hobo" },
+ { 93, "UK5_Hobo" },
+ { 94, "Korea5_Hobo" },
+ { 95, "Taiwan5_Hobo" },
+ { 96, "Japan5_Hobo" },
+ { 97, "Canada_Fr5_Hobo" },
+ { -1, NULL }
+};
+
+static const keyboard_layout type101_layout[] =
+{
+ { 0, "US101A_x86" },
+ { 1, "US101A_x86" },
+ { 34, "J3100_x86" },
+ { 35, "France_x86" },
+ { 36, "Denmark_x86" },
+ { 37, "Germany_x86" },
+ { 38, "Italy_x86" },
+ { 39, "Netherland_x86" },
+ { 40, "Norway_x86" },
+ { 41, "Portugal_x86" },
+ { 42, "Spain_x86" },
+ { 43, "Sweden_x86" },
+ { 44, "Switzer_Fr_x86" },
+ { 45, "Switzer_Ge_x86" },
+ { 46, "UK_x86" },
+ { 47, "Korea_x86" },
+ { 48, "Taiwan_x86" },
+ { 49, "Japan_x86" },
+ { 50, "Canada_Fr2_x86" },
+ { 51, "Hungary_x86" },
+ { 52, "Poland_x86" },
+ { 53, "Czech_x86" },
+ { 54, "Russia_x86" },
+ { 55, "Latvia_x86" },
+ { 56, "Turkey_x86" },
+ { 57, "Greece_x86" },
+ { 59, "Lithuania_x86" },
+ { 1001, "MS_US101A_x86" },
+ { -1, NULL }
+};
+
+static const keyboard_layout type6_layout[] =
+{
+ { 0, "US6" },
+ { 6, "Denmark6" },
+ { 7, "Finnish6" },
+ { 8, "France6" },
+ { 9, "Germany6" },
+ { 14, "Italy6" },
+ { 15, "Japan6" },
+ { 16, "Korea6" },
+ { 18, "Netherland6" },
+ { 19, "Norway6" },
+ { 22, "Portugal6" },
+ { 25, "Spain6" },
+ { 26, "Sweden6" },
+ { 27, "Switzer_Fr6" },
+ { 28, "Switzer_Ge6" },
+ { 30, "Taiwan6" },
+ { 32, "UK6" },
+ { 33, "US6" },
+ { -1, NULL }
+};
+#endif
+
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+const char* SalDisplay::GetKeyboardName( BOOL bRefresh )
+{
+ if( bRefresh || ! m_aKeyboardName.Len() )
+ {
+#ifdef SOLARIS
+ if( IsLocal() )
+ {
+ int kbd = open( "/dev/kbd", O_RDONLY );
+ if( kbd >= 0 )
+ {
+ int kbd_type = 0;
+ if( ! ioctl( kbd, KIOCTYPE, &kbd_type ) )
+ {
+ int kbd_layout = 0;
+ if( ! ioctl( kbd, KIOCLAYOUT, &kbd_layout ) )
+ {
+ const keyboard_layout *p_layout = NULL;
+ switch( kbd_type )
+ {
+ case KB_KLUNK: p_layout = type0_layout; break;
+ case KB_SUN3: p_layout = type3_layout; break;
+ case KB_SUN4: p_layout = type4_layout; break;
+ case KB_USB: p_layout = type6_layout; break;
+ case KB_PC: p_layout = type101_layout; break;
+ }
+
+ if( p_layout )
+ {
+ while( p_layout->n_layout != -1 )
+ {
+ if ( p_layout->n_layout == kbd_layout )
+ {
+ m_aKeyboardName = p_layout->p_description;
+ break;
+ }
+ p_layout++;
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+ int opcode, event, error;
+ int major = XkbMajorVersion, minor = XkbMinorVersion;
+ if( ! m_aKeyboardName.Len() &&
+ XSalIsDisplay( GetDisplay() ) &&
+ XkbQueryExtension( GetDisplay(), &opcode, &event,&error, &major, &minor ) )
+ {
+ XkbDescPtr pXkbDesc = NULL;
+ // try X keyboard extension
+ if( pXkbDesc = XkbGetKeyboard( GetDisplay(), XkbAllComponentsMask, XkbUseCoreKbd ) )
+ {
+ const char* pAtom = XGetAtomName( GetDisplay(), pXkbDesc->names->groups[0] );
+ m_aKeyboardName = pAtom;
+ XFree( (void*)pAtom );
+
+#ifdef DEBUG
+#define PRINT_ATOM( x ) { if( pXkbDesc->names->x ) { pAtom = XGetAtomName( GetDisplay(), pXkbDesc->names->x ); fprintf( stderr, "%s: %s\n", #x, pAtom ); XFree( (void*)pAtom ); } else fprintf( stderr, "%s: <nil>\n", #x ); }
+
+ PRINT_ATOM( keycodes );
+ PRINT_ATOM( geometry );
+ PRINT_ATOM( symbols );
+ PRINT_ATOM( types );
+ PRINT_ATOM( compat );
+ PRINT_ATOM( phys_symbols );
+
+ int i;
+ for( i = 0; i < XkbNumVirtualMods; i++ )
+ PRINT_ATOM( vmods[i] );
+ for( i = 0; i < XkbNumIndicators; i++ )
+ PRINT_ATOM( indicators[i] );
+ for( i = 0; i < XkbNumKbdGroups; i++ )
+ PRINT_ATOM( groups[i] );
+#endif
+ XkbFreeKeyboard( pXkbDesc, 0, True );
+ }
+ }
+#endif
+ }
+ return m_aKeyboardName.GetBuffer();
+}
diff --git a/vcl/unx/source/app/makefile.mk b/vcl/unx/source/app/makefile.mk
new file mode 100644
index 000000000000..c532bcd1a836
--- /dev/null
+++ b/vcl/unx/source/app/makefile.mk
@@ -0,0 +1,142 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salapp
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(OS)"=="MACOSX"
+
+dummy:
+ @echo "Nothing to build for Mac OS X"
+
+.ELSE # "$(OS)"=="MACOSX"
+
+.IF "$(remote)"==""
+OBJFILES=\
+ $(OBJ)$/salmain.obj
+
+SLOFILES=\
+ $(SLO)$/i18n_cb.obj \
+ $(SLO)$/i18n_ic.obj \
+ $(SLO)$/i18n_im.obj \
+ $(SLO)$/i18n_xkb.obj \
+ $(SLO)$/i18n_wrp.obj \
+ $(SLO)$/salmain.obj \
+ $(SLO)$/saldata.obj \
+ $(SLO)$/saltimer.obj \
+ $(SLO)$/saldisp.obj \
+ $(SLO)$/salinst.obj \
+ $(SLO)$/salsound2.obj \
+ $(SLO)$/audioconvert.obj \
+ $(SLO)$/osssound.obj \
+ $(SLO)$/devaudiosound.obj \
+ $(SLO)$/rptpsound.obj \
+ $(SLO)$/nassound.obj \
+ $(SLO)$/salsys.obj \
+ $(SLO)$/soicon.obj \
+ $(SLO)$/sm.obj \
+ $(SLO)$/stacktrace.obj \
+ $(SLO)$/keysymnames.obj
+
+.IF "$(OS)$(CPU)" == "SOLARISS"
+.IF "$(COM)"!="GCC"
+SLOFILES+=$(SLO)$/getfpsols.obj
+.ENDIF # "$(COM)"!="GCC"
+.ELIF "$(OS)$(CPU)" == "SOLARISI"
+SLOFILES+=$(SLO)$/getfpsoli.obj
+.ENDIF
+
+.ELSE
+SLOFILES=\
+ $(SLO)$/salmain.obj
+.ENDIF
+
+.IF "$(remote)"!=""
+EXCEPTIONSFILES=$(SLO)$/salmain.obj \
+ $(OBJ)$/salmain.obj
+.ENDIF
+
+.ENDIF # "$(OS)"=="MACOSX"
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
+
+$(SLO)$/getfpsols.obj: getfpsols.s
+ CC -c -o $(SLO)$/getfpsols.o getfpsols.s && touch $(SLO)$/getfpsols.obj
+
+$(SLO)$/getfpsoli.obj: getfpsoli.s
+ CC -c -o $(SLO)$/getfpsoli.o getfpsoli.s && touch $(SLO)$/getfpsoli.obj
+
diff --git a/vcl/unx/source/app/saldata.cxx b/vcl/unx/source/app/saldata.cxx
new file mode 100644
index 000000000000..4519e75fd56f
--- /dev/null
+++ b/vcl/unx/source/app/saldata.cxx
@@ -0,0 +1,854 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldata.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALDATA_CXX
+
+#ifdef USE_XTOOLKIT
+# define SAL_XT
+#endif
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sys/resource.h>
+#ifdef SUN
+#include <sys/systeminfo.h>
+#endif
+#ifdef AIX
+#include <strings.h>
+#endif
+
+#include <prex.h>
+#include <X11/Shell.h>
+#include <X11/Xproto.h>
+#include <postx.h>
+
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#include <salunx.h>
+
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _OSL_SIGNAL_H_
+#include <osl/signal.h>
+#endif
+#ifndef _OSL_THREAD_H_
+#include <osl/thread.h>
+#endif
+#ifndef _OSL_PROCESS_H_
+#include <osl/process.h>
+#endif
+
+#include <tools/debug.hxx>
+
+#ifndef _SAL_I18N_INPUTMETHOD_HXX
+#include "i18n_im.hxx"
+#endif
+#ifndef _SAL_I18N_XKBDEXTENSION_HXX
+#include "i18n_xkb.hxx"
+#endif
+
+// -=-= <signal.h> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef UNX
+#ifndef SIGBUS
+#define SIGBUS 10
+#endif
+#ifndef SIGSEGV
+#define SIGSEGV 11
+#endif
+#ifndef SIGIOT
+#define SIGIOT SIGABRT
+#endif
+#endif
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+static const struct timeval noyield = { 0, 0 };
+static const struct timeval yield = { 0, 10000 };
+static const struct fd_set ZeroFDS = { 0 };
+static const char* XRequest[] = {
+ // see /usr/lib/X11/XErrorDB, /usr/openwin/lib/XErrorDB ...
+ NULL,
+ "X_CreateWindow",
+ "X_ChangeWindowAttributes",
+ "X_GetWindowAttributes",
+ "X_DestroyWindow",
+ "X_DestroySubwindows",
+ "X_ChangeSaveSet",
+ "X_ReparentWindow",
+ "X_MapWindow",
+ "X_MapSubwindows",
+ "X_UnmapWindow",
+ "X_UnmapSubwindows",
+ "X_ConfigureWindow",
+ "X_CirculateWindow",
+ "X_GetGeometry",
+ "X_QueryTree",
+ "X_InternAtom",
+ "X_GetAtomName",
+ "X_ChangeProperty",
+ "X_DeleteProperty",
+ "X_GetProperty",
+ "X_ListProperties",
+ "X_SetSelectionOwner",
+ "X_GetSelectionOwner",
+ "X_ConvertSelection",
+ "X_SendEvent",
+ "X_GrabPointer",
+ "X_UngrabPointer",
+ "X_GrabButton",
+ "X_UngrabButton",
+ "X_ChangeActivePointerGrab",
+ "X_GrabKeyboard",
+ "X_UngrabKeyboard",
+ "X_GrabKey",
+ "X_UngrabKey",
+ "X_AllowEvents",
+ "X_GrabServer",
+ "X_UngrabServer",
+ "X_QueryPointer",
+ "X_GetMotionEvents",
+ "X_TranslateCoords",
+ "X_WarpPointer",
+ "X_SetInputFocus",
+ "X_GetInputFocus",
+ "X_QueryKeymap",
+ "X_OpenFont",
+ "X_CloseFont",
+ "X_QueryFont",
+ "X_QueryTextExtents",
+ "X_ListFonts",
+ "X_ListFontsWithInfo",
+ "X_SetFontPath",
+ "X_GetFontPath",
+ "X_CreatePixmap",
+ "X_FreePixmap",
+ "X_CreateGC",
+ "X_ChangeGC",
+ "X_CopyGC",
+ "X_SetDashes",
+ "X_SetClipRectangles",
+ "X_FreeGC",
+ "X_ClearArea",
+ "X_CopyArea",
+ "X_CopyPlane",
+ "X_PolyPoint",
+ "X_PolyLine",
+ "X_PolySegment",
+ "X_PolyRectangle",
+ "X_PolyArc",
+ "X_FillPoly",
+ "X_PolyFillRectangle",
+ "X_PolyFillArc",
+ "X_PutImage",
+ "X_GetImage",
+ "X_PolyText8",
+ "X_PolyText16",
+ "X_ImageText8",
+ "X_ImageText16",
+ "X_CreateColormap",
+ "X_FreeColormap",
+ "X_CopyColormapAndFree",
+ "X_InstallColormap",
+ "X_UninstallColormap",
+ "X_ListInstalledColormaps",
+ "X_AllocColor",
+ "X_AllocNamedColor",
+ "X_AllocColorCells",
+ "X_AllocColorPlanes",
+ "X_FreeColors",
+ "X_StoreColors",
+ "X_StoreNamedColor",
+ "X_QueryColors",
+ "X_LookupColor",
+ "X_CreateCursor",
+ "X_CreateGlyphCursor",
+ "X_FreeCursor",
+ "X_RecolorCursor",
+ "X_QueryBestSize",
+ "X_QueryExtension",
+ "X_ListExtensions",
+ "X_ChangeKeyboardMapping",
+ "X_GetKeyboardMapping",
+ "X_ChangeKeyboardControl",
+ "X_GetKeyboardControl",
+ "X_Bell",
+ "X_ChangePointerControl",
+ "X_GetPointerControl",
+ "X_SetScreenSaver",
+ "X_GetScreenSaver",
+ "X_ChangeHosts",
+ "X_ListHosts",
+ "X_SetAccessControl",
+ "X_SetCloseDownMode",
+ "X_KillClient",
+ "X_RotateProperties",
+ "X_ForceScreenSaver",
+ "X_SetPointerMapping",
+ "X_GetPointerMapping",
+ "X_SetModifierMapping",
+ "X_GetModifierMapping",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "X_NoOperation"
+};
+
+BEGIN_C
+// -=-= C statics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+static oslSignalAction SalSignalHdl (void* pData, oslSignalInfo* pInfo)
+{
+ ULONG nException = 0;
+
+ switch (pInfo->Signal)
+ {
+ case osl_Signal_System :
+ return osl_Signal_ActCallNextHdl;
+ case osl_Signal_Terminate :
+ if (!GetSalData()->Close())
+ return osl_Signal_ActIgnore;
+ break;
+ case osl_Signal_User :
+ return osl_Signal_ActCallNextHdl;
+ default: break;
+ }
+
+ return osl_Signal_ActAbortApp;
+}
+
+
+final static int sal_XErrorHdl( Display *pDisplay, XErrorEvent *pEvent )
+{
+ GetSalData()->XError( pDisplay, pEvent );
+ return 0;
+}
+
+final static int sal_XIOErrorHdl( Display *pDisplay )
+{
+ SalData *pSalData = GetSalData();
+ SalDisplay *pSalDisplay = pSalData->GetDisplay( pDisplay );
+ if ( pDisplay && pSalDisplay->IsDisplay() )
+ pSalData->GetLib()->Remove( ConnectionNumber( pDisplay ) );
+
+ oslSignalAction eToDo = osl_raiseSignal (OSL_SIGNAL_USER_X11SUBSYSTEMERROR, NULL);
+ // einen XIOError kann man nicht ignorieren. Die Connection ist
+ // zusammengebrochen, hier kann man nur noch halbwegs sinnvoll runterfahren
+
+ fprintf( stderr, "X IO Error\n" );
+ fflush( stdout );
+ fflush( stderr );
+ exit(0);
+ return 0;
+}
+
+final static void sal_XtErrorHdl( XLIB_String sMsg )
+{
+#ifdef DBG_UTIL
+ fprintf( stderr, "X Toolkit Error: %s\n", sMsg );
+#endif
+ fflush( stdout );
+ fflush( stderr );
+ abort();
+}
+
+final static void sal_XtWarningHdl( XLIB_String sMsg )
+{
+#ifdef DBG_UTIL
+ fprintf( stderr, "X Toolkit Warning: %s\n", sMsg );
+ fflush( stdout );
+ fflush( stderr );
+#endif
+}
+
+END_C
+
+// -=-= SalData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <pthread.h>
+
+final SalData::SalData()
+{
+ argv_ = 0;
+ argc_ = 0;
+
+ pTimerProc_ = 0;
+
+ memset( sig_, 0, sizeof( sig_ ) ); // SIG_DFL
+ bNoExceptions_ = !!getenv( "SAL_NOSEGV" );
+
+ pXLib_ = new SalXLib();
+ pDefDisp_ = 0;
+ pCurDisp_ = 0;
+
+ hMainThread_ = pthread_self();
+
+ pFirstInstance_ = NULL;
+ pFirstFrame_ = NULL;
+}
+
+final SalData::~SalData()
+{
+ delete pXLib_;
+}
+
+final long SalData::Close() const
+{
+ signal( SIGTERM, sig_[SIGTERM] );
+ if( !pFirstFrame_ )
+ return 1;
+
+ SalFrame *pFrame = pFirstFrame_;
+ while( pFrame )
+ {
+ if( !pFrame->maFrameData.Close() )
+ return 0;
+ pFrame = pFrame->maFrameData.GetNextFrame();
+ }
+ return 1;
+}
+
+final long SalData::ShutDown() const
+{
+ if( !pFirstFrame_ )
+ return 1;
+
+ SalFrame *pFrame = pFirstFrame_;
+ while( pFrame )
+ {
+ if( !pFrame->maFrameData.ShutDown() )
+ return 0;
+ pFrame = pFrame->maFrameData.GetNextFrame();
+ }
+ return 1;
+}
+
+final XubString SalData::GetCommandLineParam( USHORT nParam ) const
+{
+ if( !nParam ) { return aBinaryPath_; }
+ if( nParam >= argc_ ) return String();
+ return String( argv_[nParam], gsl_getSystemTextEncoding() );
+}
+
+final SalDisplay *SalData::GetDisplay( Display *pDisplay )
+{
+ SalDisplay *pSalDisplay = SalDisplays_.First();
+ while( pSalDisplay && pSalDisplay->GetDisplay() != pDisplay )
+ pSalDisplay = SalDisplays_.Next();
+ return pSalDisplay;
+}
+
+void SalData::Init( int *pArgc, char *ppArgv[] )
+{
+ // Pfad zum Executable bestimmen
+ char aFilePath[ PATH_MAX ];
+ ::rtl::OUString aPath;
+ osl_getExecutableFile( &aPath.pData );
+
+ aBinaryPath_ = aPath;
+
+ pXLib_->Init( pArgc, ppArgv );
+
+ argc_ = *pArgc;
+ argv_ = ppArgv;
+}
+
+
+// -=-= SalXLib =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalXLib::SalXLib()
+{
+ pApplicationContext_ = NULL;
+ Timeout_.tv_sec = 0;
+ Timeout_.tv_usec = 0;
+ nTimeoutMS_ = 0;
+ bWasXError_ = FALSE;
+ bIgnoreXErrors_ = !!getenv( "SAL_IGNOREXERRORS" );
+ nStateOfYield_ = 0;
+ nFDs_ = 0;
+ pReadFDS_ = new fd_set;
+ pExceptionFDS_ = new fd_set;
+ FD_ZERO( pReadFDS_ );
+ FD_ZERO( pExceptionFDS_ );
+}
+
+final SalXLib::~SalXLib()
+{
+ delete pReadFDS_;
+ delete pExceptionFDS_;
+
+// completetly disabled Bug Nr. #47319 -> segv while using xsuntransport=shmem
+// #ifdef SAL_XT
+// XtDestroyApplicationContext( pApplicationContext_ );
+// #endif
+}
+
+static char sDISPLAY___[30];
+final void SalXLib::Init( int *pArgc, char *ppArgv[] )
+{
+ SalData *pSalData = GetSalData();
+ SalI18N_InputMethod* pInputMethod = new SalI18N_InputMethod;
+
+ pInputMethod->SetLocale();
+
+ if( !getenv( "DISPLAY" ) )
+ putenv( "DISPLAY=:0" );
+
+ XtSetLanguageProc( NULL, NULL, NULL );
+ XtToolkitInitialize();
+ XrmInitialize();
+ pApplicationContext_ = XtCreateApplicationContext();
+
+ Display *pDisp = XtOpenDisplay( pApplicationContext_,
+ NULL,
+ NULL,
+ "VCL",
+ NULL,
+ 0,
+ pArgc,
+ ppArgv );
+
+ if( !pDisp )
+ {
+ char *pDisplayString = getenv ("DISPLAY");
+
+ fprintf( stderr, "%s: cannot open display \"%s\"\n",
+ ppArgv[0],
+ pDisplayString ? pDisplayString : ":0.0" );
+ fprintf( stderr, "Please check your \"DISPLAY\" environment variable, as well as the permissions to access that display ");
+ fprintf( stderr, "(See \"man X\" resp. \"man xhost\" for details)\n");
+ fflush ( stderr );
+ exit (0);
+ }
+
+ XVisualInfo aVI;
+ Colormap aColMap;
+ int nScreen = DefaultScreen( pDisp );
+
+ if( SalDisplay::BestVisual( pDisp, nScreen, aVI ) ) // DefaultVisual
+ aColMap = DefaultColormap( pDisp, nScreen );
+ else
+ aColMap = XCreateColormap( pDisp,
+ RootWindow( pDisp, nScreen ),
+ aVI.visual,
+ AllocNone );
+
+ Arg aArgs[10];
+ int nArgs = 0;
+ XtSetArg( aArgs[nArgs], XtNvisual, aVI.visual ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNdepth, aVI.depth ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNcolormap, aColMap ); nArgs++;
+
+ Widget wInitWidget = XtAppCreateShell( NULL,
+ "SAL",
+ applicationShellWidgetClass,
+ pDisp,
+ aArgs, nArgs );
+
+
+ XSetIOErrorHandler ( (XIOErrorHandler)sal_XIOErrorHdl );
+ XSetErrorHandler ( (XErrorHandler)sal_XErrorHdl );
+
+ XtAppSetErrorHandler ( GetAppContext(),
+ (XtErrorHandler)sal_XtErrorHdl );
+ XtAppSetWarningHandler( GetAppContext(),
+ (XtErrorHandler)sal_XtWarningHdl );
+
+ SalDisplay *pSalDisplay = new SalDisplay( wInitWidget );
+
+ pInputMethod->CreateMethod( pDisp );
+ pSalDisplay->SetInputMethod( pInputMethod );
+
+ sal_Bool bOldErrorSetting = GetIgnoreXErrors();
+ SetIgnoreXErrors( True );
+ SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp );
+ XSync( pDisp, False );
+
+ pKbdExtension->UseExtension( ! WasXError() );
+ SetIgnoreXErrors( bOldErrorSetting );
+
+ pSalDisplay->SetKbdExtension( pKbdExtension );
+
+#if 0 // ! USE_XTOOLKIT
+
+ SalDisplay *pSalDisplay = new SalDisplay( pDisp, aVI.visual, aColMap );
+
+#endif
+}
+
+extern "C" {
+void EmitFontpathWarning( void )
+{
+ static Bool bOnce = False;
+ if ( !bOnce )
+ {
+ bOnce = True;
+ fprintf( stderr, "Please verify your fontpath settings\n"
+ "\t(See \"man xset\" for details"
+ " or ask your system administrator)\n" );
+ }
+}
+
+} /* extern "C" */
+
+final void SalXLib::XError( Display *pDisplay, XErrorEvent *pEvent )
+{
+ char msg[ 120 ];
+
+ if( ! bIgnoreXErrors_ )
+ {
+#if defined DEBUG || defined DBG_UTIL
+ XGetErrorText( pDisplay, pEvent->error_code, msg, sizeof( msg ) );
+ fprintf( stderr, "X-Error: %s\n", msg );
+ if( pEvent->request_code > capacityof( XRequest ) )
+ fprintf( stderr, "\tMajor opcode: %d (Shm?)\n", pEvent->request_code );
+ else if( XRequest[pEvent->request_code] )
+ fprintf( stderr, "\tMajor opcode: %d (%s)\n",
+ pEvent->request_code, XRequest[pEvent->request_code] );
+ else
+ fprintf( stderr, "\tMajor opcode: %d (BadRequest?)\n", pEvent->request_code );
+ fprintf( stderr, "\tResource ID: 0x%lx\n",
+ pEvent->resourceid );
+ fprintf( stderr, "\tSerial No: %ld (%ld)\n",
+ pEvent->serial, LastKnownRequestProcessed(pDisplay) );
+
+ fflush( stdout );
+ fflush( stderr );
+#endif
+
+ oslSignalAction eToDo = osl_raiseSignal (OSL_SIGNAL_USER_X11SUBSYSTEMERROR, NULL);
+ switch (eToDo)
+ {
+ case osl_Signal_ActIgnore :
+ return;
+ case osl_Signal_ActAbortApp :
+ abort();
+ case osl_Signal_ActKillApp :
+ exit(0);
+ case osl_Signal_ActCallNextHdl :
+ break;
+ default :
+ break;
+ }
+
+ if ( (pEvent->error_code == BadAlloc)
+ && (pEvent->request_code == X_OpenFont) )
+ {
+ static Bool bOnce = False;
+ if ( !bOnce )
+ {
+ fprintf(stderr, "X-Error occured in a request for X_OpenFont\n");
+ EmitFontpathWarning();
+
+ bOnce = True ;
+ }
+ }
+ else
+ {
+ abort();
+ }
+ }
+
+ bWasXError_ = TRUE;
+}
+
+#define MAX_NUM_DESCRIPTORS 128
+
+struct YieldEntry
+{
+ YieldEntry* next; // pointer to next entry
+ int fd; // file descriptor for reading
+ void* data; // data for predicate and callback
+ YieldFunc pending; // predicate (determins pending events)
+ YieldFunc queued; // read and queue up events
+ YieldFunc handle; // handle pending events
+
+ inline int HasPendingEvent() const { return pending( fd, data ); }
+ inline int IsEventQueued() const { return queued( fd, data ); }
+ inline void HandleNextEvent() const { handle( fd, data ); }
+};
+
+#define MAX_NUM_DESCRIPTORS 128
+
+static YieldEntry yieldTable[ MAX_NUM_DESCRIPTORS ];
+
+void SalXLib::Insert( int nFD, void* data,
+ YieldFunc pending,
+ YieldFunc queued,
+ YieldFunc handle )
+{
+ DBG_ASSERT( nFD, "can not insert stdin descriptor" )
+ DBG_ASSERT( !yieldTable[nFD].fd, "SalXLib::Insert fd twice" )
+
+ yieldTable[nFD].fd = nFD;
+ yieldTable[nFD].data = data;
+ yieldTable[nFD].pending = pending;
+ yieldTable[nFD].queued = queued;
+ yieldTable[nFD].handle = handle;
+
+ FD_SET( nFD, pReadFDS_ );
+ FD_SET( nFD, pExceptionFDS_ );
+
+ if( nFD >= nFDs_ )
+ nFDs_ = nFD + 1;
+}
+
+void SalXLib::Remove( int nFD )
+{
+ FD_CLR( nFD, pReadFDS_ );
+ FD_CLR( nFD, pExceptionFDS_ );
+
+ yieldTable[nFD].fd = 0;
+
+ if ( nFD == nFDs_ )
+ {
+ for ( nFD = nFDs_ - 1;
+ nFD >= 0 && !yieldTable[nFD].fd;
+ nFD-- );
+
+ nFDs_ = nFD + 1;
+ }
+}
+
+class YieldMutexReleaser
+{
+ ULONG m_nYieldCount;
+ SalYieldMutex* m_pSalInstYieldMutex;
+public:
+ YieldMutexReleaser();
+ ~YieldMutexReleaser();
+};
+
+YieldMutexReleaser::YieldMutexReleaser()
+{
+ SalData *pSalData = GetSalData();
+ m_pSalInstYieldMutex =
+ pSalData->pFirstInstance_->maInstData.mpSalYieldMutex;
+
+ ULONG i;
+ if ( m_pSalInstYieldMutex->GetThreadId() ==
+ NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
+ {
+ m_nYieldCount = m_pSalInstYieldMutex->GetAcquireCount();
+ for ( i = 0; i < m_nYieldCount; i++ )
+ m_pSalInstYieldMutex->release();
+ }
+ else
+ m_nYieldCount = 0;
+}
+
+YieldMutexReleaser::~YieldMutexReleaser()
+{
+ // Yield-Semaphore wieder holen
+ while ( m_nYieldCount )
+ {
+ m_pSalInstYieldMutex->acquire();
+ m_nYieldCount--;
+ }
+}
+
+final void SalXLib::Yield( BOOL bWait )
+{
+ fd_set ReadFDS;
+ fd_set ExceptionFDS;
+ int nFound = 0;
+
+ nStateOfYield_ = 0; // is not 0 if we are recursive called
+
+ // first look for queued events
+ for ( int nFD = 0; nFD < nFDs_; nFD++ )
+ {
+ YieldEntry* pEntry = &(yieldTable[nFD]);
+ if ( pEntry->fd )
+ {
+ DBG_ASSERT( nFD == pEntry->fd, "wrong fd in Yield()" );
+
+ if ( pEntry->HasPendingEvent() )
+ {
+ pEntry->HandleNextEvent();
+ // #63862# da jetzt alle user-events ueber die interne
+ // queue kommen, wird die Kontrolle analog zum select
+ // gesteuerten Zweig einmal bei bWait abgegeben
+ YieldMutexReleaser aReleaser;
+ if ( bWait )
+ osl_yieldThread();
+ return;
+ }
+ }
+ }
+
+ // next select with or without timeout according to bWait
+
+ ReadFDS = *pReadFDS_;
+ ExceptionFDS = *pExceptionFDS_;
+
+ struct timeval Timeout;
+ Timeout = bWait ? yield : noyield;
+
+ nStateOfYield_ = 1;
+
+ {
+ // Yield-Semaphore freigeben
+ YieldMutexReleaser aReleaser;
+ if( bWait )
+ osl_yieldThread();
+#if defined (HPUX) && defined (CMA_UX)
+ nFound = select( nFDs_, (int*)&ReadFDS, (int*)NULL,
+ (int*)&ExceptionFDS, &Timeout );
+#else
+ nFound = select( nFDs_, &ReadFDS, NULL, &ExceptionFDS, &Timeout );
+#endif
+ }
+ if( nFound < 0 ) // error
+ {
+#ifdef DBG_UTIL
+ fprintf( stderr, "SalXLib::Yield s=%d e=%d f=%d\n",
+ nStateOfYield_, errno, nFound );
+#endif
+ nStateOfYield_ = 0;
+ if( EINTR == errno )
+ {
+ errno = 0;
+ }
+ }
+
+ // check for timeouts
+ if( Timeout_.tv_sec ) // timer is started
+ {
+ gettimeofday( &Timeout, NULL );
+
+ if( Timeout >= Timeout_ )
+ {
+ Timeout_ = Timeout + nTimeoutMS_;
+ GetSalData()->Timeout();
+ }
+ }
+
+ // handle events
+ if( nFound > 0 )
+ {
+ // now we are in the protected section !
+ // recall select if we have acquired fd's, ready for reading,
+
+ struct timeval noTimeout = { 0, 0 };
+ nFound = select( nFDs_, &ReadFDS, NULL,
+ &ExceptionFDS, &noTimeout );
+
+ // someone-else has done the job for us
+ if (nFound == 0)
+ {
+ nStateOfYield_ = 0;
+ //if ( !pthread_equal (pthread_self(),
+ // pSalData->GetMainThread()))
+ return;
+ }
+
+ for ( int nFD = 0; nFD < nFDs_; nFD++ )
+ {
+ YieldEntry* pEntry = &(yieldTable[nFD]);
+ if ( pEntry->fd )
+ {
+ if ( FD_ISSET( nFD, &ExceptionFDS ) ) {
+#if defined DEBUG
+ fprintf( stderr, "SalXLib::Yield exception\n" );
+#endif
+ nFound--;
+ }
+ if ( FD_ISSET( nFD, &ReadFDS ) )
+ {
+ nStateOfYield_ = 3;
+ if ( pEntry->IsEventQueued() )
+ {
+ nStateOfYield_ = 4;
+ pEntry->HandleNextEvent();
+ // if a recursive call has done the job
+ // so abort here
+ if ( nStateOfYield_ != 4 )
+ break;
+ }
+ nFound--;
+ }
+ }
+ }
+ }
+ nStateOfYield_ = 0;
+}
+
diff --git a/vcl/unx/source/app/saldisp.cxx b/vcl/unx/source/app/saldisp.cxx
new file mode 100644
index 000000000000..5c7ca51b0a6b
--- /dev/null
+++ b/vcl/unx/source/app/saldisp.cxx
@@ -0,0 +1,3653 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldisp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALDISP_CXX
+
+#define SAL_XT
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+
+#ifdef __SunOS_5_5_1
+extern "C" { int gethostname(char*,int); }
+#endif
+
+#include <prex.h>
+#include <X11/cursorfont.h>
+#include "nodrop_curs.h"
+#include "nodrop_mask.h"
+#include "wait_curs.h"
+#include "wait_mask.h"
+#include "hsplit_curs.h"
+#include "hsplit_mask.h"
+#include "vsplit_curs.h"
+#include "vsplit_mask.h"
+#include "neswsize_curs.h"
+#include "neswsize_mask.h"
+#include "nwsesize_curs.h"
+#include "nwsesize_mask.h"
+#include "magnify_curs.h"
+#include "magnify_mask.h"
+#include "rotate_curs.h"
+#include "rotate_mask.h"
+#include "hshear_curs.h"
+#include "hshear_mask.h"
+#include "vshear_curs.h"
+#include "vshear_mask.h"
+#include "drawline_curs.h"
+#include "drawline_mask.h"
+#include "drawrect_curs.h"
+#include "drawrect_mask.h"
+#include "drawpolygon_curs.h"
+#include "drawpolygon_mask.h"
+#include "drawbezier_curs.h"
+#include "drawbezier_mask.h"
+#include "drawarc_curs.h"
+#include "drawarc_mask.h"
+#include "drawpie_curs.h"
+#include "drawpie_mask.h"
+#include "drawcirclecut_curs.h"
+#include "drawcirclecut_mask.h"
+#include "drawellipse_curs.h"
+#include "drawellipse_mask.h"
+#include "drawconnect_curs.h"
+#include "drawconnect_mask.h"
+#include "drawtext_curs.h"
+#include "drawtext_mask.h"
+#include "mirror_curs.h"
+#include "mirror_mask.h"
+#include "crook_curs.h"
+#include "crook_mask.h"
+#include "crop_curs.h"
+#include "crop_mask.h"
+#include "move_curs.h"
+#include "move_mask.h"
+#include "movepoint_curs.h"
+#include "movepoint_mask.h"
+#include "movebezierweight_curs.h"
+#include "movebezierweight_mask.h"
+#include "drawfreehand_curs.h"
+#include "drawfreehand_mask.h"
+#include "drawcaption_curs.h"
+#include "drawcaption_mask.h"
+#include "movedata_curs.h"
+#include "movedata_mask.h"
+#include "copydata_curs.h"
+#include "copydata_mask.h"
+#include "linkdata_curs.h"
+#include "linkdata_mask.h"
+#include "movedlnk_curs.h"
+#include "movedlnk_mask.h"
+#include "copydlnk_curs.h"
+#include "copydlnk_mask.h"
+#include "movefile_curs.h"
+#include "movefile_mask.h"
+#include "copyfile_curs.h"
+#include "copyfile_mask.h"
+#include "linkfile_curs.h"
+#include "linkfile_mask.h"
+#include "moveflnk_curs.h"
+#include "moveflnk_mask.h"
+#include "copyflnk_curs.h"
+#include "copyflnk_mask.h"
+#include "movefiles_curs.h"
+#include "movefiles_mask.h"
+#include "copyfiles_curs.h"
+#include "copyfiles_mask.h"
+
+#include "chart_curs.h"
+#include "chart_mask.h"
+#include "detective_curs.h"
+#include "detective_mask.h"
+#include "pivotcol_curs.h"
+#include "pivotcol_mask.h"
+#include "pivotfld_curs.h"
+#include "pivotfld_mask.h"
+#include "pivotrow_curs.h"
+#include "pivotrow_mask.h"
+
+#include "chain_curs.h"
+#include "chain_mask.h"
+#include "chainnot_curs.h"
+#include "chainnot_mask.h"
+
+#include "timemove_curs.h"
+#include "timemove_mask.h"
+#include "timesize_curs.h"
+#include "timesize_mask.h"
+
+#include "ase_curs.h"
+#include "ase_mask.h"
+#include "asn_curs.h"
+#include "asn_mask.h"
+#include "asne_curs.h"
+#include "asne_mask.h"
+#include "asns_curs.h"
+#include "asns_mask.h"
+#include "asnswe_curs.h"
+#include "asnswe_mask.h"
+#include "asnw_curs.h"
+#include "asnw_mask.h"
+#include "ass_curs.h"
+#include "ass_mask.h"
+#include "asse_curs.h"
+#include "asse_mask.h"
+#include "assw_curs.h"
+#include "assw_mask.h"
+#include "asw_curs.h"
+#include "asw_mask.h"
+#include "aswe_curs.h"
+#include "aswe_mask.h"
+#include "null_curs.h"
+#include "null_mask.h"
+
+#include "airbrush_curs.h"
+#include "airbrush_mask.h"
+#include "fill_curs.h"
+#include "fill_mask.h"
+
+#include "invert50.h"
+#if !(defined S390 || defined AIX)
+#include <X11/extensions/XShm.h>
+#endif
+#include <X11/keysym.h>
+
+#ifdef USE_XMU
+#include <X11/Xmu/Atoms.h>
+#include <X11/Xmu/SysUtil.h>
+#endif
+#include <X11/Xatom.h>
+#include <postx.h>
+
+#include <salunx.h>
+
+#ifndef _SAL_I18N_INPUTMETHOD_HXX
+#include "i18n_im.hxx"
+#endif
+#ifndef _SAL_I18N_XKBDEXTENSION_HXX
+#include "i18n_xkb.hxx"
+#endif
+
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_KEYCODES_HXX
+#include <keycodes.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+#ifndef _SV_DTINT_HXX
+#include <dtint.hxx>
+#endif
+#ifndef _SV_SALOGL_HXX
+#include <salogl.hxx>
+#endif
+#ifndef _OSL_THREADMUTEX_H_
+#include <osl/mutex.h>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+#ifndef _VCL_SM_HXX
+#include <sm.hxx>
+#endif
+
+#include <osl/socket.h>
+#include <rtl/ustring>
+
+// -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#define PSEUDOCOLOR12
+#define PSEUDOCOLOR8
+#define TRUECOLOR24
+#define TRUECOLOR16
+#define TRUECOLOR15
+#define TRUECOLOR12
+#define TRUECOLOR8
+
+#define SALCOLOR_WHITE MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF )
+#define SALCOLOR_BLACK MAKE_SALCOLOR( 0x00, 0x00, 0x00 )
+
+// -=-= Prototyps =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+EXTERN_C int XShmGetEventBase( Display* );
+
+// -=-= static variables -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+static const char* const VisualClassName[] = {
+ "StaticGray",
+ "GrayScale",
+ "StaticColor",
+ "PseudoColor",
+ "TrueColor",
+ "DirectColor"
+};
+
+static const char* const AtomStrings[] =
+{
+ "WM_PROTOCOLS", // window manager
+ "WM_STATE",
+ "WM_DELETE_WINDOW",
+ "WM_SAVE_YOURSELF",
+ "WM_COMMAND",
+
+ "SAL_QUITEVENT", // client message events
+ "SAL_USEREVENT",
+};
+
+static const char* const EventNames[] =
+{
+ NULL,
+ NULL,
+ "KeyPress",
+ "KeyRelease",
+ "ButtonPress",
+ "ButtonRelease",
+ "MotionNotify",
+ "EnterNotify",
+ "LeaveNotify",
+ "FocusIn",
+ "FocusOut",
+ "KeymapNotify",
+ "Expose",
+ "GraphicsExpose",
+ "NoExpose",
+ "VisibilityNotify",
+ "CreateNotify",
+ "DestroyNotify",
+ "UnmapNotify",
+ "MapNotify",
+ "MapRequest",
+ "ReparentNotify",
+ "ConfigureNotify",
+ "ConfigureRequest",
+ "GravityNotify",
+ "ResizeRequest",
+ "CirculateNotify",
+ "CirculateRequest",
+ "PropertyNotify",
+ "SelectionClear",
+ "SelectionRequest",
+ "SelectionNotify",
+ "ColormapNotify",
+ "ClientMessage",
+ "MappingNotify"
+};
+
+static UINT32 nIn___, nOut___;
+
+// -=-= global inline =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+inline const char *Null( const char *p ) { return p ? p : ""; }
+inline const char *GetEnv( const char *p ) { return Null( getenv( p ) ); }
+inline const char *KeyStr( KeySym n ) { return Null( XKeysymToString( n ) ); }
+
+#ifdef USE_XMU
+final inline const char *GetAtomName( Display *d, Atom a )
+{ return Null( XmuGetAtomName( d, a ) ); }
+#else
+final inline const char *GetAtomName( Display *d, Atom a )
+{ return Null( XGetAtomName( d, a ) ); }
+#endif
+
+final inline double Hypothenuse( long w, long h )
+{ return sqrt( (w*w)+(h*h) ); }
+
+final inline int ColorDiff( int r, int g, int b )
+{ return (r*r)+(g*g)+(b*b); }
+
+final inline int ColorDiff( SalColor c1, int r, int g, int b )
+{ return ColorDiff( (int)SALCOLOR_RED (c1)-r,
+ (int)SALCOLOR_GREEN(c1)-g,
+ (int)SALCOLOR_BLUE (c1)-b ); }
+
+// -=-= global functions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+static int sal_Shift( Pixel nMask )
+{
+ int i = 24;
+ if( nMask < 0x00010000 ) { nMask <<= 16; i -= 16; }
+ if( nMask < 0x01000000 ) { nMask <<= 8; i -= 8; }
+ if( nMask < 0x10000000 ) { nMask <<= 4; i -= 4; }
+ if( nMask < 0x40000000 ) { nMask <<= 2; i -= 2; }
+ if( nMask < 0x80000000 ) { nMask <<= 1; i -= 1; }
+ return i;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+static BOOL sal_GetVisualInfo( Display *pDisplay, XID nVID, XVisualInfo &rVI )
+{
+ int nInfos;
+ XVisualInfo aTemplate;
+ XVisualInfo*pInfos;
+
+ aTemplate.visualid = nVID;
+
+ pInfos = XGetVisualInfo( pDisplay, VisualIDMask, &aTemplate, &nInfos );
+ if( !pInfos )
+ return FALSE;
+
+ rVI = *pInfos;
+ XFree( pInfos );
+
+ DBG_ASSERT( rVI.visualid == nVID,
+ "sal_GetVisualInfo: could not get correct visual by visualId" )
+ return TRUE;
+}
+
+// ---------------------------------------------------------------------------
+
+// check wether displaystring is in format N.M or N. or just N
+// with N and M beeing natural numbers
+static BOOL
+sal_IsDisplayNumber( const char *pDisplayString )
+{
+ if ( ! isdigit(*pDisplayString) )
+ return FALSE;
+ while ( isdigit(*(++pDisplayString)) )
+ ; /* do nothing */
+
+ if ( *pDisplayString == '.' )
+ {
+ while ( isdigit(*(++pDisplayString)) )
+ ; /* do nothing */
+ }
+
+ return (*pDisplayString == '\0');
+}
+
+// check whether host1 and host2 point to the same ip address
+static BOOL
+sal_EqualHosts( const ::rtl::OUString& Host1, const ::rtl::OUString& Host2)
+{
+ oslSocketAddr pHostAddr1;
+ oslSocketAddr pHostAddr2;
+ BOOL bEqualAddress;
+
+ if ( Host1.toChar() >= '0' && Host1.toChar() <= '9' )
+ pHostAddr1 = osl_createInetSocketAddr( Host1.pData, 0 );
+ else
+ pHostAddr1 = osl_resolveHostname( Host1.pData );
+
+ if ( Host2.toChar() >= '0' && Host2.toChar() <= '9' )
+ pHostAddr2 = osl_createInetSocketAddr( Host2.pData, 0 );
+ else
+ pHostAddr2 = osl_resolveHostname( Host2.pData );
+
+ bEqualAddress = osl_isEqualSocketAddr( pHostAddr1, pHostAddr2 ) ? TRUE : FALSE;
+
+ osl_destroySocketAddr( pHostAddr1 );
+ osl_destroySocketAddr( pHostAddr2 );
+
+ return bEqualAddress;
+}
+
+static BOOL
+sal_IsLocalDisplay( Display *pDisplay )
+{
+ const char *pDisplayString = DisplayString( pDisplay );
+
+ // no string, no idea
+ if ( pDisplayString == NULL || pDisplayString[ 0 ] == '\0')
+ return FALSE;
+
+ // check for ":x.y"
+ if ( pDisplayString[ 0 ] == ':' )
+ return sal_IsDisplayNumber( pDisplayString + 1 );
+
+ // check for fixed token which all mean localhost:x.y
+ const char pLocal[] = "localhost:";
+ const int nLocalLen = sizeof(pLocal) - 1;
+ if ( strncmp(pDisplayString, pLocal, nLocalLen) == 0 )
+ return sal_IsDisplayNumber( pDisplayString + nLocalLen );
+
+ const char pUnix[] = "unix:";
+ const int nUnixLen = sizeof(pUnix) - 1;
+ if ( strncmp(pDisplayString, pUnix, nUnixLen) == 0 )
+ return sal_IsDisplayNumber( pDisplayString + nUnixLen );
+
+ const char pLoopback[] = "127.0.0.1:";
+ const int nLoopbackLen= sizeof(pLoopback) - 1;
+ if ( strncmp(pDisplayString, pLoopback, nLoopbackLen) == 0 )
+ return sal_IsDisplayNumber( pDisplayString + nLoopbackLen );
+
+ // compare local hostname to displaystring, both may be ip address or
+ // hostname
+ BOOL bEqual = FALSE;
+ char *pDisplayHost = strdup( pDisplayString );
+ char *pPtr = strrchr( pDisplayHost, ':' );
+
+ if( pPtr != NULL )
+ {
+ ::rtl::OUString aLocalHostname;
+ if( osl_getLocalHostname( &aLocalHostname.pData ) == osl_Socket_Ok)
+ {
+ *pPtr = '\0';
+ ::rtl::OUString aDisplayHostname( pDisplayHost, strlen( pDisplayHost ), gsl_getSystemTextEncoding() );
+ bEqual = sal_EqualHosts( aLocalHostname, aDisplayHostname );
+ bEqual = bEqual && sal_IsDisplayNumber( pPtr + 1 );
+ }
+ }
+ free( pDisplayHost );
+
+ return bEqual;
+}
+
+// ---------------------------------------------------------------------------
+// IsLocal means soffice is running on the same host as the xserver
+// since it is not called very often and sal_IsLocalDisplay() is relative
+// expensive bLocal_ is initialized on first call
+
+BOOL SalDisplay::IsLocal()
+{
+ if ( ! mbLocalIsValid )
+ {
+ bLocal_ = sal_IsLocalDisplay( pDisp_ );
+ mbLocalIsValid = TRUE;
+ }
+ return (BOOL)bLocal_;
+}
+
+// ---------------------------------------------------------------------------
+extern "C" srv_vendor_t
+sal_GetServerVendor( Display *p_display )
+{
+ typedef struct {
+ srv_vendor_t e_vendor; // vendor as enum
+ char *p_name; // vendor name as returned by VendorString()
+ unsigned int n_len; // number of chars to compare
+ } vendor_t;
+
+ const vendor_t p_vendorlist[] = {
+ { vendor_xfree, "The XFree86 Project, Inc", 13 },
+ { vendor_sun, "Sun Microsystems, Inc.", 10 },
+ { vendor_attachmate, "Attachmate Corporation", 10 },
+ { vendor_excursion,
+ "DECWINDOWS DigitalEquipmentCorporation, eXcursion", 42 },
+ { vendor_hp, "Hewlett-Packard Company", 17 },
+ { vendor_hummingbird, "Hummingbird Communications Ltd.", 11 },
+ { vendor_ibm, "International Business Machines", 24 },
+ { vendor_sgi, "Silicon Graphics", 9 },
+ { vendor_sco, "The Santa Cruz Operation", 16 },
+ { vendor_xinside, "X Inside Inc.", 10 },
+ // allways the last entry: vendor_none to indicate eol
+ { vendor_none, NULL, 0 },
+ };
+
+ // handle xprinter separately, since it doesnt implement ServerVendor()
+ if ( ! XSalIsDisplay( p_display ) )
+ return vendor_xprinter;
+
+ // handle regular server vendors
+ char *p_name = ServerVendor( p_display );
+ vendor_t *p_vendor;
+ for (p_vendor = const_cast<vendor_t*>(p_vendorlist); p_vendor->e_vendor != vendor_none; p_vendor++)
+ {
+ if ( strncmp (p_name, p_vendor->p_name, p_vendor->n_len) == 0 )
+ return p_vendor->e_vendor;
+ }
+
+ // vendor not found in list
+ return vendor_unknown;
+}
+
+// -=-= SalDisplay -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final BOOL SalDisplay::BestVisual( Display *pDisplay,
+ int nScreen,
+ XVisualInfo &rVI )
+{
+ VisualID nDefVID = XVisualIDFromVisual( DefaultVisual( pDisplay, nScreen ) );
+ VisualID nVID = 0;
+ char *pVID = getenv( "SAL_VISUAL" );
+ if( pVID )
+ sscanf( pVID, "%li", &nVID );
+
+ if( nVID && sal_GetVisualInfo( pDisplay, nVID, rVI ) )
+ return rVI.visualid == nDefVID;
+
+ XVisualInfo aVI;
+ // get all visuals
+ int nVisuals;
+ XVisualInfo* pVInfos = XGetVisualInfo( pDisplay, VisualNoMask,
+ &aVI, &nVisuals );
+ // pVInfos should contain at least one visual, otherwise
+ // we're in trouble
+ int* pWeight = new int[ nVisuals ];
+ int i;
+ for( i = 0; i < nVisuals; i++ )
+ {
+ BOOL bUsable = FALSE;
+ int nTrueColor = 1;
+
+ if ( pVInfos[i].screen != nScreen )
+ {
+ bUsable = FALSE;
+ }
+ else
+ if( pVInfos[i].c_class == TrueColor )
+ {
+ nTrueColor = 2048;
+ if( pVInfos[i].depth == 24 )
+ bUsable = TRUE;
+#ifdef TRUECOLOR8
+ else if( pVInfos[i].depth == 8 )
+ {
+ nTrueColor = -1; // strongly discourage 8 bit true color
+ bUsable = TRUE;
+ }
+#endif
+#ifdef TRUECOLOR15
+ else if( pVInfos[i].depth == 15 )
+ bUsable = TRUE;
+#endif
+#ifdef TRUECOLOR16
+ else if( pVInfos[i].depth == 16 )
+ bUsable = TRUE;
+#endif
+#ifdef TRUECOLOR32
+ else if( pVInfos[i].depth == 32 )
+ {
+ nTrueColor = 256;
+ // we do not have use for an alpha channel
+ // better use a 24 or 16 bit truecolor visual if possible
+ bUsable = TRUE;
+ }
+#endif
+ }
+ else if( pVInfos[i].c_class == PseudoColor )
+ {
+ if( pVInfos[i].depth <= 8 )
+ bUsable = TRUE;
+#ifdef PSEUDOCOLOR12
+ else if( pVInfos[i].depth == 12 )
+ bUsable = TRUE;
+#endif
+ }
+ pWeight[ i ] = bUsable ? nTrueColor*pVInfos[i].depth : -1024;
+ pWeight[ i ] -= pVInfos[ i ].visualid;
+ }
+
+ SalOpenGL::MakeVisualWeights( pDisplay, pVInfos, pWeight, nVisuals );
+
+ int nBestVisual = 0;
+ int nBestWeight = -1024;
+ for( i = 0; i < nVisuals; i++ )
+ {
+ if( pWeight[ i ] > nBestWeight )
+ {
+ nBestWeight = pWeight[ i ];
+ nBestVisual = i;
+ }
+ }
+
+ rVI = pVInfos[ nBestVisual ];
+
+ XFree( pVInfos );
+ return rVI.visualid == nDefVID;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+final SalDisplay::SalDisplay( Widget w )
+{
+ SalData *pSalData = GetSalData();
+
+ if( !pSalData->GetDefDisp() )
+ pSalData->SetDefDisp( this );
+ if( !pSalData->GetCurDisp() )
+ pSalData->SetCurDisp( this );
+
+ pXLib_ = pSalData->GetLib();
+ pDisp_ = XtDisplay( w );
+ nScreen_ = DefaultScreen( pDisp_ );
+ hShell_ = w;
+ hComposite_ = XtVaCreateManagedWidget(
+ "ShellComposite",
+ SAL_COMPOSITE_WIDGET,
+ hShell_,
+ NULL );
+
+ Visual *pVisual = NULL;
+ Colormap hColMap = None;
+ Arg aArgs[10];
+
+ XtSetArg( aArgs[0], XtNvisual, &pVisual );
+ XtSetArg( aArgs[1], XtNcolormap, &hColMap );
+
+ XtGetValues( hShell_, aArgs, 2 );
+ if( !pVisual )
+ pVisual = DefaultVisual( pDisp_, nScreen_ );
+ if (!hColMap)
+ hColMap = DefaultColormap( pDisp_, nScreen_ );
+ if( !IsDisplay() && !hColMap)
+ hColMap = 1; // trick for XPrinter
+
+ XVisualInfo aXVI;
+ sal_GetVisualInfo( pDisp_, XVisualIDFromVisual( pVisual ), aXVI );
+
+ Init( hColMap, &aXVI );
+}
+
+final SalDisplay::SalDisplay( Display *display, Visual *pVisual,
+ Colormap aColMap ) : pDisp_( display )
+{
+ SalData *pSalData = GetSalData();
+ XVisualInfo aXVI;
+
+ if( !pSalData->GetDefDisp() )
+ pSalData->SetDefDisp( this );
+ if( !pSalData->GetCurDisp() )
+ pSalData->SetCurDisp( this );
+
+ pXLib_ = XSalIsDisplay( pDisp_ ) ? pSalData->GetLib() : NULL;
+ nScreen_ = DefaultScreen( pDisp_ );
+
+ if (!aColMap)
+ aColMap = DefaultColormap( display, nScreen_ );
+ if( !IsDisplay() && !aColMap)
+ aColMap = 1; // trick for XPrinter
+ if (!pVisual)
+ pVisual = DefaultVisual( pDisp_, nScreen_ );
+
+ sal_GetVisualInfo( pDisp_, XVisualIDFromVisual( pVisual ), aXVI );
+ Init( aColMap, &aXVI );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalDisplay::~SalDisplay( )
+{
+ SalData *pSalData = GetSalData();
+
+ SalBitmap::ImplDestroyCache();
+ DestroyFontCache();
+
+ if( IsDisplay() )
+ {
+ osl_destroyMutex( hEventGuard_ );
+
+ XDestroyWindow( pDisp_, hRefWindow_ );
+ if( pMonoGC_ != pCopyGC_ )
+ XFreeGC( pDisp_, pMonoGC_ );
+ XFreeGC( pDisp_, pCopyGC_ );
+ XFreeGC( pDisp_, pAndInvertedGC_ );
+ XFreeGC( pDisp_, pAndGC_ );
+ XFreeGC( pDisp_, pOrGC_ );
+ XFreeGC( pDisp_, pStippleGC_ );
+ XFreePixmap( pDisp_, hInvert50_ );
+
+ hEventGuard_ = (oslMutex)ILLEGAL_POINTER;
+ hRefWindow_ = (XLIB_Window)ILLEGAL_POINTER;
+ pMonoGC_ = (GC)ILLEGAL_POINTER;
+ pCopyGC_ = (GC)ILLEGAL_POINTER;
+ pAndInvertedGC_ = (GC)ILLEGAL_POINTER;
+ pAndGC_ = (GC)ILLEGAL_POINTER;
+ pOrGC_ = (GC)ILLEGAL_POINTER;
+ pStippleGC_ = (GC)ILLEGAL_POINTER;
+ hInvert50_ = None;
+
+ for( size_t i = 0; i < POINTER_COUNT; i++ )
+ {
+ XFreeCursor( pDisp_, aPointerCache_[i] );
+#ifdef DBG_UTIL
+ aPointerCache_[i] = None;
+#endif
+ }
+
+ if( hComposite_ )
+ XtDestroyWidget( hComposite_ );
+ if( hShell_ )
+ XtDestroyWidget( hShell_ );
+
+ pXLib_->Remove( ConnectionNumber( pDisp_ ) );
+
+ delete mpInputMethod;
+ delete mpKbdExtension;
+ XtCloseDisplay( pDisp_ );
+ }
+
+ pDisp_ = (Display*)ILLEGAL_POINTER;
+
+ pSalData->Remove( this );
+
+ // free colormap before modifying pVisual_
+ xColor_.Clear();
+
+ delete pICCCM_;
+ delete pVisual_;
+
+ if( pRootVisual_ != pVisual_ )
+ delete pRootVisual_;
+
+ pICCCM_ = (SalICCCM*)ILLEGAL_POINTER;
+ pVisual_ = (SalVisual*)ILLEGAL_POINTER;
+ pRootVisual_ = (SalVisual*)ILLEGAL_POINTER;
+
+ if( pSalData->GetDefDisp() == this )
+ pSalData->SetDefDisp( NULL );
+ if( pSalData->GetCurDisp() == this )
+ pSalData->SetCurDisp( NULL );
+}
+
+static int DisplayHasEvent( int fd, SalDisplay *pDisplay )
+{
+ DBG_ASSERT( ConnectionNumber( pDisplay->GetDisplay() ) == fd,
+ "wrong fd in DisplayHasEvent" )
+ return pDisplay->IsDisplay() && pDisplay->IsEvent();
+}
+static int DisplayQueue( int fd, SalDisplay *pDisplay )
+{
+ DBG_ASSERT( ConnectionNumber( pDisplay->GetDisplay() ) == fd,
+ "wrong fd in DisplayHasEvent" )
+ return XEventsQueued( pDisplay->GetDisplay(),
+ QueuedAfterReading );
+}
+static int DisplayYield( int fd, SalDisplay *pDisplay )
+{
+ DBG_ASSERT( ConnectionNumber( pDisplay->GetDisplay() ) == fd,
+ "wrong fd in DisplayHasEvent" )
+ pDisplay->Yield( TRUE );
+ return TRUE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalDisplay::Init( Colormap hXColmap, const XVisualInfo* pXVI )
+{
+ GetSalData()->Insert( this );
+
+ for( size_t i = 0; i < POINTER_COUNT; i++ )
+ aPointerCache_[i] = None;
+
+ eWindowManager_ = otherwm;
+ nProperties_ = PROPERTY_DEFAULT;
+ nStateOfYield_ = 0;
+ nStateOfSendEvent_ = 0;
+ hEventGuard_ = NULL;
+ pEventQueue_ = NULL;
+ pDispatchStack_ = NULL;
+ pFontCache_ = NULL;
+ mpFontList = (XlfdStorage*)NULL;
+ mpFactory = (AttributeProvider*)NULL;
+ mpCvtCache = NULL;
+ pCapture_ = NULL;
+ pVisual_ = new SalVisual( pXVI );
+ aSize_ = Size( DisplayWidth ( pDisp_, nScreen_ ),
+ DisplayHeight( pDisp_, nScreen_ ) );
+ aResolution_ =
+ Pair( DPI( aSize_.Width(), DisplayWidthMM ( pDisp_, nScreen_ ) ),
+ DPI( aSize_.Height(), DisplayHeightMM( pDisp_, nScreen_ ) ) );
+
+ nMaxRequestSize_ = XExtendedMaxRequestSize( pDisp_ ) * 4;
+ if( !nMaxRequestSize_ )
+ nMaxRequestSize_ = XMaxRequestSize( pDisp_ ) * 4;
+
+ SetServerVendor();
+ SalBitmap::ImplCreateCache();
+
+ if( IsDisplay() )
+ {
+ hEventGuard_ = osl_createMutex();
+
+ pXLib_->Insert( ConnectionNumber( pDisp_ ),
+ this,
+ (YieldFunc) DisplayHasEvent,
+ (YieldFunc) DisplayQueue,
+ (YieldFunc) DisplayYield );
+
+ pICCCM_ = new SalICCCM( this );
+ pScreen_ = ScreenOfDisplay( pDisp_, nScreen_ );
+ hRootWindow_ = RootWindowOfScreen( pScreen_ );
+
+ // we are interested in create and destroy notify events
+ // for salsystem
+ if( hRootWindow_ != None )
+ XSelectInput( pDisp_, hRootWindow_, SubstructureNotifyMask );
+
+ bLocal_ = FALSE; /* dont care, initialize later by
+ calling SalDisplay::IsLocal() */
+ mbLocalIsValid = FALSE; /* bLocal_ is not yet initialized */
+
+ // - - - - - - - - - - Visuals - - - - - - - - - - - - - - -
+ Visual *pRootVisual = DefaultVisual( pDisp_, nScreen_ );
+ // if( pRootVisual != pXVI->visual )
+ if( pRootVisual->visualid != pVisual_->GetVisualId() )
+ {
+ XVisualInfo aXVI;
+ sal_GetVisualInfo( pDisp_, pRootVisual->visualid, aXVI );
+ pRootVisual_ = new SalVisual( &aXVI );
+ }
+ else
+ pRootVisual_ = pVisual_;
+
+ // start session management
+ SessionManagerClient::open();
+
+ // - - - - - - - - - - Reference Window/Default Drawable - -
+ XSetWindowAttributes aXWAttributes;
+ aXWAttributes.border_pixel = 0;
+ aXWAttributes.background_pixel = 0;
+ aXWAttributes.colormap = hXColmap;
+ hRefWindow_ = XCreateWindow( pDisp_,
+ hRootWindow_,
+ 0,0, 16,16, 0,
+ pVisual_->GetDepth(),
+ InputOutput,
+ pVisual_->GetVisual(),
+ CWBorderPixel|CWBackPixel|CWColormap,
+ &aXWAttributes );
+
+ // set client leader and session id
+ char* pSessionID = SessionManagerClient::getSessionID();
+ if( hRefWindow_ )
+ {
+ if( pSessionID )
+ {
+ XChangeProperty( pDisp_,
+ hRefWindow_,
+ XInternAtom( pDisp_, "SM_CLIENT_ID", False ),
+ XA_STRING,
+ 8,
+ PropModeReplace,
+ (unsigned char*)pSessionID,
+ strlen( pSessionID )
+ );
+ }
+ // client leader must have WM_CLIENT_LEADER pointing to itself
+
+ XChangeProperty( pDisp_,
+ hRefWindow_,
+ XInternAtom( pDisp_, "WM_CLIENT_LEADER", False ),
+ XA_WINDOW,
+ 32,
+ PropModeReplace,
+ (unsigned char*)&hRefWindow_,
+ 1
+
+ );
+
+ ByteString aExec( SessionManagerClient::getExecName(), gsl_getSystemTextEncoding() );
+ char* argv[2];
+ argv[0] = "/bin/sh";
+ argv[1] = const_cast<char*>(aExec.GetBuffer());
+ XSetCommand( pDisp_, hRefWindow_, argv, 2 );
+ }
+
+ // - - - - - - - - - - Synchronize - - - - - - - - - - - - -
+ if( getenv( "SAL_SYNCHRONIZE" ) )
+ XSynchronize( pDisp_, True );
+
+ // - - - - - - - - - - Window Manager - - - - - - - - - - -
+ const char *pWM = getenv( "SAL_WM" );
+ if( pWM )
+ sscanf( pWM, "%li", &eWindowManager_ );
+ else if( XInternAtom( pDisp_, "_SGI_TELL_WM", True ) )
+ eWindowManager_ = _4Dwm;
+ else if( XInternAtom( pDisp_, "KWM_RUNNING", True ) )
+ eWindowManager_ = mwm; // naja, eigentlich kwm ...
+ else if( XInternAtom( pDisp_, "_OL_WIN_ATTR", True ) )
+ eWindowManager_ = olwm;
+
+ // - - - - - - - - - - Properties - - - - - - - - - - - - -
+ const char *pProperties = getenv( "SAL_PROPERTIES" );
+ if( pProperties )
+ sscanf( pProperties, "%li", &nProperties_ );
+ else
+ {
+#if defined DBG_UTIL || defined SUN || defined LINUX
+ nProperties_ |= PROPERTY_FEATURE_Maximize;
+#endif
+ // Server Bugs & Properties
+ if( GetServerVendor() == vendor_excursion )
+ {
+ nProperties_ |= PROPERTY_BUG_Stipple;
+ nProperties_ |= PROPERTY_BUG_DrawLine;
+ nProperties_ &= ~PROPERTY_SUPPORT_XSetClipMask;
+ }
+ else
+ if( GetServerVendor() == vendor_attachmate )
+ {
+ nProperties_ |= PROPERTY_BUG_CopyPlane_RevertBWPixel;
+ }
+ else
+ if( GetServerVendor() == vendor_ibm )
+ {
+ nProperties_ |= PROPERTY_BUG_XA_FAMILY_NAME_nil;
+
+ if( otherwm == eWindowManager_ ) eWindowManager_ = mwm;
+ }
+ else
+ if( GetServerVendor() == vendor_xfree )
+ {
+ nProperties_ |= PROPERTY_BUG_XCopyArea_GXxor;
+#ifdef ARM32 // ??? Server! nicht Client ???
+ nProperties_ &= ~PROPERTY_SUPPORT_XSetClipMask;
+#endif
+#ifdef LINUX
+ // otherwm and olwm are a kind of default, which are not detected
+ // carefully. if we are running linux (i.e. not netbsd) on an xfree
+ // display, fvwm is most probable the wm to choose, confusing with mwm
+ // doesn't harm. #57791# start maximized if possible
+ if( (otherwm == eWindowManager_)
+ || (olwm == eWindowManager_ ))
+ {
+ eWindowManager_ = fvwm; // ???
+ nProperties_ |= PROPERTY_FEATURE_Maximize;
+ }
+#else
+ if( otherwm == eWindowManager_ ) eWindowManager_ = winmgr;
+#endif
+#if defined SOLARIS && defined SPARC
+ nProperties_ |= PROPERTY_BUG_Bitmap_Bit_Order;
+ // solaris xlib seems to have problems with putting images
+ // in correct bit order to xfree 8 bit displays
+#endif
+ }
+ else
+ if( GetServerVendor() == vendor_sun )
+ {
+ // nicht alle! (bekannt: nur Sparc II CG3, CG6?)
+ nProperties_ &= ~PROPERTY_SUPPORT_XSetClipMask;
+
+ // Fehler im Sun-Solaris X86 Server !
+ if (ImageByteOrder(GetDisplay()) == LSBFirst)
+ {
+ nProperties_ |= PROPERTY_BUG_Tile;
+ nProperties_ |= PROPERTY_SUPPORT_3ButtonMouse;
+ }
+ else // MSBFirst Sun-Solaris Sparc Server
+ {
+ // XCopyPlane reverts black and white for 1bit bitmaps
+ // only sun, only 8bit pseudocolor target
+ if ( (pVisual_->GetDepth() == 8)
+ && (pVisual_->GetClass() == PseudoColor))
+ nProperties_ |= PROPERTY_BUG_CopyPlane_RevertBWPixel;
+ // Fehler in Solaris 2.5.1
+ if (VendorRelease ( GetDisplay() ) < 3600)
+ nProperties_ |= PROPERTY_BUG_FillPolygon_Tile;
+ }
+
+ if( otherwm == eWindowManager_ )
+ if( XInternAtom( pDisp_, "_MOTIF_WM_INFO", True ) )
+ eWindowManager_ = dtwm;
+ else
+ eWindowManager_ = olwm;
+ }
+ else
+ if( GetServerVendor() == vendor_sco )
+ {
+ if( otherwm == eWindowManager_ ) eWindowManager_ = pmwm;
+ }
+ else
+ if( GetServerVendor() == vendor_sgi )
+ {
+ if( pVisual_->GetDepth() > 8 && pVisual_->GetDepth() <= 16 )
+ nProperties_ |= PROPERTY_BUG_XCopyArea_GXxor;
+ nProperties_ |= PROPERTY_SUPPORT_XSetClipMask;
+
+ if( otherwm == eWindowManager_ ) eWindowManager_ = _4Dwm;
+ }
+ else
+ if( GetServerVendor() == vendor_hp )
+ {
+ if( otherwm == eWindowManager_ ) eWindowManager_ = dtwm;
+ }
+ else
+ if( GetServerVendor() == vendor_hummingbird )
+ {
+ if (pVisual_->GetDepth() == 24)
+ nProperties_ |= PROPERTY_BUG_CopyArea_OnlySmallSlices;
+ }
+
+ if( otherwm == eWindowManager_ )
+ {
+ if( !XInternAtom( pDisp_, "_MOTIF_WM_INFO", True ) )
+ eWindowManager_ = olwm;
+ // ???
+ }
+
+ if( winmgr == eWindowManager_ )
+ {
+ nProperties_ &= ~PROPERTY_SUPPORT_WM_SetPos;
+ nProperties_ &= ~PROPERTY_SUPPORT_WM_Screen;
+ nProperties_ |= PROPERTY_FEATURE_Maximize;
+ }
+ else if( dtwm == eWindowManager_ )
+ {
+ nProperties_ &= ~PROPERTY_SUPPORT_WM_ClientPos;
+ }
+ else if( pmwm == eWindowManager_ )
+ {
+ nProperties_ &= ~PROPERTY_SUPPORT_WM_ClientPos;
+ }
+ }
+
+ // - - - - - - - - - - Shared Images - - - - - - - - - - - -
+#if defined _XSHM_H_ // && defined DBG_UTIL
+ // SharedMem wird nur noch ueber SalProperties enabled
+ // wegen Bugs #47289 und #46512
+
+ if( ( nProperties_ & PROPERTY_FEATURE_SharedMemory )
+ && ( *DisplayString( pDisp_ ) == ':'
+ || !strncmp( DisplayString( pDisp_ ), "localhost:", 10 ))
+ )
+ {
+ int nMinor, nMajor;
+ Bool bPixmaps;
+
+ nSharedImages_ = XShmQueryVersion( pDisp_,
+ &nMajor,
+ &nMinor,
+ &bPixmaps )
+ ? 0x80000000 : 0;
+ }
+ else
+ nSharedImages_ = 0;
+#else
+ nSharedImages_ = 0;
+#endif
+ // - - - - - - - - - - Images - - - - - - - - - - - - - - -
+ nImageDepths_ = 0x00000000;
+ int nCount, *pDepths = XListDepths( pDisp_, nScreen_, &nCount );
+ if( pDepths )
+ {
+ for( int i = 0; i < nCount; i++ )
+ nImageDepths_ |= 1 << (pDepths[i]-1);
+ XFree( pDepths );
+ }
+ }
+ else
+ {
+ pICCCM_ = NULL;
+ pScreen_ = NULL;
+ hRootWindow_ = None;
+ pRootVisual_ = pVisual_;
+#ifdef DBG_UTIL
+ hRefWindow_ = (XLIB_Window)ILLEGAL_POINTER;
+#endif
+ hInvert50_ = None;
+ bLocal_ = TRUE; /* always true for xprinter */
+ mbLocalIsValid = TRUE; /* yes bLocal_ is initialized */
+ nProperties_ &= ~PROPERTY_SUPPORT_XSetClipMask; //XPrinter doesnt
+ nSharedImages_ = 0;
+ nImageDepths_ = 0xFFFFFFFF;
+ }
+
+ // - - - - - - - - - - Images - - - - - - - - - - - - - - -
+ // 0x8080C889
+ nImageDepths_ &= (1<<(32-1))
+ |(1<<(24-1))
+ |(1<<(16-1))
+ |(1<<(15-1))
+ |(1<<(12-1))
+ |(1<<(8-1))
+ |(1<<(4-1))
+ |(1<<(1-1));
+
+ xColor_ = new SalColormap( this, hXColmap );
+
+ // - - - - - - - - - - GCs - - - - - - - - - - - - - - - - -
+ XGCValues values;
+ values.graphics_exposures = True;
+ values.fill_style = FillOpaqueStippled;
+ values.background = (1<<pVisual_->GetDepth())-1;
+ values.foreground = 0;
+
+ pCopyGC_ = XCreateGC( pDisp_,
+ hRefWindow_,
+ GCGraphicsExposures
+ | GCForeground
+ | GCBackground,
+ &values );
+ pAndInvertedGC_ = XCreateGC( pDisp_,
+ hRefWindow_,
+ GCGraphicsExposures
+ | GCForeground
+ | GCBackground,
+ &values );
+ pAndGC_ = XCreateGC( pDisp_,
+ hRefWindow_,
+ GCGraphicsExposures
+ | GCForeground
+ | GCBackground,
+ &values );
+ pOrGC_ = XCreateGC( pDisp_,
+ hRefWindow_,
+ GCGraphicsExposures
+ | GCForeground
+ | GCBackground,
+ &values );
+ pStippleGC_ = XCreateGC( pDisp_,
+ hRefWindow_,
+ GCGraphicsExposures
+ | GCFillStyle
+ | GCForeground
+ | GCBackground,
+ &values );
+
+ XSetFunction( pDisp_, pAndInvertedGC_, GXandInverted );
+ XSetFunction( pDisp_, pAndGC_, GXand );
+ // #44556# PowerPC Solaris 2.5 (XSun 3500) Bug: GXor = GXnop
+ //XSetFunction( pDisp_, pOrGC_, GXor );
+ XSetFunction( pDisp_, pOrGC_, GXxor );
+
+ if( 1 == pVisual_->GetDepth() ) // irgendwer dreht immer
+ {
+ XSetFunction( pDisp_, pCopyGC_, GXcopyInverted );
+ pMonoGC_ = pCopyGC_;
+ }
+ else
+ {
+ Pixmap hPixmap = XCreatePixmap( pDisp_, hRefWindow_, 1, 1, 1 );
+ pMonoGC_ = XCreateGC( pDisp_,
+ hPixmap,
+ GCGraphicsExposures,
+ &values );
+ XFreePixmap( pDisp_, hPixmap );
+ }
+
+ if( IsDisplay() )
+ {
+ hInvert50_ = XCreateBitmapFromData( pDisp_,
+ hRefWindow_,
+ invert50_bits,
+ invert50_width,
+ invert50_height );
+
+ // - - - - - - - - - - Sound - - - - - - - - - - - - - - - -
+
+ nBeepVolume_ = 0;
+
+ // - - - - - - - - - - Fonts - - - - - - - - - - - - - - - -
+
+ const char *pFontPath = getenv( "SAL_FONTPATH" );
+ if( pFontPath )
+ AddFontPath( ByteString( pFontPath ) );
+
+ // - - - - - - - - - - Keyboardmapping - - - - - - - - - - -
+
+ ModifierMapping();
+
+ // - - - - - - - - - - ShellWidget - - - - - - - - - - - - -
+
+
+ if( !XtWindow( hShell_ ) )
+ {
+ Position w, h;
+ Arg aArgs[10];
+
+ XtSetArg( aArgs[0], XtNwidth, &w );
+ XtSetArg( aArgs[1], XtNheight, &h );
+ XtGetValues( hShell_, aArgs, 2 );
+
+ if( !w || !h )
+ {
+ if( GetProperties() & PROPERTY_FEATURE_Maximize )
+ {
+ XtSetArg( aArgs[0], XtNwidth, aSize_.Width() );
+ XtSetArg( aArgs[1], XtNheight, aSize_.Height() );
+ }
+ else
+ {
+ XtSetArg( aArgs[0], XtNwidth, 500 );
+ XtSetArg( aArgs[1], XtNheight, 400 );
+ }
+ XtSetValues( hShell_, aArgs, 2 );
+ }
+
+ // X-Window erzeugen
+ XtSetMappedWhenManaged( hShell_, FALSE );
+ XtRealizeWidget( hShell_ );
+ }
+ if( !XtWindow( hComposite_ ) )
+ XtRealizeWidget( hComposite_ );
+ }
+#ifdef DBG_UTIL
+ PrintInfo();
+#endif
+
+#ifdef DEBUG
+ fprintf( stderr, "Keyboard name: %s\n", GetKeyboardName() );
+ String aConvert = GetKeyNameFromKeySym( XK_Control_L );
+ fprintf( stderr, "Control: %s\n", aConvert.Len() ? ByteString( aConvert, gsl_getSystemTextEncoding() ).GetBuffer() : "<nil>" );
+ aConvert = GetKeyNameFromKeySym( XK_Shift_L );
+ fprintf( stderr, "Shift: %s\n", aConvert.Len() ? ByteString( aConvert, gsl_getSystemTextEncoding() ).GetBuffer() : "<nil>" );
+ aConvert = GetKeyNameFromKeySym( XK_Alt_L );
+ fprintf( stderr, "Alt: %s\n", aConvert.Len() ? ByteString( aConvert, gsl_getSystemTextEncoding() ).GetBuffer() : "<nil>" );
+ aConvert = GetKeyNameFromKeySym( XK_Alt_R );
+ fprintf( stderr, "AltGr: %s\n", aConvert.Len() ? ByteString( aConvert, gsl_getSystemTextEncoding() ).GetBuffer() : "<nil>" );
+#endif
+}
+
+/*----------------------------
+ keep track of windows that are sized in ::Init but repositioned
+ by the window-mgr. If they are not resized by SalFrame::Set[Pos]Size
+ then SalFrameData::HandleReparentEvent takes a look at it, to prevent it
+ from beeing moved outside the screen
+ ------------------------------*/
+
+static unsigned int nRefWindow = 0;
+
+void
+MarkWindowAsBadPositioned( unsigned int nWindow )
+{
+ nRefWindow = nWindow;
+}
+
+void
+MarkWindowAsGoodPositioned( unsigned int nWindow )
+{
+ if ( nRefWindow == nWindow )
+ nRefWindow = 0;
+}
+
+Boolean
+WindowNeedGoodPosition( unsigned int nWindow )
+{
+ return (Boolean) nWindow == nRefWindow;
+}
+
+// Sound
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+beta void SalDisplay::Beep() const
+{
+ XBell( pDisp_, nBeepVolume_ );
+}
+
+// Keyboard
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+String SalDisplay::GetKeyNameFromKeySym( KeySym nKeySym ) const
+{
+ String aRet;
+ if( !nKeySym )
+ aRet = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "???" ) );
+ else
+ {
+ aRet = ::vcl_sal::getKeysymReplacementName( const_cast<SalDisplay*>(this)->GetKeyboardName(), nKeySym );
+ if( ! aRet.Len() )
+ {
+ const char *pString = XKeysymToString( nKeySym );
+ int n = strlen( pString );
+ if( n > 2 && pString[n-2] == '_' )
+ aRet = String( pString, n-2, RTL_TEXTENCODING_ISO_8859_1 );
+ else
+ aRet = String( pString, n, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+ }
+ return aRet;
+}
+
+inline KeySym sal_XModifier2Keysym( Display *pDisplay,
+ XModifierKeymap *pXModMap,
+ int n )
+{
+ return XKeycodeToKeysym( pDisplay,
+ pXModMap->modifiermap[n*pXModMap->max_keypermod],
+ 0 );
+}
+
+final void SalDisplay::ModifierMapping()
+{
+ XModifierKeymap *pXModMap = XGetModifierMapping( pDisp_ );
+
+ bNumLockFromXS_ = True;
+ nShiftKeySym_ = sal_XModifier2Keysym( pDisp_, pXModMap, ShiftMapIndex );
+ nCtrlKeySym_ = sal_XModifier2Keysym( pDisp_, pXModMap, ControlMapIndex );
+ nMod1KeySym_ = sal_XModifier2Keysym( pDisp_, pXModMap, Mod1MapIndex );
+
+ // Auf Sun-Servern und SCO-Severn beruecksichtigt XLookupString
+ // nicht den NumLock Modifier.
+ if( (GetServerVendor() == vendor_sun)
+ || (GetServerVendor() == vendor_sco) )
+ {
+ XLIB_KeyCode aNumLock = XKeysymToKeycode( pDisp_, XK_Num_Lock );
+
+ if( aNumLock ) for( int i = ShiftMapIndex; i <= Mod5MapIndex; i++ )
+ {
+ if( pXModMap->modifiermap[i*pXModMap->max_keypermod] == aNumLock )
+ {
+ bNumLockFromXS_ = False;
+ nNumLockIndex_ = i;
+ nNumLockMask_ = 1<<i;
+ break;
+ }
+ }
+ }
+
+ XFreeModifiermap( pXModMap );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final XubString SalDisplay::GetKeyName( USHORT nKeyCode ) const
+{
+ String aStrMap;
+
+ if( nKeyCode & KEY_MOD2 )
+ {
+ aStrMap += GetKeyNameFromKeySym( nMod1KeySym_ );
+ }
+ if( nKeyCode & KEY_MOD1 )
+ {
+ if( aStrMap.Len() )
+ aStrMap += '+';
+ aStrMap += GetKeyNameFromKeySym( nCtrlKeySym_ );
+ }
+ if( nKeyCode & KEY_SHIFT )
+ {
+ if( aStrMap.Len() )
+ aStrMap += '+';
+ aStrMap += GetKeyNameFromKeySym( nShiftKeySym_ );
+ }
+ nKeyCode &= 0x0FFF;
+
+ KeySym nKeySym = 0;
+
+ if( KEY_0 <= nKeyCode && nKeyCode <= KEY_9 )
+ nKeySym = XK_0 + (nKeyCode - KEY_0);
+ else if( KEY_A <= nKeyCode && nKeyCode <= KEY_Z )
+ nKeySym = XK_A + (nKeyCode - KEY_A);
+ else if( KEY_F1 <= nKeyCode && nKeyCode <= KEY_F26 ) // Existiert die Taste
+ nKeySym = XK_F1 + (nKeyCode - KEY_F1);
+ else switch( nKeyCode )
+ {
+ case KEY_DOWN:
+ nKeySym = XK_Down;
+ break;
+ case KEY_UP:
+ nKeySym = XK_Up;
+ break;
+ case KEY_LEFT:
+ nKeySym = XK_Left;
+ break;
+ case KEY_RIGHT:
+ nKeySym = XK_Right;
+ break;
+ case KEY_HOME:
+ nKeySym = XK_Home;
+ break;
+ case KEY_END:
+ nKeySym = XK_End;
+ break;
+ case KEY_PAGEUP:
+ nKeySym = XK_Prior;
+ break;
+ case KEY_PAGEDOWN:
+ nKeySym = XK_Next;
+ break;
+ case KEY_RETURN:
+ nKeySym = XK_Return;
+ break;
+ case KEY_ESCAPE:
+ nKeySym = XK_Escape;
+ break;
+ case KEY_TAB:
+ nKeySym = XK_Tab;
+ break;
+ case KEY_BACKSPACE:
+ nKeySym = XK_BackSpace;
+ break;
+ case KEY_SPACE:
+ nKeySym = XK_space;
+ break;
+ case KEY_INSERT:
+ nKeySym = XK_Insert;
+ break;
+ case KEY_DELETE:
+ nKeySym = XK_Delete;
+ break;
+ case KEY_OPEN:
+ nKeySym = XK_L7;
+ break;
+ case KEY_CUT:
+ nKeySym = XK_L10;
+ break;
+ case KEY_COPY:
+ nKeySym = XK_L6;
+ break;
+ case KEY_PASTE:
+ nKeySym = XK_L8;
+ break;
+ case KEY_UNDO:
+ nKeySym = XK_L4; // XK_Undo; ???
+ break;
+ case KEY_REPEAT:
+// nKeySym = XK_L2; // XK_Redo; ???
+ nKeySym = XK_Redo;
+ break;
+ case KEY_FIND:
+ nKeySym = XK_L9; // XK_Find; ???
+ break;
+ case KEY_PROPERTIES:
+ nKeySym = XK_L3;
+ break;
+ case KEY_FRONT:
+ nKeySym = XK_L5;
+ break;
+
+ case KEY_ADD:
+ nKeySym = XK_plus;
+ break;
+ case KEY_SUBTRACT:
+ nKeySym = XK_minus;
+ break;
+ case KEY_MULTIPLY:
+ nKeySym = XK_asterisk;
+ break;
+ case KEY_DIVIDE:
+ nKeySym = XK_slash;
+ break;
+ case KEY_POINT:
+ nKeySym = XK_period;
+ break;
+ case KEY_COMMA:
+ nKeySym = XK_comma;
+ break;
+ case KEY_LESS:
+ nKeySym = XK_less;
+ break;
+ case KEY_GREATER:
+ nKeySym = XK_greater;
+ break;
+ case KEY_EQUAL:
+ nKeySym = XK_equal;
+ break;
+ case KEY_FRONT+1: // KEY_HELP
+ nKeySym = XK_F1; // XK_Help; ???
+ break;
+
+ default:
+ nKeySym = 0;
+ break;
+ }
+
+ if( nKeySym )
+ {
+ if( aStrMap.Len() )
+ aStrMap += '+';
+ aStrMap += GetKeyNameFromKeySym( nKeySym );
+ }
+
+ return aStrMap;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef IsISOKey
+#define IsISOKey( n ) (0x0000FE00==((n)&0xFFFFFF00))
+#endif
+
+final USHORT SalDisplay::GetKeyCode( KeySym keysym, char*pcPrintable ) const
+{
+ USHORT nKey = 0;
+
+ if( XK_a <= keysym && XK_z >= keysym )
+ nKey = (USHORT)(KEY_A + (keysym - XK_a));
+ else if( XK_A <= keysym && XK_Z >= keysym )
+ nKey = (USHORT)(KEY_A + (keysym - XK_A));
+ else if( XK_0 <= keysym && XK_9 >= keysym )
+ nKey = (USHORT)(KEY_0 + (keysym - XK_0));
+ else if( IsModifierKey( keysym ) )
+ nop;
+ else if( IsKeypadKey( keysym ) )
+ {
+ if( (keysym >= XK_KP_0) && (keysym <= XK_KP_9) )
+ {
+ nKey = (USHORT)(KEY_0 + (keysym - XK_KP_0));
+ *pcPrintable = '0' + nKey - KEY_0;
+ }
+ else if( IsPFKey( keysym ) )
+ nKey = (USHORT)(KEY_F1 + (keysym - XK_KP_F1));
+ else switch( keysym )
+ {
+ case XK_KP_Space:
+ nKey = KEY_SPACE;
+ *pcPrintable = ' ';
+ break;
+ case XK_KP_Tab:
+ nKey = KEY_TAB;
+ break;
+ case XK_KP_Enter:
+ nKey = KEY_RETURN;
+ break;
+ case XK_KP_Begin:
+ case XK_KP_Home:
+ nKey = KEY_HOME;
+ break;
+ case XK_KP_Left:
+ nKey = KEY_LEFT;
+ break;
+ case XK_KP_Up:
+ nKey = KEY_UP;
+ break;
+ case XK_KP_Right:
+ nKey = KEY_RIGHT;
+ break;
+ case XK_KP_Down:
+ nKey = KEY_DOWN;
+ break;
+ case XK_KP_Prior: // XK_KP_Page_Up
+ nKey = KEY_PAGEUP;
+ break;
+ case XK_KP_Next: // XK_KP_Page_Down
+ nKey = KEY_PAGEDOWN;
+ break;
+ case XK_KP_End:
+ nKey = KEY_END;
+ break;
+ case XK_KP_Insert:
+ nKey = KEY_INSERT;
+ break;
+ case XK_KP_Delete:
+ nKey = KEY_DELETE;
+ break;
+ case XK_KP_Equal:
+ nKey = KEY_EQUAL;
+ *pcPrintable = '=';
+ break;
+ case XK_KP_Multiply:
+ nKey = KEY_MULTIPLY;
+ *pcPrintable = '*';
+ break;
+ case XK_KP_Add:
+ nKey = KEY_ADD;
+ *pcPrintable = '+';
+ break;
+ case XK_KP_Separator:
+ nKey = KEY_COMMA; // ???
+ *pcPrintable = ',';
+ break;
+ case XK_KP_Subtract:
+ nKey = KEY_SUBTRACT;
+ *pcPrintable = '-';
+ break;
+ case XK_KP_Decimal:
+ nKey = KEY_POINT;
+ *pcPrintable = '.';
+ break;
+ case XK_KP_Divide:
+ nKey = KEY_DIVIDE;
+ *pcPrintable = '/';
+ break;
+ }
+ }
+ else if( IsFunctionKey( keysym ) )
+ {
+ if( bNumLockFromXS_ )
+ {
+ if( keysym >= XK_F1 && keysym <= XK_F26 )
+ nKey = (USHORT)(KEY_F1 + keysym - XK_F1);
+ }
+ else switch( keysym )
+ {
+#if 1 // Sun schaltet mit "Alt Graph"/XK_Mode_switch um
+ // - - - - - Sun X-Server Tastatur ohne Cursorblock ??? - - -
+#if 0 // Sal supports F1 - F26
+ case XK_R1: // XK_F21:
+ nKey = KEY_F21; // KEY_PRINT/KEY_SYSREQ
+ break;
+ case XK_R2: // XK_F22:
+ nKey = KEY_F22; // KEY_SCROLLLOCK
+ break;
+ case XK_R3: // XK_F23:
+ nKey = KEY_F23; // KEY_PAUSE/KEY_BREAK
+ break;
+ case XK_R4: // XK_F24:
+ nKey = KEY_F24; // KEY_EQUAL
+ break;
+ case XK_R5: // XK_F25:
+ nKey = KEY_F25; // KEY_DIVIDE
+ break;
+ case XK_R6: // XK_F26:
+ nKey = KEY_F26; // KEY_MULTIPLY
+ break;
+#endif
+ case XK_R7: // XK_F27:
+ nKey = KEY_HOME;
+ break;
+ case XK_R8: // XK_F28:
+ nKey = KEY_UP;
+ break;
+ case XK_R9: // XK_F29:
+ nKey = KEY_PAGEUP;
+ break;
+ case XK_R10: // XK_F30:
+ nKey = KEY_LEFT;
+ break;
+ case XK_R11: // XK_F31:
+ nKey = 0; // KEY_F31
+ break;
+ case XK_R12: // XK_F32:
+ nKey = KEY_RIGHT;
+ break;
+ case XK_R13: // XK_F33:
+ nKey = KEY_END;
+ break;
+ case XK_R14: // XK_F34:
+ nKey = KEY_DOWN;
+ break;
+ case XK_R15: // XK_F35:
+ nKey = KEY_PAGEDOWN;
+ break;
+ // - - - - - Sun X-Server Tastatur ??? - - - - - - - - - - - -
+ case XK_L1: // XK_F11:
+ nKey = KEY_F11; // KEY_CANCEL
+ break;
+ case XK_L2: // XK_F12:
+ if ( GetServerVendor() == vendor_sun )
+ nKey = KEY_REPEAT;
+ else
+ nKey = KEY_F12;
+ break;
+ case XK_L3: // XK_F13:
+ nKey = KEY_PROPERTIES; // KEY_F13
+ break;
+ case XK_L4: // XK_F14:
+ nKey = KEY_UNDO; // KEY_F14
+ break;
+ case XK_L5: // XK_F15:
+ nKey = KEY_F15; // KEY_FRONT
+ break;
+ case XK_L6: // XK_F16:
+ nKey = KEY_COPY; // KEY_F16
+ break;
+ case XK_L7: // XK_F17:
+ nKey = KEY_F17; // KEY_OPEN
+ break;
+ case XK_L8: // XK_F18:
+ nKey = KEY_PASTE; // KEY_F18
+ break;
+ case XK_L9: // XK_F19:
+ nKey = KEY_F19; // KEY_FIND
+ break;
+ case XK_L10: // XK_F20:
+ nKey = KEY_CUT; // KEY_F20
+ break;
+#endif
+ default:
+ if( keysym >= XK_F1 && keysym <= XK_F26 )
+ nKey = (USHORT)(KEY_F1 + keysym - XK_F1);
+ break;
+ }
+ }
+ else if( IsCursorKey( keysym ) )
+ {
+ switch( keysym )
+ {
+ case XK_Begin:
+ case XK_Home:
+ nKey = KEY_HOME;
+ break;
+ case XK_Left:
+ nKey = KEY_LEFT;
+ break;
+ case XK_Up:
+ nKey = KEY_UP;
+ break;
+ case XK_Right:
+ nKey = KEY_RIGHT;
+ break;
+ case XK_Down:
+ nKey = KEY_DOWN;
+ break;
+ case XK_Prior: // XK_Page_Up
+ nKey = KEY_PAGEUP;
+ break;
+ case XK_Next: // XK_Page_Down
+ nKey = KEY_PAGEDOWN;
+ break;
+ case XK_End:
+ nKey = KEY_END;
+ break;
+ }
+ }
+ else if( IsMiscFunctionKey( keysym ) )
+ {
+ switch( keysym )
+ {
+ case XK_Insert:
+ nKey = KEY_INSERT;
+ break;
+ case XK_Redo:
+ nKey = KEY_REPEAT;
+ break;
+ case XK_Undo:
+ nKey = KEY_UNDO;
+ break;
+ case XK_Find:
+ nKey = KEY_FIND;
+ break;
+ case XK_Help:
+ nKey = KEY_FRONT+1; // KEY_HELP
+ nKey = KEY_F1;
+ break;
+ case XK_Menu:
+ nKey = KEY_F10;
+ break;
+#if 0
+ case XK_Break:
+ case XK_Select:
+ case XK_Execute:
+ case XK_Print:
+ case XK_Cancel:
+#endif
+ }
+ }
+ else if( IsISOKey( keysym ) ) // XK_ISO_
+ {
+ switch( keysym )
+ {
+ case 0xFE20: // XK_ISO_Left_Tab:
+ nKey = KEY_TAB;
+ break;
+ }
+ }
+ else switch( keysym )
+ {
+ case XK_Return:
+ nKey = KEY_RETURN;
+ break;
+ case XK_BackSpace:
+ nKey = KEY_BACKSPACE;
+ break;
+ case XK_Delete:
+ nKey = KEY_DELETE;
+ break;
+ case XK_space:
+ nKey = KEY_SPACE;
+ break;
+ case XK_Tab:
+ nKey = KEY_TAB;
+ break;
+ case XK_Escape:
+ nKey = KEY_ESCAPE;
+ break;
+ case XK_plus:
+ nKey = KEY_ADD;
+ break;
+ case XK_minus:
+ nKey = KEY_SUBTRACT;
+ break;
+ case XK_asterisk:
+ nKey = KEY_MULTIPLY;
+ break;
+ case XK_slash:
+ nKey = KEY_DIVIDE;
+ break;
+ case XK_period:
+ nKey = KEY_POINT;
+ break;
+ case XK_comma:
+ nKey = KEY_COMMA;
+ break;
+ case XK_less:
+ nKey = KEY_LESS;
+ break;
+ case XK_greater:
+ nKey = KEY_GREATER;
+ break;
+ case XK_equal:
+ nKey = KEY_EQUAL;
+ break;
+// case XK_Linefeed:
+// *pcPrintable = '\n';
+// break;
+ // - - - - - - - - - - - - - Apollo - - - - - - - - - - - - - 0x1000
+ case 0x1000FF02: // apXK_Copy
+ nKey = KEY_COPY;
+ break;
+ case 0x1000FF03: // apXK_Cut
+ nKey = KEY_CUT;
+ break;
+ case 0x1000FF04: // apXK_Paste
+ nKey = KEY_PASTE;
+ break;
+ case 0x1000FF14: // apXK_Repeat
+ nKey = KEY_REPEAT;
+ break;
+ // Exit, Save
+ // - - - - - - - - - - - - - - D E C - - - - - - - - - - - - - 0x1000
+ case 0x1000FF00:
+ nKey = KEY_DELETE;
+ break;
+ // - - - - - - - - - - - - - - H P - - - - - - - - - - - - - 0x1000
+ case 0x1000FF73: // hpXK_DeleteChar
+ nKey = KEY_DELETE;
+ break;
+ case 0x1000FF74: // hpXK_BackTab
+ case 0x1000FF75: // hpXK_KP_BackTab
+ nKey = KEY_TAB;
+ break;
+ // - - - - - - - - - - - - - - I B M - - - - - - - - - - - - -
+ // - - - - - - - - - - - - - - O S F - - - - - - - - - - - - - 0x1004
+ case 0x1004FF02: // osfXK_Copy
+ nKey = KEY_COPY;
+ break;
+ case 0x1004FF03: // osfXK_Cut
+ nKey = KEY_CUT;
+ break;
+ case 0x1004FF04: // osfXK_Paste
+ nKey = KEY_PASTE;
+ break;
+ case 0x1004FF07: // osfXK_BackTab
+ nKey = KEY_TAB;
+ break;
+ case 0x1004FF08: // osfXK_BackSpace
+ nKey = KEY_BACKSPACE;
+ break;
+ case 0x1004FF1B: // osfXK_Escape
+ nKey = KEY_ESCAPE;
+ break;
+ // Up, Down, Left, Right, PageUp, PageDown
+ // - - - - - - - - - - - - - - S C O - - - - - - - - - - - - -
+ // - - - - - - - - - - - - - - S G I - - - - - - - - - - - - - 0x1007
+ // - - - - - - - - - - - - - - S N I - - - - - - - - - - - - -
+ // - - - - - - - - - - - - - - S U N - - - - - - - - - - - - - 0x1005
+ case 0x1005FF10: // SunXK_F36
+ nKey = KEY_F11;
+ break;
+ case 0x1005FF11: // SunXK_F37
+ nKey = KEY_F12;
+ break;
+ case 0x1005FF70: // SunXK_Props
+ nKey = KEY_PROPERTIES;
+ break;
+ case 0x1005FF71: // SunXK_Front
+ nKey = KEY_FRONT;
+ break;
+ case 0x1005FF72: // SunXK_Copy
+ nKey = KEY_COPY;
+ break;
+ case 0x1005FF73: // SunXK_Open
+ nKey = KEY_OPEN;
+ break;
+ case 0x1005FF74: // SunXK_Paste
+ nKey = KEY_PASTE;
+ break;
+ case 0x1005FF75: // SunXK_Cut
+ nKey = KEY_CUT;
+ break;
+ }
+ return nKey;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final KeySym SalDisplay::GetKeySym( XKeyEvent *pEvent,
+ unsigned char *pPrintable,
+ int *pLen,
+ Status *pStatusReturn,
+ XIC aInputContext ) const
+{
+ KeySym nKeySym;
+ memset( pPrintable, 0, *pLen );
+
+ if ( (aInputContext == 0) || (pEvent->type == KeyRelease) )
+ {
+ XComposeStatus nStatus;
+ *pLen = XLookupString( pEvent, (char*)pPrintable, 1,
+ &nKeySym, &nStatus );
+ }
+ else
+ {
+ *pStatusReturn = 0;
+ // not really sufficient for multibyte lookup: cannot handle more
+ // than one byte in sprintable, cannot handle conversion error
+ *pLen = XmbLookupString( aInputContext,
+ pEvent, (char*)pPrintable, *pLen - 1, &nKeySym, pStatusReturn );
+
+ // Lookup the string again, now with appropriate size
+ if ( *pStatusReturn == XBufferOverflow )
+ {
+ pPrintable[ 0 ] = (char)0;
+ return 0;
+ }
+
+ switch ( *pStatusReturn )
+ {
+ case XBufferOverflow:
+ /* unhandled error */
+ break;
+ case XLookupNone:
+ /* unhandled error */
+ break;
+ case XLookupKeySym:
+ /* #72223# this is a strange one: on exceed sometimes
+ * no printable is returned for the first char entered,
+ * just to retry lookup solves the problem. The problem
+ * is not yet fully understood, so restrict 2nd lookup
+ * to 7bit ascii chars */
+ if ( (XK_space <= nKeySym) && (XK_asciitilde >= nKeySym) )
+ {
+ *pLen = 1;
+ pPrintable[ 0 ] = (char)nKeySym;
+ }
+ break;
+ case XLookupBoth:
+ case XLookupChars:
+
+ /* nothing to, char allready in pPrintable */
+ break;
+ }
+ }
+
+ if( !bNumLockFromXS_
+ && (IsCursorKey(nKeySym)
+ || IsFunctionKey(nKeySym)
+ || IsKeypadKey(nKeySym)
+ || XK_Delete == nKeySym ) )
+ {
+ // Bei einigen X-Servern muss man bei den Keypadtasten
+ // schon sehr genau hinschauen. ZB. Solaris XServer:
+ // 2, 4, 6, 8 werden als Cursorkeys klassifiziert (Up, Down, Left, Right
+ // 1, 3, 5, 9 werden als Functionkeys klassifiziert (F27,F29,F33,F35)
+ // 0 als Keypadkey und der Dezimalpunkt gar nicht (KP_Insert)
+ KeySym nNewKeySym = XLookupKeysym( pEvent, nNumLockIndex_ );
+// fprintf( stderr, "Key%s: sym=%x state=%x code=%d new=%x\n",
+// KeyRelease == pEvent->type ? "Release" : "Press",
+// nKeySym, pEvent->state, pEvent->keycode, nNewKeySym );
+ if( nNewKeySym != NoSymbol )
+ nKeySym = nNewKeySym;
+ }
+// else
+// fprintf( stderr, "Key%s: sym=%x state=%x code=%d\n",
+// KeyRelease == pEvent->type ? "Release" : "Press",
+// nKeySym, pEvent->state, pEvent->keycode );
+
+ return nKeySym;
+}
+
+// Pointer
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#define MAKE_BITMAP( name ) \
+ XCreateBitmapFromData( pDisp_, \
+ DefaultRootWindow( pDisp_ ), \
+ name##_bits, \
+ name##_width, \
+ name##_height )
+
+#define MAKE_CURSOR( name ) \
+ aCursBitmap = MAKE_BITMAP( name##curs ); \
+ aMaskBitmap = MAKE_BITMAP( name##mask ); \
+ nXHot = name##curs_x_hot; \
+ nYHot = name##curs_y_hot
+
+final XLIB_Cursor SalDisplay::GetPointer( int ePointerStyle )
+{
+ if( ePointerStyle > POINTER_COUNT )
+ return NULL;
+
+ XLIB_Cursor &aCur = aPointerCache_[ePointerStyle];
+
+ if( aCur != None )
+ return aCur;
+
+ Pixmap aCursBitmap, aMaskBitmap;
+ unsigned int nXHot, nYHot;
+
+ switch( ePointerStyle )
+ {
+ case POINTER_NULL:
+ MAKE_CURSOR( null );
+ break;
+ case POINTER_ARROW:
+ aCur = XCreateFontCursor( pDisp_, XC_top_left_arrow );
+ break;
+ case POINTER_WAIT:
+ MAKE_CURSOR( wait_ );
+ break;
+ case POINTER_TEXT: // Mouse Pointer ist ein "I" Beam
+ aCur = XCreateFontCursor( pDisp_, XC_xterm );
+ break;
+ case POINTER_HELP:
+ aCur = XCreateFontCursor( pDisp_, XC_question_arrow );
+ break;
+ case POINTER_CROSS: // Mouse Pointer ist ein Kreuz
+ aCur = XCreateFontCursor( pDisp_, XC_crosshair );
+ break;
+ case POINTER_NSIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_sb_v_double_arrow );
+ break;
+ case POINTER_SSIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_sb_v_double_arrow );
+ break;
+ case POINTER_WSIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_sb_h_double_arrow );
+ break;
+ case POINTER_ESIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_sb_h_double_arrow );
+ break;
+ case POINTER_WINDOW_NSIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_top_tee );
+ break;
+ case POINTER_WINDOW_SSIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_bottom_tee );
+ break;
+ case POINTER_WINDOW_WSIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_left_tee );
+ break;
+ case POINTER_WINDOW_ESIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_right_tee );
+ break;
+ case POINTER_NWSIZE:
+ MAKE_CURSOR( nwsesize_ );
+ break;
+ case POINTER_NESIZE:
+ MAKE_CURSOR( neswsize_ );
+ break;
+ case POINTER_SWSIZE:
+ MAKE_CURSOR( neswsize_ );
+ break;
+ case POINTER_SESIZE:
+ MAKE_CURSOR( nwsesize_ );
+ break;
+ case POINTER_WINDOW_NWSIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_top_left_corner );
+ break;
+ case POINTER_WINDOW_NESIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_top_right_corner );
+ break;
+ case POINTER_WINDOW_SWSIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_bottom_left_corner );
+ break;
+ case POINTER_WINDOW_SESIZE:
+ aCur = XCreateFontCursor( pDisp_, XC_bottom_right_corner );
+ break;
+ case POINTER_HSPLIT:
+ MAKE_CURSOR( hsplit_ );
+ break;
+ case POINTER_VSPLIT:
+ MAKE_CURSOR( vsplit_ );
+ break;
+ case POINTER_HSIZEBAR:
+ aCur = XCreateFontCursor( pDisp_, XC_sb_h_double_arrow ); // ???
+ break;
+ case POINTER_VSIZEBAR:
+ aCur = XCreateFontCursor( pDisp_, XC_sb_v_double_arrow ); // ???
+ break;
+ case POINTER_REFHAND:
+ aCur = XCreateFontCursor( pDisp_, XC_hand1 );
+ break;
+ case POINTER_HAND:
+ aCur = XCreateFontCursor( pDisp_, XC_hand2 );
+ break;
+ case POINTER_MAGNIFY:
+ MAKE_CURSOR( magnify_ );
+ break;
+ case POINTER_FILL:
+ MAKE_CURSOR( fill_ );
+ break;
+ case POINTER_MOVE:
+ MAKE_CURSOR( move_ );
+ break;
+ case POINTER_MOVEDATA:
+ MAKE_CURSOR( movedata_ );
+ break;
+ case POINTER_COPYDATA:
+ MAKE_CURSOR( copydata_ );
+ break;
+ case POINTER_MOVEFILE:
+ MAKE_CURSOR( movefile_ );
+ break;
+ case POINTER_COPYFILE:
+ MAKE_CURSOR( copyfile_ );
+ break;
+ case POINTER_MOVEFILES:
+ MAKE_CURSOR( movefiles_ );
+ break;
+ case POINTER_COPYFILES:
+ MAKE_CURSOR( copyfiles_ );
+ break;
+ case POINTER_NOTALLOWED:
+ MAKE_CURSOR( nodrop_ );
+ break;
+ case POINTER_ROTATE:
+ MAKE_CURSOR( rotate_ );
+ break;
+ case POINTER_HSHEAR:
+ MAKE_CURSOR( hshear_ );
+ break;
+ case POINTER_VSHEAR:
+ MAKE_CURSOR( vshear_ );
+ break;
+ case POINTER_DRAW_LINE:
+ MAKE_CURSOR( drawline_ );
+ break;
+ case POINTER_DRAW_RECT:
+ MAKE_CURSOR( drawrect_ );
+ break;
+ case POINTER_DRAW_POLYGON:
+ MAKE_CURSOR( drawpolygon_ );
+ break;
+ case POINTER_DRAW_BEZIER:
+ MAKE_CURSOR( drawbezier_ );
+ break;
+ case POINTER_DRAW_ARC:
+ MAKE_CURSOR( drawarc_ );
+ break;
+ case POINTER_DRAW_PIE:
+ MAKE_CURSOR( drawpie_ );
+ break;
+ case POINTER_DRAW_CIRCLECUT:
+ MAKE_CURSOR( drawcirclecut_ );
+ break;
+ case POINTER_DRAW_ELLIPSE:
+ MAKE_CURSOR( drawellipse_ );
+ break;
+ case POINTER_DRAW_CONNECT:
+ MAKE_CURSOR( drawconnect_ );
+ break;
+ case POINTER_DRAW_TEXT:
+ MAKE_CURSOR( drawtext_ );
+ break;
+ case POINTER_MIRROR:
+ MAKE_CURSOR( mirror_ );
+ break;
+ case POINTER_CROOK:
+ MAKE_CURSOR( crook_ );
+ break;
+ case POINTER_CROP:
+ MAKE_CURSOR( crop_ );
+ break;
+ case POINTER_MOVEPOINT:
+ MAKE_CURSOR( movepoint_ );
+ break;
+ case POINTER_MOVEBEZIERWEIGHT:
+ MAKE_CURSOR( movebezierweight_ );
+ break;
+ case POINTER_DRAW_FREEHAND:
+ MAKE_CURSOR( drawfreehand_ );
+ break;
+ case POINTER_DRAW_CAPTION:
+ MAKE_CURSOR( drawcaption_ );
+ break;
+ case POINTER_PEN: // Mouse Pointer ist ein Stift
+ aCur = XCreateFontCursor( pDisp_, XC_pencil );
+ break;
+ case POINTER_LINKDATA:
+ MAKE_CURSOR( linkdata_ );
+ break;
+ case POINTER_MOVEDATALINK:
+ MAKE_CURSOR( movedlnk_ );
+ break;
+ case POINTER_COPYDATALINK:
+ MAKE_CURSOR( copydlnk_ );
+ break;
+ case POINTER_LINKFILE:
+ MAKE_CURSOR( linkfile_ );
+ break;
+ case POINTER_MOVEFILELINK:
+ MAKE_CURSOR( moveflnk_ );
+ break;
+ case POINTER_COPYFILELINK:
+ MAKE_CURSOR( copyflnk_ );
+ break;
+ case POINTER_CHART:
+ MAKE_CURSOR( chart_ );
+ break;
+ case POINTER_DETECTIVE:
+ MAKE_CURSOR( detective_ );
+ break;
+ case POINTER_PIVOT_COL:
+ MAKE_CURSOR( pivotcol_ );
+ break;
+ case POINTER_PIVOT_ROW:
+ MAKE_CURSOR( pivotrow_ );
+ break;
+ case POINTER_PIVOT_FIELD:
+ MAKE_CURSOR( pivotfld_ );
+ break;
+ case POINTER_CHAIN:
+ MAKE_CURSOR( chain_ );
+ break;
+ case POINTER_CHAIN_NOTALLOWED:
+ MAKE_CURSOR( chainnot_ );
+ break;
+ case POINTER_TIMEEVENT_MOVE:
+ MAKE_CURSOR( timemove_ );
+ break;
+ case POINTER_TIMEEVENT_SIZE:
+ MAKE_CURSOR( timesize_ );
+ break;
+ case POINTER_AUTOSCROLL_N:
+ MAKE_CURSOR(asn_ );
+ break;
+ case POINTER_AUTOSCROLL_S:
+ MAKE_CURSOR( ass_ );
+ break;
+ case POINTER_AUTOSCROLL_W:
+ MAKE_CURSOR( asw_ );
+ break;
+ case POINTER_AUTOSCROLL_E:
+ MAKE_CURSOR( ase_ );
+ break;
+ case POINTER_AUTOSCROLL_NW:
+ MAKE_CURSOR( asnw_ );
+ break;
+ case POINTER_AUTOSCROLL_NE:
+ MAKE_CURSOR( asne_ );
+ break;
+ case POINTER_AUTOSCROLL_SW:
+ MAKE_CURSOR( assw_ );
+ break;
+ case POINTER_AUTOSCROLL_SE:
+ MAKE_CURSOR( asse_ );
+ break;
+ case POINTER_AUTOSCROLL_NS:
+ MAKE_CURSOR( asns_ );
+ break;
+ case POINTER_AUTOSCROLL_WE:
+ MAKE_CURSOR( aswe_ );
+ break;
+ case POINTER_AUTOSCROLL_NSWE:
+ MAKE_CURSOR( asnswe_ );
+ break;
+ case POINTER_AIRBRUSH:
+ MAKE_CURSOR( airbrush_ );
+ break;
+ default:
+ DBG_ERROR("pointer not implemented");
+ aCur = XCreateFontCursor( pDisp_, XC_arrow );
+ break;
+ }
+
+ if( None == aCur )
+ {
+ XColor aBlack, aWhite, aDummy;
+ Colormap hColormap = xColor_->GetXColormap();
+
+ XAllocNamedColor( pDisp_, hColormap, "black", &aBlack, &aDummy );
+ XAllocNamedColor( pDisp_, hColormap, "white", &aWhite, &aDummy );
+
+ aCur = XCreatePixmapCursor( pDisp_,
+ aCursBitmap, aMaskBitmap,
+ &aBlack, &aWhite,
+ nXHot, nYHot );
+
+ XFreePixmap( pDisp_, aCursBitmap );
+ XFreePixmap( pDisp_, aMaskBitmap );
+ }
+
+ return aCur;
+}
+
+int SalDisplay::CaptureMouse( SalFrameData *pCapture )
+{
+ if( !pCapture )
+ {
+ pCapture_ = NULL;
+ XUngrabPointer( GetDisplay(), CurrentTime );
+ XFlush( GetDisplay() );
+ return 0;
+ }
+
+ if( pCapture_ )
+ //pCapture_->CaptureMouse( FALSE );
+ pCapture_ = NULL;
+
+ int ret = XGrabPointer( GetDisplay(),
+ pCapture->GetWindow(),
+ False,
+ PointerMotionMask| ButtonPressMask|ButtonReleaseMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ None,
+ pCapture->GetCursor(),
+ CurrentTime );
+
+ if( ret != GrabSuccess )
+ {
+ DBG_ASSERT( 1, "SalDisplay::CaptureMouse could not grab pointer\n");
+ return -1;
+ }
+
+ pCapture_ = pCapture;
+ return 1;
+}
+
+// Fonts
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+static BOOL
+sal_IsValidFontpath( const ByteString &rFontPath,
+ const srv_vendor_t eServerVendor )
+{
+ // filter fontpath with ':unscaled' attribute for server other
+ // than xfree (e.g.: /opt/Office51/fonts/75dpi:unscaled)
+
+ const char aAttr[] = ":unscaled";
+ const USHORT nAttrLen = sizeof( aAttr ) - 1;
+ USHORT nAttrPos;
+
+ nAttrPos = rFontPath.Search( aAttr, 0 );
+ if ( nAttrPos == (rFontPath.Len() - nAttrLen) )
+ return (eServerVendor == vendor_xfree);
+
+ return TRUE;
+}
+
+final void SalDisplay::AddFontPath( const ByteString &rPath ) const
+{
+ const char cSeparator = ';' ;
+
+ if( rPath.Len()
+ && (GetServerVendor() != vendor_excursion)
+ && (GetServerVendor() != vendor_hummingbird) )
+ {
+ USHORT nCount = rPath.GetTokenCount( cSeparator );
+ int i;
+ int nPaths = 0;
+ char **pOldFontPath = XGetFontPath( pDisp_, &nPaths );
+ int nOriginalPaths = nPaths;
+ char **pNewFontPath = new char*[nPaths+nCount];
+ BOOL bOld = pXLib_->GetIgnoreXErrors();
+
+ for( i = 0; i < nPaths; i++ )
+ pNewFontPath[i] = pOldFontPath[i];
+
+ for( USHORT nNew = 0; nNew < nCount; nNew++ )
+ {
+ ByteString aPathName = rPath.GetToken( nNew, cSeparator );
+
+ if( aPathName.Len() )
+ {
+ for( i = 0; i < nPaths; i++ )
+ if( !strcmp( pNewFontPath[i], aPathName.GetBuffer() ) )
+ break;
+
+ if ( (i == nPaths)
+ && sal_IsValidFontpath(aPathName, GetServerVendor()) )
+ {
+ pNewFontPath[nPaths] = new char[aPathName.Len()+1];
+ strcpy( pNewFontPath[nPaths++], aPathName.GetBuffer() );
+ pXLib_->SetIgnoreXErrors( TRUE ); // reset WasXError
+
+ XSetFontPath( pDisp_, pNewFontPath, nPaths );
+ XSync( pDisp_, False );
+ if( pXLib_->WasXError() )
+ delete pNewFontPath[--nPaths];
+ }
+ }
+ }
+
+ while( nPaths-- > nOriginalPaths )
+ delete pNewFontPath[ nPaths ];
+
+ delete pNewFontPath;
+ XFreeFontPath( pOldFontPath );
+
+
+ pXLib_->SetIgnoreXErrors( bOld );
+ }
+}
+
+// Events
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalDisplay::Remove( XEvent *pEvent )
+{
+}
+
+final void SalDisplay::SendEvent( Atom aEvent,
+ void *pData,
+ XLIB_Window hReceiver ) const
+{
+ UINT32 aData[5];
+
+#if __SIZEOFLONG > 4
+ aData[0] = (UINT32)((long)pData & 0xffffffff);
+ aData[1] = (UINT32)((long)pData >> 32);
+#else
+ aData[0] = (UINT32)(long)pData;
+ aData[1] = NULL;
+#endif
+ aData[2] = NULL;
+#ifndef DBG_UTIL
+ aData[3] = NULL;
+ aData[4] = NULL;
+#else
+ aData[3] = ++nIn___;
+ aData[4] = nOut___;
+#endif
+ SendEvent( aEvent, aData, hReceiver );
+}
+
+final void SalDisplay::SendEvent( Atom aEvent,
+ UINT32 *Data,
+ XLIB_Window hReceiver ) const
+{
+#define pClient (&(aClient.xclient))
+ XEvent aClient;
+
+ if( !hReceiver )
+ hReceiver = GetWindow();
+
+ pClient->type = ClientMessage;
+ pClient->display = pDisp_;
+ pClient->window = hReceiver;
+ pClient->message_type = aEvent;
+ pClient->format = 32;
+
+ if( Data ) for( int i = 0; i < 5; i++ )
+ pClient->data.l[i] = Data[i];
+
+ if( osl_acquireMutex( hEventGuard_ ) )
+ {
+ pClient->send_event = 2;
+ if( pEventQueue_ )
+ {
+ SalXEvent *pEvent = pEventQueue_;
+ while( pEvent->pNext_ )
+ pEvent = pEvent->pNext_;
+
+ pEvent->pNext_ = new SalXEvent;
+ pEvent->pNext_->event_ = aClient;
+ pEvent->pNext_->pNext_ = NULL;
+ }
+ else
+ {
+ ((SalDisplay*)this)->pEventQueue_ = new SalXEvent;
+ pEventQueue_->event_ = aClient;
+ pEventQueue_->pNext_ = NULL;
+ }
+
+ osl_releaseMutex( hEventGuard_ );
+ }
+ else
+ DBG_ASSERT( 1, "SalDisplay::SendEvent !acquireMutex\n" );
+#undef pClient
+}
+
+final BOOL SalDisplay::IsEvent()
+{
+ if( pEventQueue_ )
+ return TRUE;
+
+ if( XEventsQueued( pDisp_, QueuedAlready ) )
+ return TRUE;
+
+ XFlush( pDisp_ );
+ return FALSE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+final void SalDisplay::Yield( BOOL bWait )
+{
+ SalXEvent aEvent;
+ while( !nStateOfYield_ )
+ {
+ if( pEventQueue_ )
+ {
+ nStateOfYield_ = 5;
+ if( osl_acquireMutex( hEventGuard_ ) )
+ {
+ nStateOfYield_ = 6;
+
+ SalXEvent *pEvent = pEventQueue_;
+
+ pEventQueue_ = pEventQueue_->pNext_;
+
+ osl_releaseMutex( hEventGuard_ );
+
+ aEvent.event_ = pEvent->event_;
+
+ delete pEvent;
+
+ break;
+ }
+ else
+ DBG_ASSERT( 1, "SalDisplay::Yield !acquireMutex\n" );
+ }
+
+ nStateOfYield_ = 1;
+
+ DBG_ASSERT( XtAppPending( pXLib_->GetAppContext() ), "no pending event" );
+ SalData *pSalData = GetSalData();
+ SalYieldMutex* pSalInstYieldMutex =
+ pSalData->pFirstInstance_->maInstData.mpSalYieldMutex;
+
+ DBG_ASSERT( pSalInstYieldMutex->GetThreadId() ==
+ NAMESPACE_VOS(OThread)::getCurrentIdentifier(),
+ "will crash soon since solar mutex not locked in SalDisplay::Yield" );
+
+ // note: alternate input is dispatched by XtAppNextEvent
+ XtAppNextEvent( pXLib_->GetAppContext(), &aEvent.event_ );
+ }
+
+ nStateOfYield_ = 0;
+
+ BOOL bIgnoreXErrors = pXLib_->GetIgnoreXErrors();
+
+ aEvent.pNext_ = pDispatchStack_;
+ pDispatchStack_ = &aEvent;
+
+ Dispatch( &aEvent.event_ );
+
+ pDispatchStack_ = aEvent.pNext_;
+
+#ifdef DBG_UTIL
+ if( pXLib_->WasXError() )
+ {
+ XFlush( pDisp_ );
+ PrintEvent( "SalDisplay::Yield (WasXError)", &aEvent.event_ );
+ }
+#endif
+
+ pXLib_->SetIgnoreXErrors( bIgnoreXErrors );
+}
+
+final long SalDisplay::Dispatch( XEvent *pEvent )
+{
+ if( pEvent->type == XLIB_KeyPress || pEvent->type == KeyRelease )
+ {
+ XLIB_Window aWindow = pEvent->xkey.window;
+ SalFrame* pFrame = NULL;
+ for( pFrame = GetSalData()->pFirstFrame_;
+ pFrame
+ && pFrame->maFrameData.GetWindow() != aWindow
+ && pFrame->maFrameData.GetShellWindow() != aWindow;
+ pFrame = pFrame->maFrameData.GetNextFrame() )
+ ;
+ if( pFrame )
+ if ( mpInputMethod->FilterEvent( pEvent ) )
+ return 0;
+ }
+ else
+ if ( mpInputMethod->FilterEvent( pEvent ) )
+ return 0;
+
+ DtIntegrator::HandleXEvent( pEvent );
+
+ switch( pEvent->type )
+ {
+ case MotionNotify:
+ while( XCheckWindowEvent( pEvent->xany.display,
+ pEvent->xany.window,
+ ButtonMotionMask,
+ pEvent ) )
+ nop;
+ break;
+
+ case MappingNotify:
+ if( MappingKeyboard == pEvent->xmapping.request )
+ XRefreshKeyboardMapping( &pEvent->xmapping );
+ else if( MappingModifier == pEvent->xmapping.request )
+ ModifierMapping();
+ break;
+
+ default:
+
+ if ( GetKbdExtension()->UseExtension()
+ && GetKbdExtension()->GetEventBase() == pEvent->type )
+ {
+ GetKbdExtension()->Dispatch( pEvent );
+ return 1;
+ }
+
+#ifdef _XSHM_H_
+ {
+ BOOL bPrevious = pXLib_->GetIgnoreXErrors();
+ pXLib_->SetIgnoreXErrors( TRUE );
+ if( pEvent->type == XShmGetEventBase( pDisp_ ) + ShmCompletion )
+ {
+ Remove( pEvent );
+ return 1;
+ }
+ pXLib_->SetIgnoreXErrors( bPrevious );
+ }
+#endif
+ break;
+ }
+
+ SalFrame *pFrame = GetSalData()->pFirstFrame_;
+
+ while( pFrame )
+ {
+ if( pFrame->maFrameData.GetWindow() == pEvent->xany.window ||
+ pFrame->maFrameData.GetShellWindow() == pEvent->xany.window )
+ {
+ return pFrame->maFrameData.Dispatch( pEvent );
+ }
+ if( pFrame->maFrameData.GetForeignParent() == pEvent->xany.window ||
+ pFrame->maFrameData.GetForeignTopLevelWindow() == pEvent->xany.window )
+ {
+ pFrame->maFrameData.Dispatch( pEvent );
+ break;
+ }
+ pFrame = pFrame->maFrameData.GetNextFrame(); // not allways NULL
+ }
+
+ // dispatch to Xt
+ XtDispatchEvent( pEvent );
+
+ // dispatch to salobjects
+ SalObjectData::Dispatch( pEvent );
+
+ return 0;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalDisplay::PrintEvent( const ByteString &rComment,
+ XEvent *pEvent ) const
+{
+ if( pEvent->type <= MappingNotify )
+ {
+ fprintf( stderr, "[%s] %s s=%d w=%ld\n",
+ rComment.GetBuffer(),
+ EventNames[pEvent->type],
+ pEvent->xany.send_event,
+ pEvent->xany.window );
+
+ switch( pEvent->type )
+ {
+ case XLIB_KeyPress:
+ case KeyRelease:
+ fprintf( stderr, "\t\ts=%d c=%d\n",
+ pEvent->xkey.state,
+ pEvent->xkey.keycode );
+ break;
+
+ case ButtonPress:
+ case ButtonRelease:
+ fprintf( stderr, "\t\ts=%d b=%d x=%d y=%d rx=%d ry=%d\n",
+ pEvent->xbutton.state,
+ pEvent->xbutton.button,
+ pEvent->xbutton.x,
+ pEvent->xbutton.y,
+ pEvent->xbutton.x_root,
+ pEvent->xbutton.y_root );
+ break;
+
+ case MotionNotify:
+ fprintf( stderr, "\t\ts=%d x=%d y=%d\n",
+ pEvent->xmotion.state,
+ pEvent->xmotion.x,
+ pEvent->xmotion.y );
+ break;
+
+ case EnterNotify:
+ case LeaveNotify:
+ fprintf( stderr, "\t\tm=%d f=%d x=%d y=%d\n",
+ pEvent->xcrossing.mode,
+ pEvent->xcrossing.focus,
+ pEvent->xcrossing.x,
+ pEvent->xcrossing.y );
+ break;
+
+ case FocusIn:
+ case FocusOut:
+ fprintf( stderr, "\t\tm=%d d=%d\n",
+ pEvent->xfocus.mode,
+ pEvent->xfocus.detail );
+ break;
+
+ case Expose:
+ case GraphicsExpose:
+ fprintf( stderr, "\t\tc=%d %d*%d %d+%d\n",
+ pEvent->xexpose.count,
+ pEvent->xexpose.width,
+ pEvent->xexpose.height,
+ pEvent->xexpose.x,
+ pEvent->xexpose.y );
+ break;
+
+ case VisibilityNotify:
+ fprintf( stderr, "\t\ts=%d\n",
+ pEvent->xvisibility.state );
+ break;
+
+ case CreateNotify:
+ case DestroyNotify:
+ break;
+
+ case MapNotify:
+ case UnmapNotify:
+ break;
+
+ case ReparentNotify:
+ fprintf( stderr, "\t\tp=%d x=%d y=%d\n",
+ pEvent->xreparent.parent,
+ pEvent->xreparent.x,
+ pEvent->xreparent.y );
+ break;
+
+ case ConfigureNotify:
+ fprintf( stderr, "\t\tb=%d %d*%d %d+%d\n",
+ pEvent->xconfigure.border_width,
+ pEvent->xconfigure.width,
+ pEvent->xconfigure.height,
+ pEvent->xconfigure.x,
+ pEvent->xconfigure.y );
+ break;
+
+ case PropertyNotify:
+ fprintf( stderr, "\t\ta=%s (0x%X)\n",
+ GetAtomName( pDisp_, pEvent->xproperty.atom ),
+ pEvent->xproperty.atom );
+ break;
+
+ case ColormapNotify:
+ fprintf( stderr, "\t\tc=%ld n=%d s=%d\n",
+ pEvent->xcolormap.colormap,
+ pEvent->xcolormap.c_new,
+ pEvent->xcolormap.state );
+ break;
+
+ case ClientMessage:
+ fprintf( stderr, "\t\ta=%s (0x%X) f=%i [0x%lX,0x%lX,0x%lX,0x%lX,0x%lX])\n",
+ GetAtomName( pDisp_, pEvent->xclient.message_type ),
+ pEvent->xclient.message_type,
+ pEvent->xclient.format,
+ pEvent->xclient.data.l[0],
+ pEvent->xclient.data.l[1],
+ pEvent->xclient.data.l[2],
+ pEvent->xclient.data.l[3],
+ pEvent->xclient.data.l[4] );
+ break;
+
+ case MappingNotify:
+ fprintf( stderr, "\t\tr=%sd\n",
+ MappingModifier == pEvent->xmapping.request
+ ? "MappingModifier"
+ : MappingKeyboard == pEvent->xmapping.request
+ ? "MappingKeyboard"
+ : "MappingPointer" );
+
+ break;
+ }
+ }
+#ifdef _XSHM_H_
+ else if( pEvent->type == XShmGetEventBase( pDisp_ ) + ShmCompletion )
+ {
+#define pCompletionEvent ((XShmCompletionEvent*)pEvent)
+ fprintf( stderr, "[%s] %s s=%d d=%ld\n",
+ rComment.GetBuffer(),
+ "ShmCompletion",
+ pCompletionEvent->send_event,
+ pCompletionEvent->drawable );
+
+ fprintf( stderr, "\t\tc=%d.%d s=%ld o=%ld\n",
+ pCompletionEvent->major_code,
+ pCompletionEvent->minor_code,
+ pCompletionEvent->shmseg,
+ pCompletionEvent->offset );
+#undef pCompletionEvent
+ }
+#endif
+ else
+ fprintf( stderr, "[%s] %d s=%d w=%ld\n",
+ rComment.GetBuffer(),
+ pEvent->type,
+ pEvent->xany.send_event,
+ pEvent->xany.window );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalDisplay::PrintInfo() const
+{
+ if( IsDisplay() )
+ {
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "Environment\n" );
+ fprintf( stderr, "\t$XENVIRONMENT \t\"%s\"\n",
+ GetEnv( "XENVIRONMENT" ) );
+ fprintf( stderr, "\t$DISPLAY \t\"%s\"\n",
+ GetEnv( "DISPLAY" ) );
+ fprintf( stderr, "\t$SAL_VISUAL \t\"%s\"\n",
+ GetEnv( "SAL_VISUAL" ) );
+ fprintf( stderr, "\t$SAL_FONTPATH \t\"%s\"\n",
+ GetEnv( "SAL_FONTPATH" ) );
+ fprintf( stderr, "\t$SAL_NOSEGV \t\"%s\"\n",
+ GetEnv( "SAL_NOSEGV" ) );
+ fprintf( stderr, "\t$SAL_IGNOREXERRORS\t\"%s\"\n",
+ GetEnv( "SAL_IGNOREXERRORS" ) );
+ fprintf( stderr, "\t$SAL_PROPERTIES \t\"%s\"\n",
+ GetEnv( "SAL_PROPERTIES" ) );
+ fprintf( stderr, "\t$SAL_WM \t\"%s\"\n",
+ GetEnv( "SAL_WM" ) );
+ fprintf( stderr, "\t$SAL_SYNCHRONIZE \t\"%s\"\n",
+ GetEnv( "SAL_SYNCHRONIZE" ) );
+ fprintf( stderr, "\t$XPPATH \t\"%s\"\n",
+ GetEnv( "XPPATH" ) );
+
+ char sHostname[ 120 ];
+# ifdef USE_XMU
+ XmuGetHostname( sHostname, 120 );
+# else
+ gethostname (sHostname, 120 );
+# endif
+ fprintf( stderr, "Client\n" );
+ fprintf( stderr, "\tHost \t\"%s\"\n",
+ sHostname );
+
+ fprintf( stderr, "Display\n" );
+ fprintf( stderr, "\tHost \t\"%s\"\n",
+ DisplayString(pDisp_) );
+ fprintf( stderr, "\tVendor (Release) \t\"%s (%d)\"\n",
+ ServerVendor(pDisp_), VendorRelease(pDisp_) );
+ fprintf( stderr, "\tProtocol \t%d.%d\n",
+ ProtocolVersion(pDisp_), ProtocolRevision(pDisp_) );
+ fprintf( stderr, "\tScreen (count,def)\t%d (%d,%d)\n",
+ nScreen_, ScreenCount(pDisp_), DefaultScreen(pDisp_) );
+ fprintf( stderr, "\tshift ctrl alt \t%s (0x%X) %s (0x%X) %s (0x%X)\n",
+ KeyStr( nShiftKeySym_ ), nShiftKeySym_,
+ KeyStr( nCtrlKeySym_ ), nCtrlKeySym_,
+ KeyStr( nMod1KeySym_ ), nMod1KeySym_ );
+ if( XExtendedMaxRequestSize(pDisp_) * 4 )
+ fprintf( stderr, "\tXMaxRequestSize \t%ld %ld [bytes]\n",
+ XMaxRequestSize(pDisp_) * 4, XExtendedMaxRequestSize(pDisp_) * 4 );
+ if( GetProperties() != PROPERTY_DEFAULT )
+ fprintf( stderr, "\tProperties \t0x%lX\n", GetProperties() );
+ if( eWindowManager_ != otherwm )
+ fprintf( stderr, "\tWindowmanager \t%d\n", eWindowManager_ );
+ }
+ fprintf( stderr, "Screen\n" );
+ fprintf( stderr, "\tResolution/Size \t%d*%d %d*%d %.1lf\"\n",
+ aResolution_.A(), aResolution_.B(),
+ aSize_.Width(), aSize_.Height(),
+ Hypothenuse( DisplayWidthMM ( pDisp_, nScreen_ ),
+ DisplayHeightMM( pDisp_, nScreen_ ) ) / 25.4 );
+ fprintf( stderr, "\tBlack&White \t%lu %lu\n",
+ xColor_->GetBlackPixel(), xColor_->GetWhitePixel() );
+ fprintf( stderr, "\tRGB \t0x%lx 0x%lx 0x%lx\n",
+ pVisual_->red_mask, pVisual_->green_mask, pVisual_->blue_mask );
+ fprintf( stderr, "\tVisual \t%d-bit %s ID=0x%x\n",
+ pVisual_->GetDepth(),
+ VisualClassName[ pVisual_->GetClass() ],
+ pVisual_->GetVisualId() );
+ if( pVisual_ != pRootVisual_ )
+ fprintf( stderr, "\tRoot visual \t%d-bit %s ID=0x%x\n",
+ pRootVisual_->GetDepth(),
+ VisualClassName[ pRootVisual_->GetClass() ],
+ pRootVisual_->GetVisualId() );
+ fprintf( stderr, "\tImages (Shared) \t0x%lx (%lx)\n",
+ nImageDepths_, nSharedImages_ );
+
+ if( nStateOfYield_ || nStateOfSendEvent_ )
+ {
+ fprintf( stderr, "Thread/Signal\n" );
+ fprintf( stderr, "\tNextEvent \t%d\n", nStateOfYield_ );
+ fprintf( stderr, "\tSendEvent \t%d\n", nStateOfSendEvent_ );
+ }
+ if( pDispatchStack_ )
+ {
+ fprintf( stderr, "Event\n" );
+ SalXEvent *pEvent = pDispatchStack_;
+ while( pEvent )
+ {
+ PrintEvent( "\t\x08\x08", &pEvent->event_ );
+ pEvent = pEvent->pNext_;
+ }
+ }
+}
+
+// -=-= SalICCCM -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final
+SalICCCM::SalICCCM( SalDisplay *pDisplay )
+{
+ Display *display = pDisplay->GetDisplay();
+
+ for( int i = 0; i < capacityof( AtomStrings ); i++ )
+ (&aWM_Protocols_)[i] = XInternAtom( display, AtomStrings[i], False );
+}
+
+// -=-= SalVisual -=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+SalVisual::SalVisual( const XVisualInfo* pXVI )
+{
+ *(XVisualInfo*)this = *pXVI;
+ if( GetClass() == TrueColor )
+ {
+ nRedShift_ = sal_Shift( red_mask );
+ nGreenShift_ = sal_Shift( green_mask );
+ nBlueShift_ = sal_Shift( blue_mask );
+
+ if( GetDepth() == 24 )
+ if( red_mask == 0xFF0000 )
+ if( green_mask == 0xFF00 )
+ if( blue_mask == 0xFF )
+ eRGBMode_ = RGB;
+ else
+ eRGBMode_ = other;
+ else if( blue_mask == 0xFF00 )
+ if( green_mask == 0xFF )
+ eRGBMode_ = RBG;
+ else
+ eRGBMode_ = other;
+ else
+ eRGBMode_ = other;
+ else if( green_mask == 0xFF0000 )
+ if( red_mask == 0xFF00 )
+ if( blue_mask == 0xFF )
+ eRGBMode_ = GRB;
+ else
+ eRGBMode_ = other;
+ else if( blue_mask == 0xFF00 )
+ if( red_mask == 0xFF )
+ eRGBMode_ = GBR;
+ else
+ eRGBMode_ = other;
+ else
+ eRGBMode_ = other;
+ else if( blue_mask == 0xFF0000 )
+ if( red_mask == 0xFF00 )
+ if( green_mask == 0xFF )
+ eRGBMode_ = BRG;
+ else
+ eRGBMode_ = other;
+ else if( green_mask == 0xFF00 )
+ if( red_mask == 0xFF )
+ eRGBMode_ = BGR;
+ else
+ eRGBMode_ = other;
+ else
+ eRGBMode_ = other;
+ else
+ eRGBMode_ = other;
+ else
+ eRGBMode_ = other;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+SalVisual::~SalVisual()
+{
+ if( -1 == screen && -1 == visualid ) delete visual;
+}
+
+// Konvertiert die Reihenfolge der Bytes eines Pixel in Bytes eines SalColors
+// fuer die 6 XXXA ist das nicht reversibel
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// SalColor is RGB (ABGR) a=0xFF000000, r=0xFF0000, g=0xFF00, b=0xFF
+
+#define SALCOLOR RGB
+#define SALCOLORREVERSE BGR
+
+BOOL SalVisual::Convert( int &n0, int &n1, int &n2, int &n3 )
+{
+ int n;
+
+ switch( GetMode() )
+ {
+ case other:
+ return FALSE;
+ break;
+ case SALCOLOR:
+ break;
+ case SALCOLORREVERSE:
+ case RBG:
+ case BRG:
+ case GBR:
+ case GRB:
+ return Convert( n0, n1, n2 );
+ break;
+ case RGBA:
+ n = n0;
+ n0 = n1;
+ n1 = n2;
+ n2 = n3;
+ n3 = n;
+ break;
+ case BGRA:
+ case RBGA:
+ case BRGA:
+ case GBRA:
+ case GRBA:
+ default:
+ fprintf( stderr, "SalVisual::Convert %d\n", GetMode() );
+ abort();
+ break;
+ }
+ return TRUE;
+}
+
+BOOL SalVisual::Convert( int &n0, int &n1, int &n2 )
+{
+ int n;
+
+ switch( GetMode() )
+ {
+ case other:
+ return FALSE;
+ break;
+ case SALCOLOR:
+ break;
+ case RBG:
+ n = n0;
+ n0 = n1;
+ n1 = n;
+ break;
+ case GRB:
+ n = n1;
+ n1 = n2;
+ n2 = n;
+ break;
+ case SALCOLORREVERSE:
+ n = n0;
+ n0 = n2;
+ n2 = n;
+ break;
+ case BRG:
+ n = n0;
+ n0 = n1;
+ n1 = n2;
+ n2 = n;
+ break;
+ case GBR:
+ n = n2;
+ n2 = n1;
+ n1 = n0;
+ n0 = n;
+ break;
+ default:
+ fprintf( stderr, "SalVisual::Convert %d\n", GetMode() );
+ abort();
+ break;
+ }
+ return TRUE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalColor SalVisual::GetTCColor( Pixel nPixel ) const
+{
+ if( SALCOLOR == eRGBMode_ )
+ return (SalColor)nPixel;
+
+ if( SALCOLORREVERSE == eRGBMode_ )
+ return MAKE_SALCOLOR( (nPixel & 0x0000FF),
+ (nPixel & 0x00FF00) >> 8,
+ (nPixel & 0xFF0000) >> 16);
+
+ Pixel r = nPixel & red_mask;
+ Pixel g = nPixel & green_mask;
+ Pixel b = nPixel & blue_mask;
+
+ if( other != eRGBMode_ ) // 8+8+8=24
+ return MAKE_SALCOLOR( r >> nRedShift_,
+ g >> nGreenShift_,
+ b >> nBlueShift_ );
+
+ if( nRedShift_ > 0 ) r >>= nRedShift_; else r <<= -nRedShift_;
+ if( nGreenShift_ > 0 ) g >>= nGreenShift_; else g <<= -nGreenShift_;
+ if( nBlueShift_ > 0 ) b >>= nBlueShift_; else b <<= -nBlueShift_;
+
+ return MAKE_SALCOLOR( r, g, b );
+}
+
+final Pixel SalVisual::GetTCPixel( SalColor nSalColor ) const
+{
+ if( SALCOLOR == eRGBMode_ )
+ return (Pixel)nSalColor;
+
+ Pixel r = (Pixel)SALCOLOR_RED( nSalColor );
+ Pixel g = (Pixel)SALCOLOR_GREEN( nSalColor );
+ Pixel b = (Pixel)SALCOLOR_BLUE( nSalColor );
+
+ if( SALCOLORREVERSE == eRGBMode_ )
+ return (b << 16) | (g << 8) | (r);
+
+ if( other != eRGBMode_ ) // 8+8+8=24
+ return (r << nRedShift_) | (g << nGreenShift_) | (b << nBlueShift_);
+
+ if( nRedShift_ > 0 ) r <<= nRedShift_; else r >>= -nRedShift_;
+ if( nGreenShift_ > 0 ) g <<= nGreenShift_; else g >>= -nGreenShift_;
+ if( nBlueShift_ > 0 ) b <<= nBlueShift_; else b >>= -nBlueShift_;
+
+ return (r&red_mask) | (g&green_mask) | (b&blue_mask);
+}
+
+// -=-= SalColormap -=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalColormap::SalColormap( SalDisplay *pDisplay, Colormap hColormap )
+ : pDisplay_( pDisplay ),
+ hColormap_( hColormap ),
+ pPalette_( NULL ),
+ pLookupTable_( NULL )
+{
+ pVisual_ = pDisplay_->GetVisual();
+
+ if( pVisual_ == pDisplay_->GetRootVisual() )
+ {
+ nBlackPixel_ = BlackPixel( pDisplay_->GetDisplay(),
+ pDisplay_->GetScreenNumber() );
+ nWhitePixel_ = WhitePixel( pDisplay_->GetDisplay(),
+ pDisplay_->GetScreenNumber() );
+ }
+ else
+ {
+ XColor aColor;
+
+ GetXPixel( aColor, 0x00, 0x00, 0x00 );
+ nBlackPixel_ = aColor.pixel;
+
+ GetXPixel( aColor, 0xFF, 0xFF, 0xFF );
+ nWhitePixel_ = aColor.pixel;
+ }
+
+ nUsed_ = 1 << pVisual_->GetDepth();
+
+ if( pVisual_->GetClass() == PseudoColor )
+ {
+ XColor aColor;
+ int r, g, b;
+
+ // black, white, gray, ~gray = 4
+ GetXPixels( aColor, 0xC0, 0xC0, 0xC0 );
+
+ // light colors: 3 * 2 = 6
+// GetXPixels( aColor, 0x00, 0x00, 0x00 );
+ GetXPixels( aColor, 0x00, 0x00, 0xFF );
+ GetXPixels( aColor, 0x00, 0xFF, 0x00 );
+ GetXPixels( aColor, 0x00, 0xFF, 0xFF );
+// GetXPixels( aColor, 0xFF, 0x00, 0x00 );
+// GetXPixels( aColor, 0xFF, 0x00, 0xFF );
+// GetXPixels( aColor, 0xFF, 0xFF, 0x00 );
+// GetXPixels( aColor, 0xFF, 0xFF, 0xFF );
+
+ // standard colors: 7 * 2 = 14
+// GetXPixels( aColor, 0x00, 0x00, 0x00 );
+ GetXPixels( aColor, 0x00, 0x00, 0x80 );
+ GetXPixels( aColor, 0x00, 0x80, 0x00 );
+ GetXPixels( aColor, 0x00, 0x80, 0x80 );
+ GetXPixels( aColor, 0x80, 0x00, 0x00 );
+ GetXPixels( aColor, 0x80, 0x00, 0x80 );
+ GetXPixels( aColor, 0x80, 0x80, 0x00 );
+ GetXPixels( aColor, 0x80, 0x80, 0x80 );
+ GetXPixels( aColor, 0x00, 0xB8, 0xFF ); // Blau 7
+
+ // cube: 6*6*6 - 8 = 208
+ for( r = 0; r < 0x100; r += 0x33 ) // 0x33, 0x66, 0x99, 0xCC, 0xFF
+ for( g = 0; g < 0x100; g += 0x33 )
+ for( b = 0; b < 0x100; b += 0x33 )
+ GetXPixels( aColor, r, g, b );
+
+ // gray: 16 - 6 = 10
+ for( g = 0x11; g < 0xFF; g += 0x11 )
+ GetXPixels( aColor, g, g, g );
+
+ // green: 16 - 6 = 10
+ for( g = 0x11; g < 0xFF; g += 0x11 )
+ GetXPixels( aColor, 0, g, 0 );
+
+ // red: 16 - 6 = 10
+ for( r = 0x11; r < 0xFF; r += 0x11 )
+ GetXPixels( aColor, r, 0, 0 );
+
+ // blue: 16 - 6 = 10
+ for( b = 0x11; b < 0xFF; b += 0x11 )
+ GetXPixels( aColor, 0, 0, b );
+ }
+}
+
+// PseudoColor
+final SalColormap::SalColormap( const BitmapPalette &rPalette )
+ : pDisplay_( GetSalData()->GetCurDisp() ),
+ hColormap_( None ),
+ pVisual_( NULL ),
+ nUsed_( rPalette.GetEntryCount() ),
+ nBlackPixel_( 0xFFFFFFFF ),
+ nWhitePixel_( 0xFFFFFFFF ),
+ pLookupTable_( NULL )
+{
+ pPalette_ = new SalColor[nUsed_];
+
+ for( int i = 0; i < nUsed_; i++ )
+ {
+ const BitmapColor &rColor = rPalette[i];
+ pPalette_[i] = MAKE_SALCOLOR( rColor.GetRed(),
+ rColor.GetGreen(),
+ rColor.GetBlue() );
+ if( nBlackPixel_ == 0xFFFFFFFF && SALCOLOR_BLACK == pPalette_[i] )
+ nBlackPixel_ = i;
+ else if( nWhitePixel_ == 0xFFFFFFFF && SALCOLOR_WHITE == pPalette_[i] )
+ nWhitePixel_ = i;
+ }
+}
+
+// MonoChrome
+final SalColormap::SalColormap()
+ : pDisplay_( GetSalData()->GetCurDisp() ),
+ hColormap_( None ),
+ pVisual_( NULL ),
+ nUsed_( 2 ),
+ nBlackPixel_( 0 ),
+ nWhitePixel_( 1 ),
+ pLookupTable_( NULL )
+{
+ pPalette_ = new SalColor[nUsed_];
+
+ pPalette_[nBlackPixel_] = SALCOLOR_BLACK;
+ pPalette_[nWhitePixel_] = SALCOLOR_WHITE;
+}
+
+// TrueColor
+final SalColormap::SalColormap( USHORT nDepth )
+ : pDisplay_( GetSalData()->GetCurDisp() ),
+ hColormap_( None ),
+ pPalette_( NULL ),
+ nUsed_( 1 << nDepth ),
+ nWhitePixel_( (1 << nDepth) - 1 ),
+ nBlackPixel_( 0x00000000 ),
+ pLookupTable_( NULL )
+
+{
+ SalVisual *pVisual = pDisplay_->GetVisual();
+
+ if( pVisual->GetClass() == TrueColor && pVisual->GetDepth() == nDepth )
+ pVisual_ = pVisual;
+ else
+ {
+ XVisualInfo aVI;
+
+ if( !XMatchVisualInfo( pDisplay_->GetDisplay(),
+ pDisplay_->GetScreenNumber(),
+ nDepth,
+ TrueColor,
+ &aVI ) )
+ {
+ aVI.visual = new Visual();
+ aVI.visualid = (VisualID)-1;
+ aVI.screen = -1;
+ aVI.depth = nDepth;
+ aVI.c_class = TrueColor;
+ if( 24 == nDepth ) // 888
+ {
+ aVI.red_mask = 0xFF0000;
+ aVI.green_mask = 0x00FF00;
+ aVI.blue_mask = 0x0000FF;
+ }
+ else if( 16 == nDepth ) // 565
+ {
+ aVI.red_mask = 0x00F800;
+ aVI.green_mask = 0x0007E0;
+ aVI.blue_mask = 0x00001F;
+ }
+ else if( 15 == nDepth ) // 555
+ {
+ aVI.red_mask = 0x007C00;
+ aVI.green_mask = 0x0003E0;
+ aVI.blue_mask = 0x00001F;
+ }
+ else if( 12 == nDepth ) // 444
+ {
+ aVI.red_mask = 0x000F00;
+ aVI.green_mask = 0x0000F0;
+ aVI.blue_mask = 0x00000F;
+ }
+ else if( 8 == nDepth ) // 332
+ {
+ aVI.red_mask = 0x0000E0;
+ aVI.green_mask = 0x00001C;
+ aVI.blue_mask = 0x000003;
+ }
+ else
+ {
+ aVI.red_mask = 0x000000;
+ aVI.green_mask = 0x000000;
+ aVI.blue_mask = 0x000000;
+ }
+ aVI.colormap_size = 0;
+ aVI.bits_per_rgb = 8;
+
+ aVI.visual->ext_data = NULL;
+ aVI.visual->visualid = aVI.visualid;
+ aVI.visual->c_class = aVI.c_class;
+ aVI.visual->red_mask = aVI.red_mask;
+ aVI.visual->green_mask = aVI.green_mask;
+ aVI.visual->blue_mask = aVI.blue_mask;
+ aVI.visual->bits_per_rgb = aVI.bits_per_rgb;
+ aVI.visual->map_entries = aVI.colormap_size;
+ }
+
+ pVisual_ = new SalVisual( &aVI );
+ }
+}
+
+final SalColormap::~SalColormap()
+{
+ if( hColormap_
+ && pDisplay_->IsDisplay()
+ && hColormap_ != DefaultColormap( GetXDisplay(), pDisplay_->GetScreenNumber() ) )
+ XFreeColormap( GetXDisplay(), hColormap_ );
+ delete pPalette_;
+ delete pLookupTable_;
+ if( pVisual_ != pDisplay_->GetVisual() )
+ delete pVisual_;
+
+#ifdef DBG_UTIL
+ hColormap_ = (Colormap)ILLEGAL_POINTER;
+ pDisplay_ = (SalDisplay*)ILLEGAL_POINTER;
+ pPalette_ = (SalColor*)ILLEGAL_POINTER;
+ pLookupTable_ = (USHORT*)ILLEGAL_POINTER;
+ pVisual_ = (SalVisual*)ILLEGAL_POINTER;
+#endif
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalColormap::SetPalette( const BitmapPalette &rPalette )
+{
+ if( this != &GetSalData()->GetCurDisp()->GetColormap() )
+ {
+ nBlackPixel_ = 0xFFFFFFFF;
+ nWhitePixel_ = 0xFFFFFFFF;
+ }
+
+ if( rPalette.GetEntryCount() > nUsed_ )
+ {
+ nBlackPixel_ = 0xFFFFFFFF;
+ nWhitePixel_ = 0xFFFFFFFF;
+ delete pPalette_;
+ pPalette_ = new SalColor[rPalette.GetEntryCount()];
+ nUsed_ = rPalette.GetEntryCount();
+ }
+
+ for( int i = 0; i < rPalette.GetEntryCount(); i++ )
+ {
+ const BitmapColor &rColor = rPalette[i];
+ pPalette_[i] = MAKE_SALCOLOR( rColor.GetRed(),
+ rColor.GetGreen(),
+ rColor.GetBlue() );
+ if( nBlackPixel_ == 0xFFFFFFFF && SALCOLOR_BLACK == pPalette_[i] )
+ nBlackPixel_ = i;
+ else if( nWhitePixel_ == 0xFFFFFFFF && SALCOLOR_WHITE == pPalette_[i] )
+ nWhitePixel_ = i;
+ }
+}
+
+final void SalColormap::GetPalette()
+{
+ Pixel i;
+
+ pPalette_ = new SalColor[nUsed_];
+
+ XColor *aColor = new XColor[nUsed_];
+
+ for( i = 0; i < nUsed_; i++ )
+ {
+ aColor[i].red = aColor[i].green = aColor[i].blue = 0;
+ aColor[i].pixel = i;
+ }
+
+ XQueryColors( pDisplay_->GetDisplay(), hColormap_, aColor, nUsed_ );
+
+ for( i = 0; i < nUsed_; i++ )
+ {
+ pPalette_[i] = MAKE_SALCOLOR( aColor[i].red >> 8,
+ aColor[i].green >> 8,
+ aColor[i].blue >> 8 );
+ }
+
+ delete aColor;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final static USHORT sal_Lookup( SalColor *pPalette,
+ int r, int g, int b,
+ Pixel nUsed )
+{
+ USHORT nPixel = 0;
+ int nBest = ColorDiff( pPalette[0], r, g, b );
+
+ for( USHORT i = 1; i < nUsed; i++ )
+ {
+ int n = ColorDiff( pPalette[i], r, g, b );
+
+ if( n < nBest )
+ {
+ if( !n )
+ return i;
+
+ nPixel = i;
+ nBest = n;
+ }
+ }
+ return nPixel;
+}
+
+final void SalColormap::GetLookupTable()
+{
+ USHORT *p = pLookupTable_ = new USHORT[16*16*16];
+
+ for( int r = 0; r < 256; r += 17 )
+ for( int g = 0; g < 256; g += 17 )
+ for( int b = 0; b < 256; b += 17 )
+ *p++ = sal_Lookup( pPalette_, r, g, b, nUsed_ );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalColor SalColormap::GetColor( Pixel nPixel ) const
+{
+ if( nBlackPixel_ == nPixel ) return SALCOLOR_BLACK;
+ if( nWhitePixel_ == nPixel ) return SALCOLOR_WHITE;
+
+ if( pVisual_ )
+ {
+ if( pVisual_->GetClass() == TrueColor )
+ return pVisual_->GetTCColor( nPixel );
+
+ if( !pPalette_
+ && ( hColormap_ || XSalIsPrinter( GetXDisplay() ) )
+#ifdef PSEUDOCOLOR12
+ && pVisual_->GetDepth() <= 12
+#else
+ && pVisual_->GetDepth() <= 8
+#endif
+ && pVisual_->GetClass() == PseudoColor )
+ ((SalColormap*)this)->GetPalette();
+ }
+
+ if( pPalette_ && nPixel < nUsed_ )
+ return pPalette_[nPixel];
+
+ if( !hColormap_ && !XSalIsPrinter( GetXDisplay() ) )
+ {
+ DBG_ASSERT( 1, "SalColormap::GetColor() !hColormap_\n" );
+ return nPixel;
+ }
+
+ // DirectColor, StaticColor, StaticGray, GrayScale
+ XColor aColor;
+
+ aColor.pixel = nPixel;
+
+ XQueryColor( pDisplay_->GetDisplay(), hColormap_, &aColor );
+
+ return MAKE_SALCOLOR( aColor.red>>8, aColor.green>>8, aColor.blue>>8 );
+}
+
+final inline BOOL SalColormap::GetXPixel( XColor &rColor,
+ int r,
+ int g,
+ int b ) const
+{
+ rColor.red = r * 257;
+ rColor.green = g * 257;
+ rColor.blue = b * 257;
+ return XAllocColor( GetXDisplay(), hColormap_, &rColor );
+}
+
+final BOOL SalColormap::GetXPixels( XColor &rColor,
+ int r,
+ int g,
+ int b ) const
+{
+ if( !GetXPixel( rColor, r, g, b ) )
+ return FALSE;
+ if( rColor.pixel & 1 )
+ return TRUE;
+ return GetXPixel( rColor, r^0xFF, g^0xFF, b^0xFF );
+}
+
+final Pixel SalColormap::GetPixel( SalColor nSalColor ) const
+{
+ if( 0xFFFFFFFF == nSalColor ) return 0;
+ if( SALCOLOR_BLACK == nSalColor ) return nBlackPixel_;
+ if( SALCOLOR_WHITE == nSalColor ) return nWhitePixel_;
+
+ if( pVisual_ && pVisual_->GetClass() == TrueColor )
+ return pVisual_->GetTCPixel( nSalColor );
+
+ if( !pLookupTable_ )
+ {
+ if( !pPalette_
+ && ( hColormap_ || XSalIsPrinter( GetXDisplay() ) )
+ && pVisual_
+#ifdef PSEUDOCOLOR12
+ && pVisual_->GetDepth() <= 12
+#else
+ && pVisual_->GetDepth() <= 8
+#endif
+ && pVisual_->GetClass() == PseudoColor ) // what else ???
+ ((SalColormap*)this)->GetPalette();
+
+ if( pPalette_ )
+ for( Pixel i = 0; i < nUsed_; i++ )
+ if( pPalette_[i] == nSalColor )
+ return i;
+
+ if( hColormap_ || XSalIsPrinter( GetXDisplay() ) )
+ {
+ // DirectColor, StaticColor, StaticGray, GrayScale (PseudoColor)
+ XColor aColor;
+
+ if( GetXPixel( aColor,
+ SALCOLOR_RED ( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE ( nSalColor ) ) )
+ {
+ if( pPalette_ && !pPalette_[aColor.pixel] )
+ {
+ pPalette_[aColor.pixel] = nSalColor;
+
+ if( !(aColor.pixel & 1) && !pPalette_[aColor.pixel+1] )
+ {
+ XColor aInversColor;
+
+ SalColor nInversColor = nSalColor ^ 0xFFFFFF;
+
+ GetXPixel( aInversColor,
+ SALCOLOR_RED ( nInversColor ),
+ SALCOLOR_GREEN( nInversColor ),
+ SALCOLOR_BLUE ( nInversColor ) );
+
+ if( !pPalette_[aInversColor.pixel] )
+ pPalette_[aInversColor.pixel] = nInversColor;
+#ifdef DBG_UTIL
+ else
+ fprintf( stderr, "SalColormap::GetPixel() 0x06lx=%d 0x06lx=%d\n",
+ nSalColor, aColor.pixel,
+ nInversColor, aInversColor.pixel);
+#endif
+ }
+ }
+
+ return aColor.pixel;
+ }
+
+#ifdef DBG_UTIL
+ fprintf( stderr, "SalColormap::GetPixel() !XAllocColor %lx\n",
+ nSalColor );
+#endif
+ }
+
+ if( !pPalette_ )
+ {
+ fprintf( stderr, "SalColormap::GetPixel() !pPalette_ %lx\n",
+ nSalColor);
+ return nSalColor;
+ }
+
+ ((SalColormap*)this)->GetLookupTable();
+ }
+
+ // Colormatching ueber Palette
+ USHORT r = SALCOLOR_RED ( nSalColor );
+ USHORT g = SALCOLOR_GREEN( nSalColor );
+ USHORT b = SALCOLOR_BLUE ( nSalColor );
+ return pLookupTable_[ (((r+8)/17) << 8)
+ + (((g+8)/17) << 4)
+ + ((b+8)/17) ];
+}
+
diff --git a/vcl/unx/source/app/salinst.cxx b/vcl/unx/source/app/salinst.cxx
new file mode 100644
index 000000000000..374ab09a94df
--- /dev/null
+++ b/vcl/unx/source/app/salinst.cxx
@@ -0,0 +1,346 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALINST_CXX
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <salunx.h>
+
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALWTYPE_HXX
+#include <salwtype.hxx>
+#endif
+#ifndef _SV_SALATYPE_HXX
+#include <salatype.hxx>
+#endif
+#ifndef _SV_DTINT_HXX
+#include <dtint.hxx>
+#endif
+#ifndef _SV_SALPRN_H
+#include <salprn.h>
+#endif
+#ifndef _VCL_SALCONFIG_HXX
+#include <salconfig.hxx>
+#endif
+
+// -=-= C++ globals =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+void SalAbort( const XubString& rErrorText )
+{
+ if( !rErrorText.Len() )
+ fprintf( stderr, "Application Error" );
+ else
+ fprintf( stderr, ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() );
+ abort();
+}
+
+
+// -------------------------------------------------------------------------
+//
+// SalYieldMutex
+//
+// -------------------------------------------------------------------------
+
+SalYieldMutex::SalYieldMutex()
+{
+ mnCount = 0;
+ mnThreadId = 0;
+}
+
+void SalYieldMutex::acquire()
+{
+ OMutex::acquire();
+ mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier();
+ mnCount++;
+}
+
+void SalYieldMutex::release()
+{
+ if ( mnThreadId == NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
+ {
+ if ( mnCount == 1 )
+ mnThreadId = 0;
+ mnCount--;
+ }
+ OMutex::release();
+}
+
+sal_Bool SalYieldMutex::tryToAcquire()
+{
+ if ( OMutex::tryToAcquire() )
+ {
+ mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier();
+ mnCount++;
+ return True;
+ }
+ else
+ return False;
+}
+
+//----------------------------------------------------------------------------
+
+final void InitSalData()
+{
+ SalData *pSalData = new SalData;
+ SetSalData( pSalData );
+}
+
+final void DeInitSalData()
+{
+ SalData *pSalData = GetSalData();
+ delete pSalData;
+ SetSalData( NULL );
+}
+
+final void SetFilterCallback( void* pCallback, void* pInst )
+{
+ SalData* pSalData = GetSalData();
+
+ pSalData->pFirstInstance_->maInstData.mpFilterCallback = pCallback;
+ pSalData->pFirstInstance_->maInstData.mpFilterInst = pInst;
+}
+
+final SalInstance *CreateSalInstance()
+{
+ SalData *pSalData = GetSalData();
+ SalInstance *pInst = new SalInstance;
+
+ // init instance (only one instance in this version !!!)
+ pSalData->pFirstInstance_ = pInst;
+
+ StartPrinterListening();
+
+ return pInst;
+}
+
+final void DestroySalInstance( SalInstance *pInst )
+{
+ SalData *pSalData = GetSalData();
+
+ // reset instance (only one instance in this version !!!)
+ if( pSalData->pFirstInstance_ == pInst )
+ {
+ StopPrinterListening();
+ pSalData->pFirstInstance_ = NULL;
+ ::vcl_sal::XpDefaults::release();
+ }
+
+ delete pInst;
+}
+
+// -=-= SalInstance =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalInstance::SalInstance()
+{
+ maInstData.mpFilterCallback = NULL;
+ maInstData.mpFilterInst = NULL;
+ maInstData.mpSalYieldMutex = new SalYieldMutex;
+ maInstData.mpSalYieldMutex->acquire();
+}
+
+final SalInstance::~SalInstance()
+{
+// #75711# - java is running
+ maInstData.mpSalYieldMutex->release();
+ delete maInstData.mpSalYieldMutex;
+}
+
+
+// --------------------------------------------------------
+// AnyInput from sv/mow/source/app/svapp.cxx
+
+struct PredicateReturn
+{
+ USHORT nType;
+ BOOL bRet;
+};
+
+Bool ImplPredicateEvent( Display *, XEvent *pEvent, char *pData )
+{
+ PredicateReturn *pPre = (PredicateReturn *)pData;
+
+ if ( pPre->bRet )
+ return False;
+
+ USHORT nType;
+
+ switch( pEvent->type )
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case EnterNotify:
+ case LeaveNotify:
+ nType = INPUT_MOUSE;
+ break;
+
+ case XLIB_KeyPress:
+ //case KeyRelease:
+ nType = INPUT_KEYBOARD;
+ break;
+ case Expose:
+ case GraphicsExpose:
+ case NoExpose:
+ nType = INPUT_PAINT;
+ break;
+ default:
+ nType = 0;
+ }
+
+ if ( nType & pPre->nType || ( ! nType && pPre->nType & INPUT_OTHER ) )
+ pPre->bRet = TRUE;
+
+ return False;
+}
+
+
+alpha BOOL SalInstance::AnyInput(USHORT nType)
+{
+ SalData *pSalData = GetSalData();
+ Display *pDisplay = pSalData->GetDefDisp()->GetDisplay();
+
+ // XtInputMask nMask = XtAppPending( SVData().GetAppContext() );
+ // if( nMask )
+ if (XPending(pDisplay) )
+ {
+ // if ( INPUT_TIMER & nType && XtIMTimer & nMask )
+ // return TRUE;
+ // else
+ {
+ PredicateReturn aInput;
+ XEvent aEvent;
+
+ aInput.bRet = FALSE;
+ aInput.nType = nType;
+
+ XCheckIfEvent(pDisplay, &aEvent, ImplPredicateEvent,
+ (char *)&aInput );
+
+ return aInput.bRet;
+ }
+ }
+ return FALSE ;
+}
+
+#ifdef _VOS_NO_NAMESPACE
+IMutex* SalInstance::GetYieldMutex()
+#else
+vos::IMutex* SalInstance::GetYieldMutex()
+#endif
+{
+ return maInstData.mpSalYieldMutex;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInstance::ReleaseYieldMutex()
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->GetThreadId() ==
+ NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
+ {
+ ULONG nCount = pYieldMutex->GetAcquireCount();
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+
+ return nCount;
+ }
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::AcquireYieldMutex( ULONG nCount )
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ while ( nCount )
+ {
+ pYieldMutex->acquire();
+ nCount--;
+ }
+}
+
+final void SalInstance::Yield( BOOL bWait )
+{ GetSalData()->GetLib()->Yield( bWait ); }
+
diff --git a/vcl/unx/source/app/salsys.cxx b/vcl/unx/source/app/salsys.cxx
new file mode 100644
index 000000000000..47f855ce365a
--- /dev/null
+++ b/vcl/unx/source/app/salsys.cxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * $RCSfile: salsys.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALSYS_CXX
+
+#include <cstdio>
+#include <string>
+
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+#ifndef _SV_DTINT_HXX
+#include <dtint.hxx>
+#endif
+#include <salframe.hxx>
+
+#include <strhelper.hxx>
+#include <stacktrace.hxx>
+
+
+void SalSystemData::CreateDtIntegrator( SalFrame* pNewFrame )
+{
+ if( pNewFrame )
+ {
+ if( m_pDtIntegrator && m_pDtIntegrator->GetDisplay() !=
+ pNewFrame->maFrameData.GetDisplay()->GetDisplay() )
+ {
+ m_pDtIntegrator->Release();
+ m_pDtIntegrator = 0;
+ }
+ if( ! m_pDtIntegrator )
+ {
+ m_pDtIntegrator = DtIntegrator::CreateDtIntegrator( pNewFrame );
+ m_pDtIntegrator->Acquire();
+ }
+ }
+}
+
+void SalSystemData::SetSalDisplay( SalDisplay *pSalDisplay )
+{
+ m_pSalDisplay = pSalDisplay;
+}
+
+SalSystemData::~SalSystemData()
+{
+ if( m_pDtIntegrator )
+ m_pDtIntegrator->Release();
+}
+
+
+// -----------------------------------------------------------------------
+
+SalSystem* SalInstance::CreateSystem()
+{
+ return new SalSystem();
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroySystem( SalSystem* pSystem )
+{
+ delete pSystem;
+}
+
+// =======================================================================
+
+SalSystem::SalSystem()
+{
+ maSystemData.m_pSalDisplay = 0;
+ maSystemData.m_pDtIntegrator = 0;
+}
+
+// -----------------------------------------------------------------------
+
+SalSystem::~SalSystem()
+{
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalSystem::StartProcess( SalFrame* pFrame, const String& rFileName,
+ const String& rParam,
+ const String& rWorkingDirectory )
+{
+ maSystemData.CreateDtIntegrator( pFrame );
+
+ XubString aFileName( '\"' );
+ aFileName += rFileName;
+ aFileName += '\"';
+
+ // StartProcess is desktop specific
+ return maSystemData.m_pDtIntegrator->
+ StartProcess( aFileName,
+ const_cast<XubString&>(rParam),
+ const_cast<XubString&>(rWorkingDirectory) );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalSystem::AddRecentDoc( SalFrame* pFrame, const XubString& rFileName )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+String SalSystem::GetSummarySystemInfos( ULONG nFlags )
+{
+ sal_PostMortem aPostMortem;
+
+ /*
+ * unimplemented flags:
+ * SALSYSTEM_GETSYSTEMINFO_MODULES
+ * SALSYSTEM_GETSYSTEMINFO_MOUSEINFO
+ * SALSYSTEM_GETSYSTEMINFO_SYSTEMDIRS
+ * SALSYSTEM_GETSYSTEMINFO_LOCALVOLUMES
+ */
+
+ ByteString aRet;
+ if( nFlags & SALSYSTEM_GETSYSTEMINFO_SYSTEMVERSION )
+ aRet += aPostMortem.getSystemInfo();
+ if( nFlags & SALSYSTEM_GETSYSTEMINFO_CPUTYPE )
+ aRet += aPostMortem.getProcessorInfo();
+ if( nFlags & SALSYSTEM_GETSYSTEMINFO_MEMORYINFO )
+ aRet += aPostMortem.getMemoryInfo();
+ if( nFlags & SALSYSTEM_GETSYSTEMINFO_STACK )
+ aRet += aPostMortem.getStackTrace();
+ if( nFlags & SALSYSTEM_GETSYSTEMINFO_GRAPHICSSYSTEM )
+ aRet += aPostMortem.getGraphicsSystem();
+
+#ifdef DEBUG
+ fprintf( stderr, "SalSystem::GetSummarySystemInfos() =\n%s", aRet.GetBuffer() );
+#endif
+ return String( aRet, RTL_TEXTENCODING_ISO_8859_1 );
+}
+
diff --git a/vcl/unx/source/app/saltimer.cxx b/vcl/unx/source/app/saltimer.cxx
new file mode 100644
index 000000000000..754d0509de66
--- /dev/null
+++ b/vcl/unx/source/app/saltimer.cxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * $RCSfile: saltimer.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALTIMER_CXX
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <salunx.h>
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+
+// -=-= SalData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalData::Timeout() const
+{
+ if( pTimerProc_ )
+ pTimerProc_();
+}
+
+// -=-= SalXLib =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final inline void SalXLib::StopTimer()
+{
+ Timeout_.tv_sec = 0;
+ Timeout_.tv_usec = 0;
+ nTimeoutMS_ = 0;
+}
+
+final inline void SalXLib::StartTimer( ULONG nMS )
+{
+ gettimeofday( &Timeout_, NULL );
+
+ nTimeoutMS_ = nMS;
+ Timeout_.tv_sec += nTimeoutMS_ / 1000;
+ Timeout_.tv_usec += nTimeoutMS_ ? (nTimeoutMS_ % 1000) * 1000 : 500;
+ if( Timeout_.tv_usec > 1000000 )
+ {
+ Timeout_.tv_sec++;
+ Timeout_.tv_usec -= 1000000;
+ }
+}
+
+// -=-= SalTimer -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/* static */ final void SalTimer::SetCallback( SALTIMERPROC pProc )
+{ GetSalData()->SetCallback( pProc ); }
+
+
+/* static */ final void SalTimer::Stop()
+{
+ GetSalData()->GetLib()->StopTimer();
+}
+
+/* static */ final void SalTimer::Start( ULONG nMS )
+{
+ GetSalData()->GetLib()->StartTimer( nMS );
+}
+
diff --git a/vcl/unx/source/app/sm.cxx b/vcl/unx/source/app/sm.cxx
new file mode 100644
index 000000000000..b6552ac490bc
--- /dev/null
+++ b/vcl/unx/source/app/sm.cxx
@@ -0,0 +1,347 @@
+/*************************************************************************
+ *
+ * $RCSfile: sm.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <unistd.h>
+#include <stdio.h>
+
+#include <vos/process.hxx>
+#include <vos/security.hxx>
+
+#ifndef _VCL_SM_HXX
+#include <sm.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_CONFIG_HXX
+#include <config.hxx>
+#endif
+
+//#define USE_SM_EXTENSION
+
+BOOL ICEConnectionObserver::bIsWatching = FALSE;
+SmcConn SessionManagerClient::aSmcConnection = NULL;
+char* SessionManagerClient::pClientID = NULL;
+
+static SmProp* pSmProps = NULL;
+static SmProp** ppSmProps = NULL;
+static int nSmProps = 0;
+
+static void BuildSmPropertyList()
+{
+ if( ! pSmProps )
+ {
+ ByteString aExec( SessionManagerClient::getExecName(), gsl_getSystemTextEncoding() );
+
+ nSmProps = 4;
+ pSmProps = new SmProp[ nSmProps ];
+
+ pSmProps[ 0 ].name = "SmCloneCommand";
+ pSmProps[ 0 ].type = "SmLISTofARRAY8";
+ pSmProps[ 0 ].num_vals = 1;
+ pSmProps[ 0 ].vals = new SmPropValue;
+ pSmProps[ 0 ].vals->length = aExec.Len();
+ pSmProps[ 0 ].vals->value = strdup( aExec.GetBuffer() );
+
+ pSmProps[ 1 ].name = "SmProgram";
+ pSmProps[ 1 ].type = "SmARRAY8";
+ pSmProps[ 1 ].num_vals = 1;
+ pSmProps[ 1 ].vals = new SmPropValue;
+ pSmProps[ 1 ].vals->length = aExec.Len();
+ pSmProps[ 1 ].vals->value = strdup( aExec.GetBuffer() );
+
+ pSmProps[ 2 ].name = "SmRestartCommand";
+ pSmProps[ 2 ].type = "SmLISTofARRAY8";
+ pSmProps[ 2 ].num_vals = 1;
+ pSmProps[ 2 ].vals = new SmPropValue;
+ pSmProps[ 2 ].vals->length = aExec.Len();
+ pSmProps[ 2 ].vals->value = strdup( aExec.GetBuffer() );
+
+ NAMESPACE_VOS(OSecurity) aSecurity;
+ ::rtl::OUString aUserName;
+ aSecurity.getUserName( aUserName );
+ ::rtl::OString aUser( ::rtl::OUStringToOString( aUserName, gsl_getSystemTextEncoding() ) );
+
+ pSmProps[ 3 ].name = "SmUserID";
+ pSmProps[ 3 ].type = "SmARRAY8";
+ pSmProps[ 3 ].num_vals = 1;
+ pSmProps[ 3 ].vals = new SmPropValue;
+ pSmProps[ 3 ].vals->value = strdup( aUser.getStr() );
+ pSmProps[ 3 ].vals->length = strlen( (char *)pSmProps[ 3 ].vals->value );
+
+ ppSmProps = new SmProp*[ nSmProps ];
+ for( int i = 0; i < nSmProps; i++ )
+ ppSmProps[ i ] = &pSmProps[i];
+ }
+}
+
+
+void SessionManagerClient::SaveYourselfProc(
+ SmcConn connection,
+ SmPointer client_data,
+ int save_type,
+ Bool shutdown,
+ int interact_style,
+ Bool fast
+ )
+{
+ BuildSmPropertyList();
+#ifdef USE_SM_EXTENSION
+ SmcSetProperties( aSmcConnection, nSmProps, ppSmProps );
+ SmcSaveYourselfDone( aSmcConnection, True );
+#endif
+}
+
+void SessionManagerClient::DieProc(
+ SmcConn connection,
+ SmPointer client_data
+ )
+{
+#ifdef USE_SM_EXTENSION
+ SmcCloseConnection( connection, 0, NULL );
+#endif
+ if( connection == aSmcConnection )
+ aSmcConnection = NULL;
+}
+
+void SessionManagerClient::SaveCompleteProc(
+ SmcConn connection,
+ SmPointer client_data
+ )
+{
+}
+
+void SessionManagerClient::ShutdownCanceledProc(
+ SmcConn connection,
+ SmPointer client_data )
+{
+}
+
+void SessionManagerClient::open()
+{
+ static SmcCallbacks aCallbacks;
+
+#ifdef USE_SM_EXTENSION
+ // erst scharf schalten wenn getestet
+
+ // this is the way Xt does it, so we can too
+ if( ! aSmcConnection && getenv( "SESSION_MANAGER" ) )
+ {
+ char aErrBuf[1024];
+ String aFilename( getenv( "HOME" ) );
+ aFilename += "/.so_lastSessionID";
+
+ ICEConnectionObserver::activate();
+
+ aCallbacks.save_yourself.callback = SaveYourselfProc;
+ aCallbacks.save_yourself.client_data = NULL;
+ aCallbacks.die.callback = DieProc;
+ aCallbacks.die.client_data = NULL;
+ aCallbacks.save_complete.callback = SaveCompleteProc;
+ aCallbacks.save_complete.client_data = NULL;
+ aCallbacks.shutdown_cancelled.callback = ShutdownCanceledProc;
+ aCallbacks.shutdown_cancelled.client_data = NULL;
+ aSmcConnection = SmcOpenConnection( NULL,
+ NULL,
+ SmProtoMajor,
+ SmProtoMinor,
+ SmcSaveYourselfProcMask |
+ SmcDieProcMask |
+ SmcSaveCompleteProcMask |
+ SmcShutdownCancelledProcMask ,
+ &aCallbacks,
+ getPreviousSessionID(),
+ &pClientID,
+ sizeof( aErrBuf ),
+ aErrBuf );
+#if defined DEBUG || defined DBG_UTIL
+ if( ! aSmcConnection )
+ fprintf( stderr, "SmcOpenConnection failed: %s\n", aErrBuf );
+#endif
+ setPreviousSessionID( pClientID );
+ }
+#endif
+}
+
+void SessionManagerClient::close()
+{
+ if( aSmcConnection )
+ {
+#ifdef USE_SM_EXTENSION
+ SmcCloseConnection( aSmcConnection, 0, NULL );
+#endif
+ aSmcConnection = NULL;
+ ICEConnectionObserver::deactivate();
+ }
+}
+
+
+String SessionManagerClient::getExecName()
+{
+ static NAMESPACE_VOS( OStartupInfo ) aStartupInfo;
+
+ ::rtl::OUString aExec;
+ aStartupInfo.getExecutableFile( aExec );
+
+ int nPos = aExec.search( ::rtl::OUString::createFromAscii( ".bin" ) );
+ if( nPos != -1 )
+ aExec = aExec.copy( 0, nPos );
+ return aExec;
+}
+
+
+char* SessionManagerClient::getPreviousSessionID()
+{
+ static char aID[1024];
+
+ String aFilename( getenv( "HOME" ), gsl_getSystemTextEncoding() );
+ aFilename.AppendAscii( "/.sosessions" );
+
+ ByteString aExec( getExecName(), gsl_getSystemTextEncoding() );
+ aExec = aExec.GetToken( aExec.GetTokenCount( '/' )-1, '/' );
+
+ Config aConfig( aFilename );
+ aConfig.SetGroup( "Sessions" );
+ ByteString aSessionID = aConfig.ReadKey( aExec );
+ if( aSessionID.Len() )
+ {
+ strncpy( aID, aSessionID.GetBuffer(), sizeof( aID ) );
+ return aID;
+ }
+ return NULL;
+}
+
+void SessionManagerClient::setPreviousSessionID( const ByteString& rID )
+{
+ static char aID[1024];
+
+ String aFilename( getenv( "HOME" ), gsl_getSystemTextEncoding() );
+ aFilename.AppendAscii( "/.sosessions" );
+
+ ByteString aExec( getExecName(), gsl_getSystemTextEncoding() );
+ aExec = aExec.GetToken( aExec.GetTokenCount( '/' )-1, '/' );
+
+ Config aConfig( aFilename );
+ aConfig.SetGroup( "Sessions" );
+ aConfig.WriteKey( aExec, rID );
+}
+
+void ICEConnectionObserver::activate()
+{
+ if( ! bIsWatching )
+ {
+ bIsWatching = TRUE;
+#ifdef USE_SM_EXTENSION
+ IceAddConnectionWatch( ICEWatchProc, NULL );
+#endif
+ }
+}
+
+void ICEConnectionObserver::deactivate()
+{
+ if( bIsWatching )
+ {
+ bIsWatching = FALSE;
+#ifdef USE_SM_EXTENSION
+ IceRemoveConnectionWatch( ICEWatchProc, NULL );
+#endif
+ }
+}
+
+void ICEConnectionObserver::ICEWatchProc(
+ IceConn connection,
+ IcePointer client_data,
+ Bool opening,
+ IcePointer* watch_data
+ )
+{
+#ifdef USE_SM_EXTENSION
+ if( opening )
+ GetSalData()->GetLib()->Insert( IceConnectionNumber( connection ),
+ connection,
+ (YieldFunc)Pending,
+ (YieldFunc)Queued,
+ (YieldFunc)HandleEvents );
+ else
+ GetSalData()->GetLib()->Remove( IceConnectionNumber( connection ) );
+#endif
+}
+
+int ICEConnectionObserver::Pending( int fd, void* data )
+{
+ return 1;
+}
+
+int ICEConnectionObserver::Queued( int fd, void* data )
+{
+ return 1;
+}
+
+int ICEConnectionObserver::HandleEvents( int fd, void* data )
+{
+#ifdef USE_SM_EXTENSION
+ IceProcessMessages( (IceConn)data, NULL, NULL );
+#endif
+ return 0;
+}
+
diff --git a/vcl/unx/source/app/soicon.cxx b/vcl/unx/source/app/soicon.cxx
new file mode 100644
index 000000000000..caf8c6797156
--- /dev/null
+++ b/vcl/unx/source/app/soicon.cxx
@@ -0,0 +1,502 @@
+/*************************************************************************
+ *
+ * $RCSfile: soicon.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SOICON_CXX
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <salunx.h>
+
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_IMPBMP_HXX
+#include <impbmp.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmap.hxx>
+#endif
+#ifndef _SV_BITMAP_HXX
+#include <bitmapex.hxx>
+#endif
+#ifndef _SV_GRAPH_HXX
+#include <graph.hxx>
+#endif
+#ifndef _SV_CVTGRF_HXX
+#include <cvtgrf.hxx>
+#endif
+#ifndef _SV_STRHELPER_HXX
+#include <strhelper.hxx>
+#endif
+
+#include <tools/stream.hxx>
+#include <tools/string.hxx>
+
+
+#include "so.xpm"
+
+static Pixmap aAppPixmap = 0, aAppMask = 0;
+
+static void ConvertXpm( SalDisplay* pDisplay )
+{
+ int nWidth, nHeight, nColors, nCharsPerPixel;
+ XColor *pColors;
+ char *pColorAlias;
+ int nElement = 0,nColor = 0,i,nX,nY;
+ char pColorName[16], pComName[16],pColorString[256];
+ BOOL bTransparent = FALSE;
+
+ sscanf( xpmdata[ nElement++ ], "%d%d%d%d", &nWidth, &nHeight,
+ &nColors, &nCharsPerPixel );
+#if defined DBG_UTIL || defined DEBUG
+ fprintf( stderr, "ConvertXpm: converting width = %d height = %d ncolors = %d chars_per_pixel = %d\n", nWidth, nHeight, nColors, nCharsPerPixel );
+#endif
+ nColor = 0;
+ pColors = new XColor[ nColors ];
+ pColorAlias = new char[ nColors * nCharsPerPixel ];
+ while( nElement <= nColors )
+ {
+ sscanf( xpmdata[ nElement++ ],"%s %s %s",
+ pColorName, pComName, pColorString);
+ if( strncmp( pColorString, "None", 4 ) )
+ {
+ XAllocNamedColor( pDisplay->GetDisplay(),
+ DefaultColormap( pDisplay->GetDisplay(),
+ pDisplay->GetScreenNumber() ),
+ pColorString, &pColors[nColor], &pColors[nColor] );
+ strncpy( &pColorAlias[nColor*nCharsPerPixel],
+ pColorName, nCharsPerPixel );
+ nColor++;
+ }
+ }
+ nColors = nColor+1;
+
+ aAppPixmap = XCreatePixmap( pDisplay->GetDisplay(),
+ pDisplay->GetRootWindow(),
+ nWidth, nHeight,
+ pDisplay->GetRootVisual()->GetDepth() );
+ XSetForeground( pDisplay->GetDisplay(),
+ DefaultGC( pDisplay->GetDisplay(),
+ pDisplay->GetScreenNumber() ),
+ BlackPixel( pDisplay->GetDisplay(),
+ pDisplay->GetScreenNumber() ) );
+ XFillRectangle( pDisplay->GetDisplay(), aAppPixmap,
+ DefaultGC( pDisplay->GetDisplay(),
+ pDisplay->GetScreenNumber() ),
+ 0,0,nWidth,nHeight );
+
+ aAppMask = XCreatePixmap( pDisplay->GetDisplay(),
+ pDisplay->GetRootWindow(),
+ nWidth, nHeight, 1 );
+
+ XGCValues aValues;
+ aValues.function = GXset;
+ aValues.foreground = 0xffffffff;
+ GC aMonoGC = XCreateGC( pDisplay->GetDisplay(), aAppMask,
+ GCFunction|GCForeground, &aValues );
+
+ XFillRectangle( pDisplay->GetDisplay(), aAppMask, aMonoGC,
+ 0,0, nWidth, nHeight );
+ aValues.function = GXclear;
+ XChangeGC( pDisplay->GetDisplay(), aMonoGC, GCFunction, &aValues );
+
+ for( nY=0; nY < nHeight; nY++ )
+ {
+ char *pRun = xpmdata[ nElement+nY ];
+ for( nX=0; nX < nWidth; nX++ )
+ {
+ // get color number
+ nColor = 0;
+ while( nColor < nColors &&
+ strncmp( pRun, &pColorAlias[nColor*nCharsPerPixel],
+ nCharsPerPixel ) )
+ nColor++;
+ if( nColor < nColors )
+ {
+ XSetForeground( pDisplay->GetDisplay(),
+ DefaultGC( pDisplay->GetDisplay(),
+ pDisplay->GetScreenNumber() ),
+ pColors[ nColor ].pixel );
+ XDrawPoint( pDisplay->GetDisplay(),
+ aAppPixmap,
+ DefaultGC( pDisplay->GetDisplay(),
+ pDisplay->GetScreenNumber() ),
+ nX, nY );
+
+ }
+ else
+ {
+ bTransparent = TRUE;
+ XDrawPoint( pDisplay->GetDisplay(),
+ aAppMask, aMonoGC, nX, nY );
+ }
+ pRun += nCharsPerPixel;
+ }
+ }
+ delete pColors;
+ delete pColorAlias;
+ XFreeGC( pDisplay->GetDisplay(), aMonoGC );
+
+ if( ! bTransparent )
+ {
+#if defined DBG_UTIL || defined DEBUG
+ fprintf( stderr, "ConvertXpm: keine Transparenz -> keine Maske\n" );
+#endif
+ XFreePixmap( pDisplay->GetDisplay(), aAppMask );
+ aAppMask = 0;
+ }
+}
+
+Pixmap GetAppIconPixmap( SalDisplay *pDisplay )
+{
+ if( ! aAppPixmap )
+ ConvertXpm( pDisplay );
+ return aAppPixmap;
+}
+
+Pixmap GetAppIconMask( SalDisplay *pDisplay )
+{
+ if( ! aAppPixmap )
+ ConvertXpm( pDisplay );
+ return aAppMask;
+}
+
+static void NextLine( SvStream& rFile, ByteString& rLine, BOOL bXpm2Mode )
+{
+ if( bXpm2Mode )
+ {
+ rFile.ReadLine( rLine );
+ }
+ else
+ {
+ do
+ {
+ rFile.ReadLine( rLine );
+ rLine = rLine.GetToken( 1, '"' );
+ if( rLine.Len() )
+ rLine = rLine.GetToken( 0, '"' );
+ } while( ! ( rLine.Len() || rFile.IsEof() ) );
+ }
+}
+
+BOOL ReadXBMFile( Display* pDisplay, const String& rFile, SalBitmap*& rpBmp )
+{
+ SvFileStream aFile( rFile, STREAM_READ );
+ int nBytes = 0;
+ int nWidth= -1, nHeight=-1;
+ BOOL bSuccess = FALSE;
+
+ rpBmp = NULL;
+
+ // read in bitmap file ( cause XReadBitmapFileData not present
+ // in Solaris 2.5.1)
+ if( ! aFile.IsOpen() )
+ return FALSE;
+
+ ByteString aLine;
+
+ while( ( nWidth < 0 || nHeight < 0 ) && ! aFile.IsEof() )
+ {
+ aFile.ReadLine( aLine );
+ aLine = WhitespaceToSpace( aLine );
+
+ if( aLine.GetChar(0) == '#' )
+ {
+ if( aLine.Search( "_width" ) != STRING_NOTFOUND )
+ nWidth = aLine.GetToken( ' ', 2 ).ToInt32();
+ else if( aLine.Search( "_height" ) != STRING_NOTFOUND )
+ nHeight = aLine.GetToken( ' ', 2 ).ToInt32();
+ }
+ }
+
+ if( nWidth <= 0 || nHeight <= 0 )
+ return FALSE;
+
+ BitmapPalette aPal( 2 );
+ const Size aSize( nWidth, nHeight );
+
+ aPal[ 0 ] = BitmapColor( 0, 0, 0 );
+ aPal[ 1 ] = BitmapColor( 0xff, 0xff, 0xff );
+
+ rpBmp = new SalBitmap;
+ rpBmp->Create( aSize, 1, aPal );
+
+ BitmapBuffer* pBmpBuf = rpBmp->AcquireBuffer( FALSE );
+ BYTE* pBmpScan = pBmpBuf->mpBits + ( nHeight - 1 ) * pBmpBuf->mnScanlineSize;
+ long nX = 0, nY = 0;
+
+ aFile.Seek( 0L );
+
+ do
+ {
+ int nPos;
+
+ aFile.ReadLine( aLine );
+ aLine.ToUpperAscii();
+
+ while( ( ( nPos = aLine.Search( "0X" ) ) != STRING_NOTFOUND ) && ( nY < nHeight ) )
+ {
+ BYTE cData = 0;
+
+ for( int i = 0; i < 2; i++ )
+ {
+ cData *= 16;
+ char c = aLine.GetChar( nPos + 2 + i);
+
+ if( c >= '0' && c <= '9' )
+ cData += (unsigned char)( c - '0' );
+ else if( c >= 'A' && c <= 'F' )
+ cData += (unsigned char)( c - 'A' + 10 );
+ }
+
+ *pBmpScan++ += ( ( cData & 1 ) << 7 ) | ( ( cData & 2 ) << 5 ) |
+ ( ( cData & 4 ) << 3 ) | ( ( cData & 8 ) << 1 ) |
+ ( ( cData & 16 ) >> 1 ) | ( ( cData & 32 ) >> 3 ) |
+ ( ( cData & 64 ) >> 5 ) | ( ( cData& 128 ) >> 7 );
+
+ if( ( nX += 8 ) >= nWidth )
+ nX = 0, pBmpScan = pBmpBuf->mpBits + ( nHeight - ++nY - 1 ) * pBmpBuf->mnScanlineSize;
+
+ aLine.Erase( 0, nPos + 5 );
+ }
+ }
+ while( !aFile.IsEof() && ( nY < nHeight ) );
+
+ rpBmp->ReleaseBuffer( pBmpBuf, FALSE );
+
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+
+BOOL ReadXPMFile( Display* pDisplay, const String& rFile,
+ SalBitmap*& rpBmp, SalBitmap*& rpMsk )
+{
+ SvFileStream aFile( rFile, STREAM_READ );
+ ByteString aColorName, aColorString, aLine;
+ int nWidth, nHeight, nColors, nCharsPerPixel;
+ int nElement = 0,nColor = 0, i, nX, nY;
+ UINT8* pColorTable;
+ char* pColorAlias;
+ BOOL bTransparent = FALSE;
+ BOOL bXpm2Mode = FALSE;
+
+ rpBmp = rpMsk = NULL;
+
+ if( ! aFile.IsOpen() )
+ return FALSE;
+
+ aFile.ReadLine( aLine );
+ aLine = WhitespaceToSpace( aLine );
+
+ if( aLine.CompareTo( "! XPM", 5 ) == COMPARE_EQUAL )
+ bXpm2Mode = TRUE;
+ else
+ {
+ bXpm2Mode = FALSE;
+ aFile.Seek( 0L );
+ }
+
+ NextLine( aFile, aLine, bXpm2Mode );
+
+ nWidth = GetCommandLineToken( 0, aLine ).ToInt32();
+ nHeight = GetCommandLineToken( 1, aLine ).ToInt32();
+ nColors = GetCommandLineToken( 2, aLine ).ToInt32();
+ nCharsPerPixel = GetCommandLineToken( 3, aLine ).ToInt32();
+
+ if( nWidth == 0 || nHeight == 0 || nColors == 0 || nCharsPerPixel == 0 )
+ {
+ // not really an xpm despite the name => try to load it via GraphicConverter
+ aFile.Seek( 0L );
+ Graphic aGraphic;
+ GraphicConverter::Import( aFile, aGraphic );
+
+ BitmapEx aBitmapEx( aGraphic.GetBitmapEx() );
+
+ if( aBitmapEx.GetSizePixel().Width() == 0 || aBitmapEx.GetSizePixel().Height() == 0 )
+ return FALSE;
+
+ const Bitmap aBmp( aBitmapEx.GetBitmap() );
+ const Bitmap aMsk( aBitmapEx.GetMask() );
+
+ if( !!aBmp )
+ {
+ rpBmp = new SalBitmap;
+ rpBmp->Create( *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap() );
+ }
+
+ if( !!aMsk )
+ {
+ rpMsk = new SalBitmap;
+ rpMsk->Create( *aMsk.ImplGetImpBitmap()->ImplGetSalBitmap() );
+ }
+
+ return TRUE;
+ }
+
+ nColor = 0;
+ pColorTable = new UINT8[ (nColors+1) * 3 ];
+ pColorAlias = new char[ nColors * nCharsPerPixel ];
+ XColor aExactColor;
+ aExactColor.flags = DoRed | DoGreen | DoBlue;
+ while( nColors )
+ {
+ NextLine( aFile, aLine, bXpm2Mode );
+ // might be a space as color variable
+ aColorName = aLine.Copy( 0, nCharsPerPixel );
+ aLine.Erase( 0, nCharsPerPixel );
+ aLine = WhitespaceToSpace( aLine );
+
+ int nPos = aLine.Search( " c " );
+ if( nPos == STRING_NOTFOUND && aLine.CompareIgnoreCaseToAscii( "c ", 2 ) == COMPARE_EQUAL )
+ nPos = 2;
+ else
+ nPos += 3;
+ aColorString = aLine.Copy( nPos );
+
+ if( aColorString.CompareIgnoreCaseToAscii( "none", 4 ) != COMPARE_EQUAL )
+ {
+ XParseColor( pDisplay,
+ DefaultColormap( pDisplay,
+ DefaultScreen( pDisplay ) ),
+ aColorString.GetBuffer(),
+ &aExactColor );
+ pColorTable[ nColor * 3 +2 ] = (UINT8)(aExactColor.red / 256 );
+ pColorTable[ nColor * 3 +1 ] = (UINT8)(aExactColor.green / 256 );
+ pColorTable[ nColor * 3 ] = (UINT8)(aExactColor.blue / 256 );
+ strncpy( pColorAlias + nColor*nCharsPerPixel,
+ aColorName.GetBuffer(), nCharsPerPixel );
+ nColor++;
+ }
+ nColors--;
+ }
+ pColorTable[ 3*nColor ] = pColorTable[ 3*nColor+1 ] =
+ pColorTable[ 3*nColor+2 ] = 0;
+ nColors = nColor;
+
+ // read SalBitmap's
+ BitmapPalette aPal( 2 );
+ const Size aSize( nWidth, nHeight );
+
+ aPal[ 0 ] = BitmapColor( 0, 0, 0 );
+ aPal[ 1 ] = BitmapColor( 0xff, 0xff, 0xff );
+
+ rpBmp = new SalBitmap;
+ rpBmp->Create( aSize, 24, aPal );
+ BitmapBuffer* pBmpBuf = rpBmp->AcquireBuffer( FALSE );
+
+ rpMsk = new SalBitmap;
+ rpMsk->Create( aSize, 1, aPal );
+ BitmapBuffer* pMskBuf = rpMsk->AcquireBuffer( FALSE );
+
+ for( nY=0; nY < nHeight; nY++ )
+ {
+ NextLine( aFile, aLine, bXpm2Mode );
+
+ const char* pRun = aLine.GetBuffer();
+ BYTE* pBmpScan = pBmpBuf->mpBits + pBmpBuf->mnScanlineSize * ( nHeight - nY - 1 );
+ BYTE* pMskScan = pMskBuf->mpBits + pMskBuf->mnScanlineSize * ( nHeight - nY - 1 );
+ UINT8 nMaskByte = 0;
+
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ // get color number
+ for( nColor=0; nColor < nColors; nColor++ )
+ {
+ if( ! strncmp( pRun, pColorAlias + nColor*nCharsPerPixel,
+ nCharsPerPixel ) )
+ break;
+ }
+
+ long nIndex = nColor * 3;
+
+ *pBmpScan++ = pColorTable[ nIndex++ ];
+ *pBmpScan++ = pColorTable[ nIndex++ ];
+ *pBmpScan++ = pColorTable[ nIndex ];
+
+ if( nColor == nColors )
+ nMaskByte |= ( 1 << ( 7 - ( nX & 7 ) ) );
+
+ pRun += nCharsPerPixel;
+
+ if( ( ( nX & 7 ) == 7 ) || ( nX == nWidth - 1 ) )
+ {
+ *pMskScan++ = nMaskByte;
+ nMaskByte = 0;
+ }
+ }
+ }
+
+ rpBmp->ReleaseBuffer( pBmpBuf, FALSE );
+ rpMsk->ReleaseBuffer( pMskBuf, FALSE );
+ delete[] pColorTable;
+ delete[] pColorAlias;
+
+ return TRUE;
+}
diff --git a/vcl/unx/source/gdi/cdeint.cxx b/vcl/unx/source/gdi/cdeint.cxx
new file mode 100644
index 000000000000..8783958b79f4
--- /dev/null
+++ b/vcl/unx/source/gdi/cdeint.cxx
@@ -0,0 +1,572 @@
+/*************************************************************************
+ *
+ * $RCSfile: cdeint.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <salunx.h>
+#include <saldisp.hxx>
+#include <salbmp.hxx>
+#include <salframe.hxx>
+#include <cdeint.hxx>
+#include <soicon.hxx>
+#include <strhelper.hxx>
+#include <tools/debug.hxx>
+
+void* CDEIntegrator::pDtSvcLib = 0;
+void* CDEIntegrator::pXtLib = 0;
+void* CDEIntegrator::pXmLib = 0;
+void* CDEIntegrator::pMrmLib = 0;
+void* CDEIntegrator::pttLib = 0;
+int CDEIntegrator::nRefCount = 0;
+char* CDEIntegrator::pFallbackRes[] = {
+ "title: OfficeCDEIntegrationShell",
+ NULL
+};
+static char *ppDummyArgv[] = { "soffice.bin", NULL };
+static int nDummyArgc = 1;
+
+// function pointers
+// from DtSvc
+XLIB_Boolean (*CDEIntegrator::pDtAppInitialize)
+ ( XtAppContext, Display*, Widget, char*, char* ) = 0;
+void (*CDEIntegrator::pDtDtsLoadDataTypes)() = 0;
+void (*CDEIntegrator::pDtDtsRelease)() = 0;
+char* (*CDEIntegrator::pDtDtsFileToAttributeValue)
+ (const char*,const char*) = 0;
+void (*CDEIntegrator::pDtDtsFreeAttributeValue)( char* ) = 0;
+Status (*CDEIntegrator::pDtWsmGetWorkspaceInfo)( Display*, XLIB_Window, Atom,
+ DtWsmWorkspaceInfo** ) = 0;
+void (*CDEIntegrator::pDtWsmFreeWorkspaceInfo)( DtWsmWorkspaceInfo* ) = 0;
+Status (*CDEIntegrator::pDtWsmGetWorkspaceList)( Display*, XLIB_Window, Atom**,
+ int* ) = 0;
+Status (*CDEIntegrator::pDtWsmGetCurrentWorkspace)( Display*, XLIB_Window root, Atom* ) = 0;
+Status (*CDEIntegrator::pDtWsmGetWorkspacesOccupied)( Display*, XLIB_Window, Atom**, unsigned long* ) = 0;
+
+// from Mrm
+void (*CDEIntegrator::pMrmInitialize)() = 0;
+
+// from Xm
+WidgetClass* CDEIntegrator::pxmDrawingAreaWidgetClass = 0;
+WidgetClass* CDEIntegrator::pxmRowColumnWidgetClass = 0;
+WidgetClass* CDEIntegrator::pxmPushButtonWidgetClass = 0;
+
+// from Xt
+void (*CDEIntegrator::pXtToolkitInitialize)() = 0;
+XtAppContext (*CDEIntegrator::pXtCreateApplicationContext)() = 0;
+Widget (*CDEIntegrator::pXtAppCreateShell)
+ ( char*, char*, WidgetClass, Display*, ArgList, Cardinal ) = 0;
+Widget (*CDEIntegrator::pXtVaCreateManagedWidget)
+ ( char*, WidgetClass, Widget, ... ) = 0;
+void (*CDEIntegrator::pXtDisplayInitialize)
+ ( XtAppContext, Display*, char*, char*, XrmOptionDescRec*, Cardinal,
+ int*, char**) = 0;
+void (*CDEIntegrator::pXtAppSetFallbackResources)
+ ( XtAppContext, char** ) = 0;
+Widget (*CDEIntegrator::pXtAppInitialize)
+ (XtAppContext*, char*, XrmOptionDescList, Cardinal, int*, char**, char**,
+ ArgList, Cardinal ) = 0;
+Widget (*CDEIntegrator::pXtSetLanguageProc)
+ ( XtAppContext, XtLanguageProc, XtPointer ) = 0;
+DtActionInvocationID (*CDEIntegrator::pDtActionInvoke)
+ ( Widget, char*, DtActionArg*, int, char*, char*, char*, int,
+ DtActionCallbackProc, XtPointer ) = 0;
+void (*CDEIntegrator::pXtRealizeWidget)( Widget ) = 0;
+void (*CDEIntegrator::pXtUnrealizeWidget)( Widget ) = 0;
+XLIB_Boolean (*CDEIntegrator::pXtIsRealized)( Widget ) = 0;
+void (*CDEIntegrator::pXtConfigureWidget)
+ ( Widget, Position, Position, Dimension, Dimension, Dimension ) = 0;
+void (*CDEIntegrator::pXtAppProcessEvent)
+ ( XtAppContext, XtInputMask ) = 0;
+XtInputMask (*CDEIntegrator::pXtAppPending)( XtAppContext ) = 0;
+WidgetClass* CDEIntegrator::pAppShellClass = 0;
+
+
+CDEIntegrator::CDEIntegrator( SalFrame* pFrame ) :
+ DtIntegrator( pFrame ),
+ maAppWidget( 0 )
+{
+ meType = DtCDE;
+ if( ! nRefCount )
+ GlobalInit();
+ nRefCount++;
+
+ // instanz daten initialisieren
+ maAppContext = pXtCreateApplicationContext();
+ pXtDisplayInitialize( maAppContext, mpDisplay,
+ "OfficeCDEIntegrationShell",
+ "OfficeCDEIntegrationShell",
+ 0, 0, &nDummyArgc, ppDummyArgv );
+ pXtAppSetFallbackResources( maAppContext, pFallbackRes );
+ maAppWidget = pXtAppCreateShell( "OfficeCDEIntegrationShell",
+ "OfficeCDEIntegrationShell",
+ *pAppShellClass,
+ mpDisplay, 0, 0 );
+ pXtConfigureWidget( maAppWidget, 10, 10, 10, 10, 0 );
+ //pXtRealizeWidget( maAppWidget );
+ pDtAppInitialize( maAppContext, mpDisplay, maAppWidget,
+ ppDummyArgv[ 0 ], "Office" );
+
+ pDtDtsLoadDataTypes();
+}
+
+CDEIntegrator::~CDEIntegrator()
+{
+ if( maAppWidget )
+ pXtUnrealizeWidget( maAppWidget );
+
+ nRefCount--;
+ if( ! nRefCount )
+ GlobalDeInit();
+}
+
+void CDEIntegrator::GlobalInit()
+{
+ if( ! pDtSvcLib )
+ pDtSvcLib = _LoadLibrary( "libDtSvc.so" );
+ if( ! pttLib )
+ pttLib = _LoadLibrary( "libtt.so" );
+ if( ! pXmLib )
+ pXmLib = _LoadLibrary( "libXm.so" );
+ if( ! pMrmLib )
+ pMrmLib = _LoadLibrary( "libMrm.so" );
+ if( ! pXtLib )
+ pXtLib = _LoadLibrary( "libXt.so" );
+
+ if( pDtSvcLib && pXtLib && pttLib && pXmLib && pMrmLib )
+ {
+ bSymbolLoadFailed = FALSE;
+
+ pDtAppInitialize = (XLIB_Boolean (*)( XtAppContext, Display*,
+ Widget, char*, char* ))
+ _LoadSymbol( pDtSvcLib, "DtAppInitialize" );
+ pDtDtsLoadDataTypes = (void (*)())
+ _LoadSymbol( pDtSvcLib, "DtDtsLoadDataTypes" );
+ pDtDtsRelease = (void (*)())
+ _LoadSymbol( pDtSvcLib, "DtDtsRelease" );
+ pDtDtsFileToAttributeValue = (char* (*)(const char*,const char*))
+ _LoadSymbol( pDtSvcLib, "DtDtsFileToAttributeValue" );
+ pDtDtsFreeAttributeValue = (void (*)( char* ))
+ _LoadSymbol( pDtSvcLib, "DtDtsFreeAttributeValue" );
+ pDtActionInvoke = (DtActionInvocationID(*)
+ ( Widget, char*,DtActionArg*, int, char*,
+ char*, char*, int,
+ DtActionCallbackProc, XtPointer ))
+ _LoadSymbol( pDtSvcLib, "DtActionInvoke" );
+ pDtWsmGetWorkspaceInfo = (Status(*)( Display*, XLIB_Window, Atom,
+ DtWsmWorkspaceInfo** ))
+ _LoadSymbol( pDtSvcLib, "DtWsmGetWorkspaceInfo" );
+ pDtWsmFreeWorkspaceInfo = (void(*)( DtWsmWorkspaceInfo* ))
+ _LoadSymbol( pDtSvcLib, "DtWsmFreeWorkspaceInfo" );
+ pDtWsmGetWorkspaceList = (Status(*)( Display*, XLIB_Window, Atom**, int* ))
+ _LoadSymbol( pDtSvcLib, "DtWsmGetWorkspaceList" );
+ pDtWsmGetCurrentWorkspace = (Status(*)( Display*, XLIB_Window, Atom*))
+ _LoadSymbol( pDtSvcLib, "DtWsmGetCurrentWorkspace" );
+ pDtWsmGetWorkspacesOccupied = (Status(*)( Display*, XLIB_Window, Atom**, unsigned long* ))
+ _LoadSymbol( pDtSvcLib, "DtWsmGetWorkspacesOccupied" );
+
+ pXtToolkitInitialize = (void (*)())
+ _LoadSymbol( pXtLib, "XtToolkitInitialize" );
+ pXtCreateApplicationContext = (XtAppContext (*)())
+ _LoadSymbol( pXtLib, "XtCreateApplicationContext" );
+ pXtAppCreateShell = (Widget (*)( char*, char*, WidgetClass,
+ Display*, ArgList,
+ Cardinal ))
+ _LoadSymbol( pXtLib, "XtAppCreateShell" );
+ pXtDisplayInitialize = (void (*)( XtAppContext, Display*, char*,
+ char*, XrmOptionDescRec*, Cardinal,
+ int*, char**) )
+ _LoadSymbol( pXtLib, "XtDisplayInitialize" );
+
+ pXtVaCreateManagedWidget = (Widget (*)( char*, WidgetClass, Widget, ... ))
+ _LoadSymbol( pXtLib, "XtVaCreateManagedWidget" );
+ pXtSetLanguageProc = (Widget (*)( XtAppContext, XtLanguageProc, XtPointer ))
+ _LoadSymbol( pXtLib, "XtSetLanguageProc" );
+ pXtAppSetFallbackResources = (void (*)( XtAppContext, char** ))
+ _LoadSymbol( pXtLib, "XtAppSetFallbackResources" );
+ pXtAppInitialize = (Widget (*)(XtAppContext*, char*, XrmOptionDescList,
+ Cardinal, int*, char**, char**, ArgList,
+ Cardinal ))
+ _LoadSymbol( pXtLib, "XtAppInitialize" );
+ pXtRealizeWidget = (void(*)( Widget ))
+ _LoadSymbol( pXtLib, "XtRealizeWidget" );
+ pXtIsRealized = (XLIB_Boolean(*)( Widget ))
+ _LoadSymbol( pXtLib, "XtIsRealized" );
+ pXtUnrealizeWidget = (void(*)( Widget ))
+ _LoadSymbol( pXtLib, "XtUnrealizeWidget" );
+ pXtAppProcessEvent = (void(*)( XtAppContext, XtInputMask ))
+ _LoadSymbol( pXtLib, "XtAppProcessEvent" );
+ pXtAppPending = (XtInputMask(*)( XtAppContext ))
+ _LoadSymbol( pXtLib, "XtAppPending" );
+ pXtConfigureWidget = (void (*)( Widget, Position, Position, Dimension,
+ Dimension, Dimension ))
+ _LoadSymbol( pXtLib, "XtConfigureWidget" );
+ pAppShellClass =
+ (WidgetClass*)_LoadSymbol( pXtLib, "applicationShellWidgetClass" );
+ pMrmInitialize = (void(*)())
+ _LoadSymbol( pMrmLib, "MrmInitialize" );
+ pxmDrawingAreaWidgetClass =
+ (WidgetClass*)_LoadSymbol( pXmLib, "xmDrawingAreaWidgetClass" );
+ pxmRowColumnWidgetClass =
+ (WidgetClass*)_LoadSymbol( pXmLib, "xmRowColumnWidgetClass" );
+ pxmPushButtonWidgetClass =
+ (WidgetClass*)_LoadSymbol( pXmLib, "xmPushButtonWidgetClass" );
+
+ pXtSetLanguageProc( NULL, NULL, NULL );
+ pMrmInitialize();
+ pXtToolkitInitialize();
+ XrmInitialize();
+ }
+ else
+ {
+ if( pXtLib )
+ dlclose( pXtLib );
+ if( pXmLib )
+ dlclose( pXmLib );
+ if( pMrmLib )
+ dlclose( pMrmLib );
+ if( pttLib )
+ dlclose( pttLib );
+ if( pDtSvcLib )
+ dlclose( pDtSvcLib );
+ pttLib = pMrmLib = pXmLib = pXtLib = pDtSvcLib = 0;
+ }
+}
+
+void CDEIntegrator::GlobalDeInit()
+{
+ pDtDtsRelease();
+
+ if( pXtLib )
+ dlclose( pXtLib );
+ if( pXmLib )
+ dlclose( pXmLib );
+ if( pMrmLib )
+ dlclose( pMrmLib );
+ if( pttLib )
+ dlclose( pttLib );
+ if( pDtSvcLib )
+ dlclose( pDtSvcLib );
+ pttLib = pMrmLib = pXmLib = pXtLib = pDtSvcLib = 0;
+}
+
+void CDEIntegrator::InvokeAction( const String& rAction, const String& rFiles )
+{
+#if 1
+ String aActionLine( RTL_CONSTASCII_STRINGPARAM( "/usr/dt/bin/dtaction " ), RTL_TEXTENCODING_ASCII_US );
+ aActionLine += rAction;
+ aActionLine += ' ';
+ aActionLine += rFiles;
+ DtIntegrator::LaunchProcess( aActionLine );
+#else
+ int nTokens = GetCommandLineTokenCount( rFiles ), i;
+ DtActionArg* pArgs = new DtActionArg[ nTokens ];
+ char** pStrings = new char*[nTokens];
+ for( i = 0; i < nTokens ; i++ )
+ {
+ pStrings[ i ] = strdup( GetCommandLineToken( i, rFiles ).GetStr() );
+ pArgs[ i ].argClass = DtACTION_FILE;
+ pArgs[ i ].u.file.name = pStrings[ i ];
+ }
+
+ pid_t nPID = fork();
+ if( ! nPID )
+ // child
+ {
+ // if the action fails for some reason, CDE tries to raise
+ // an error box which leads to a SIGSEGV somewhere
+ // in Motif (probably because we are not a real Motif app)
+ // so execute this in its own process. if it dies, so what ?
+
+ // this is not perfectly safe though. The second process
+ // can cause an X Error wich comes back through our connection
+ // at an unpredictable time. Some Actions do this reproducable
+ // eg SDTAudio
+ pDtActionInvoke( maAppWidget, const_cast<char*>(rAction.GetStr()), pArgs, nTokens,
+ NULL, NULL, NULL, True, NULL, NULL );
+ _exit(0);
+ }
+ else
+ // parent
+ if( nPID > 0 )
+ waitpid( nPID, NULL, 0 );
+
+ // dtactioninvoke pops up the widget, pop it down again
+ if( pXtIsRealized( maAppWidget ) )
+ pXtUnrealizeWidget( maAppWidget );
+
+ for( i = 0; i < nTokens; i++ )
+ free( pStrings[i] );
+ delete pStrings;
+ delete pArgs;
+#endif
+}
+
+BOOL CDEIntegrator::StartProcess( String& rFile, String& rParams, const String& rDir )
+{
+ String aFiles;
+ if( rFile.GetChar( 0 ) != '"' )
+ {
+ aFiles = '\"';
+ aFiles += rFile;
+ aFiles += '\"';
+ }
+ else
+ aFiles = rFile;
+
+ if( rParams.Len() )
+ {
+ aFiles += ' ';
+ aFiles += rParams;
+ }
+ // first try to launch it
+ if( LaunchProcess( aFiles, rDir ) )
+ return TRUE;
+
+ // if not successfull it must be a file of whatever type
+ // look for an apropriate action
+ ByteString aFile( rFile, gsl_getSystemTextEncoding() );
+ char* pAttrValue = pDtDtsFileToAttributeValue( aFile.GetBuffer(), "ACTIONS" );
+ if( pAttrValue )
+ {
+ // there is an action for this file. invoke the first one
+ // (since we do not know which one
+ String aAction( pAttrValue, strlen( pAttrValue ), gsl_getSystemTextEncoding() );
+ pDtDtsFreeAttributeValue( pAttrValue );
+ aAction =
+ WhitespaceToSpace( aAction.GetToken( 0, ',' ) ).GetToken( 0, ' ' );
+ if( ! aAction.Len() )
+ return FALSE;
+
+ BOOL bPreviousState =
+ mpSalDisplay->GetXLib()->GetIgnoreXErrors();
+ mpSalDisplay->GetXLib()->SetIgnoreXErrors( TRUE );
+
+ InvokeAction( aAction, aFiles );
+
+ XSync( mpDisplay, False );
+ mpSalDisplay->GetXLib()->SetIgnoreXErrors( bPreviousState );
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static int getHexDigit( const char c )
+{
+ if( c >= '0' && c <= '9' )
+ return (int)(c-'0');
+ else if( c >= 'a' && c <= 'f' )
+ return (int)(c-'a'+10);
+ else if( c >= 'A' && c <= 'F' )
+ return (int)(c-'A'+10);
+ return -1;
+}
+
+
+BOOL CDEIntegrator::GetSystemLook( SystemLookInfo& rInfo )
+{
+ static Color aColors[ 8 ];
+ static sal_Bool bRead = sal_False;
+
+ if( ! bRead )
+ {
+ // get used palette from xrdb
+ char **ppStringList = 0;
+ int nStringCount;
+ XTextProperty aTextProperty;
+ aTextProperty.value = 0;
+ int i;
+
+ static Atom nResMgrAtom = XInternAtom( mpDisplay, "RESOURCE_MANAGER", False );
+
+ if( XGetTextProperty( mpDisplay,
+ RootWindow( mpDisplay, 0 ),
+ &aTextProperty,
+ nResMgrAtom )
+ && aTextProperty.value
+ && XTextPropertyToStringList( &aTextProperty, &ppStringList, &nStringCount )
+ )
+ {
+ // format of ColorPalette resource:
+ // *n*ColorPalette: palettefile
+
+ ByteString aLines;
+ for( i=0; i < nStringCount; i++ )
+ aLines += ppStringList[i];
+ for( i = aLines.GetTokenCount( '\n' )-1; i >= 0; i-- )
+ {
+ ByteString aLine = aLines.GetToken( i, '\n' );
+ int nIndex = aLine.Search( "ColorPalette" );
+ if( nIndex != STRING_NOTFOUND )
+ {
+ int nPos = nIndex;
+
+ nIndex+=12;
+ const char* pStr = aLine.GetBuffer() +nIndex;
+ while( *pStr && isspace( *pStr ) && *pStr != ':' )
+ {
+ pStr++;
+ nIndex++;
+ }
+ if( *pStr != ':' )
+ continue;
+ pStr++, nIndex++;
+ for( ; *pStr && isspace( *pStr ); pStr++, nIndex++ )
+ ;
+ if( ! *pStr )
+ continue;
+ int nIndex2 = nIndex;
+ for( ; *pStr && ! isspace( *pStr ); pStr++, nIndex2++ )
+ ;
+ ByteString aPaletteFile( aLine.Copy( nIndex, nIndex2 - nIndex ) );
+ // extract number before ColorPalette;
+ for( ; nPos >= 0 && aLine.GetChar( nPos ) != '*'; nPos-- )
+ ;
+ nPos--;
+ for( ; nPos >= 0 && aLine.GetChar( nPos ) != '*'; nPos-- )
+ ;
+ int nNumber = aLine.Copy( ++nPos ).ToInt32();
+
+ DBG_TRACE2( "found palette %d in resource \"%s\"", nNumber, aLine.GetBuffer() );
+
+ // found no documentation what this number actually means;
+ // might be the screen number. 0 seems to be the right one
+ // in most cases.
+ if( nNumber )
+ continue;
+
+ DBG_TRACE1( "Palette file is \"%s\".\n", aPaletteFile.GetBuffer() );
+
+ String aPath( aHomeDir );
+ aPath.AppendAscii( "/.dt/palettes/" );
+ aPath += String( aPaletteFile, gsl_getSystemTextEncoding() );
+
+ SvFileStream aStream( aPath, STREAM_READ );
+ if( ! aStream.IsOpen() )
+ {
+ aPath = String::CreateFromAscii( "/usr/dt/palettes/" );
+ aPath += String( aPaletteFile, gsl_getSystemTextEncoding() );
+ aStream.Open( aPath, STREAM_READ );
+ if( ! aStream.IsOpen() )
+ continue;
+ }
+
+ ByteString aBuffer;
+ for( nIndex = 0; nIndex < 8; nIndex++ )
+ {
+ aStream.ReadLine( aBuffer );
+ // format is "#RRRRGGGGBBBB"
+
+ DBG_TRACE1( "\t\"%s\".\n", aBuffer.GetBuffer() );
+
+ if( aBuffer.Len() )
+ {
+ const char* pArr = (const char*)aBuffer.GetBuffer()+1;
+ aColors[nIndex] = Color(
+ getHexDigit( pArr[1] )
+ | ( getHexDigit( pArr[0] ) << 4 ),
+ getHexDigit( pArr[5] )
+ | ( getHexDigit( pArr[4] ) << 4 ),
+ getHexDigit( pArr[9] )
+ | ( getHexDigit( pArr[8] ) << 4 )
+ );
+
+ DBG_TRACE1( "\t\t%lx\n", aColors[nIndex].GetColor() );
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ if( ppStringList )
+ XFreeStringList( ppStringList );
+ if( aTextProperty.value )
+ XFree( aTextProperty.value );
+ }
+
+ rInfo.windowActiveStart = aColors[0];
+ rInfo.windowActiveEnd = aColors[0];
+ rInfo.activeBorder = aColors[0];
+
+ rInfo.windowInactiveStart = aColors[1];
+ rInfo.windowInactiveEnd = aColors[1];
+ rInfo.inactiveBorder = aColors[1];
+
+ rInfo.activeForeground =
+ aColors[ 0 ].GetBlue() < 128 ||
+ aColors[ 0 ].GetGreen() < 128 ||
+ aColors[ 0 ].GetRed() < 128
+ ? Color( COL_WHITE ) : Color( COL_BLACK );
+ rInfo.inactiveForeground =
+ aColors[ 1 ].GetBlue() < 128 ||
+ aColors[ 1 ].GetGreen() < 128 ||
+ aColors[ 1 ].GetRed() < 128
+ ? Color( COL_WHITE ) : Color( COL_BLACK );
+ rInfo.foreground = rInfo.inactiveForeground;
+ rInfo.background = aColors[ 1 ];
+
+ return TRUE;
+}
diff --git a/vcl/unx/source/gdi/dtint.cxx b/vcl/unx/source/gdi/dtint.cxx
new file mode 100644
index 000000000000..d851d48f27f0
--- /dev/null
+++ b/vcl/unx/source/gdi/dtint.cxx
@@ -0,0 +1,1169 @@
+/*************************************************************************
+ *
+ * $RCSfile: dtint.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <prex.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <postx.h>
+
+#include <cdeint.hxx>
+#include <kdeint.hxx>
+#include <soicon.hxx>
+#include <saldisp.hxx>
+#include <saldata.hxx>
+#include <salbmp.hxx>
+#include <salframe.hxx>
+
+#include <strhelper.hxx>
+#include <svapp.hxx>
+
+#include <unistd.h>
+
+#ifndef _VOS_PROCESS_HXX
+#include <vos/process.hxx>
+#endif
+
+#include <tools/urlobj.hxx>
+
+#ifdef SOLARIS
+// Solaris 2.5.1 misses it in unistd.h
+extern "C" int usleep(unsigned int);
+#endif
+
+#define MAX_TRY_CONVERTSELECTION 40
+#define EVENTMASK_WHILE_DRAGGING ButtonPressMask | ButtonReleaseMask | PointerMotionMask
+
+BOOL bSymbolLoadFailed = FALSE;
+
+DtIntegratorList DtIntegrator::aIntegratorList;
+String DtIntegrator::aHomeDir;
+
+DtIntegrator::DtIntegrator( SalFrame* pFrame ) :
+ mpSalFrame( pFrame ),
+ mpSalDisplay( pFrame->maFrameData.GetDisplay() ),
+ meType( DtGeneric ),
+ mnRefCount( 0 ),
+ mpLastData( 0 ),
+ maDropSource( None ),
+ mpDropTarget( NULL ),
+ maDragTarget( None ),
+ meDragState( DtDragNone )
+{
+ mpDisplay = mpSalDisplay->GetDisplay();
+ maSelectionWindow =
+ XCreateSimpleWindow( mpDisplay, DefaultRootWindow( mpDisplay ),
+ 10,10,10,10,0,0,1 );
+ mnClipboardAtom = XInternAtom( mpDisplay, "CLIPBOARD", False );
+ mnTargetsAtom = XInternAtom( mpDisplay, "TARGETS", False );
+ mnCompoundAtom = XInternAtom( mpDisplay, "COMPOUND_TEXT", False );
+ maExPropertyAtom = XInternAtom( mpDisplay, "VCLExchangeProperty", False );
+
+ mnXdndAware = XInternAtom( mpDisplay, "XdndAware", False );
+ mnXdndSelection = XInternAtom( mpDisplay, "XdndSelection", False );
+ mnXdndEnter = XInternAtom( mpDisplay, "XdndEnter", False );
+ mnXdndLeave = XInternAtom( mpDisplay, "XdndLeave", False );
+ mnXdndStatus = XInternAtom( mpDisplay, "XdndStatus", False );
+ mnXdndTypeList = XInternAtom( mpDisplay, "XdndTypeList", False );
+ mnXdndPosition = XInternAtom( mpDisplay, "XdndPosition", False );
+ mnXdndDrop = XInternAtom( mpDisplay, "XdndDrop", False );
+ mnXdndActionCopy = XInternAtom( mpDisplay, "XdndActionCopy", False );
+ mnXdndActionMove = XInternAtom( mpDisplay, "XdndActionMove", False );
+ mnXdndActionLink = XInternAtom( mpDisplay, "XdndActionLink", False );
+ mnXdndActionCopy = XInternAtom( mpDisplay, "XdndActionCopy", False );
+ mnXdndActionAsk = XInternAtom( mpDisplay, "XdndActionAsk", False );
+ mnXdndActionDescription = XInternAtom( mpDisplay, "XdndActionDescription", False );
+ mnXdndFinished = XInternAtom( mpDisplay, "XdndFinished", False ); mnXdndActionList = XInternAtom( mpDisplay, "XdndActionList", False );
+
+ aIntegratorList.Insert( this, LIST_APPEND );
+ aHomeDir = String( getenv( "HOME" ), gsl_getSystemTextEncoding() );
+}
+
+DtIntegrator::~DtIntegrator()
+{
+ XDestroyWindow( mpDisplay, maSelectionWindow );
+ if( mpLastData )
+ delete mpLastData;
+ while( maDropTypes.Count() )
+ delete maDropTypes.Remove( (ULONG)0 );
+ while( maDragTypes.Count() )
+ delete maDragTypes.Remove( (ULONG)0 );
+}
+
+BOOL DtIntegrator::CheckUnxClipboardChanged()
+{
+ XLIB_Window aPrimWindow = XGetSelectionOwner( mpDisplay, XA_PRIMARY );
+ XLIB_Window aClipWindow = XGetSelectionOwner( mpDisplay, mnClipboardAtom );
+
+ if( aPrimWindow != maSelectionWindow && aPrimWindow != None )
+ return TRUE;
+ if( aClipWindow != maSelectionWindow && aClipWindow != None )
+ return TRUE;
+ return FALSE;
+}
+
+void DtIntegrator::Copy( DtData* pData )
+{
+ if( mpLastData )
+ delete mpLastData;
+ mpLastData = pData;
+
+ XSetSelectionOwner( mpDisplay, XA_PRIMARY,
+ maSelectionWindow, CurrentTime );
+ XSetSelectionOwner( mpDisplay, mnClipboardAtom,
+ maSelectionWindow, CurrentTime );
+
+#if defined DBG_UTIL || defined DEBUG
+ if( XGetSelectionOwner( mpDisplay, XA_PRIMARY ) != maSelectionWindow )
+ fprintf( stderr, "Could not acquire ownership of PRIMARY\n" );
+ if( XGetSelectionOwner( mpDisplay, mnClipboardAtom ) !=
+ maSelectionWindow )
+ fprintf( stderr, "Could not acquire ownership of CLIPBOARD\n" );
+#endif
+}
+
+void DtIntegrator::RegisterDropzone( SalFrame* pFrame )
+{
+ for( int i = 0; i < maDropzones.Count(); i++ )
+ {
+ if( maDropzones.GetObject( i ) == pFrame )
+ return;
+ }
+ maDropzones.Insert( pFrame, LIST_APPEND );
+
+ // create XdndAware property on window to acknowledge DND awareness
+ static int nVersion = XDND_PROTOCOL_VERSION;
+ XChangeProperty( mpDisplay, pFrame->maFrameData.GetWindow(),
+ mnXdndAware, XA_ATOM, 32, PropModeReplace,
+ (unsigned char*)(&nVersion), 1 );
+
+ ImplRegisterDropzone( pFrame );
+}
+
+void DtIntegrator::UnregisterDropzone( SalFrame* pFrame )
+{
+ maDropzones.Remove( pFrame );
+
+ XDeleteProperty( mpDisplay, pFrame->maFrameData.GetWindow(), mnXdndAware );
+
+ ImplUnregisterDropzone( pFrame );
+}
+
+void DtIntegrator::ImplRegisterDropzone( SalFrame* pFrame )
+{
+}
+
+void DtIntegrator::ImplUnregisterDropzone( SalFrame* pFrame )
+{
+}
+
+void DtIntegrator::ImplHandleXEvent( XEvent* pEvent )
+{
+ if( pEvent->type == SelectionClear )
+ {
+ if( meDragState != DtDragNone &&
+ pEvent->xselectionclear.selection == mnXdndSelection )
+ {
+ meDragState = DtDragNone;
+ maDragSource = None;
+ maDragTarget = None;
+ }
+ else
+ maClipboardChangedHdl.Call( this );
+ }
+ else if( pEvent->type == SelectionRequest )
+ {
+ BOOL bConvertable = FALSE;
+ XSelectionRequestEvent& rSelEvent = pEvent->xselectionrequest;
+ XEvent aSendEvent;
+ aSendEvent.type = SelectionNotify;
+ aSendEvent.xselection.display = rSelEvent.display;
+ aSendEvent.xselection.send_event = True;
+ aSendEvent.xselection.requestor = rSelEvent.requestor;
+ aSendEvent.xselection.selection = rSelEvent.selection;
+ aSendEvent.xselection.time = rSelEvent.time;
+ // xterm seems to be the only one to care about time = CurrentTime
+
+ // clipboard and xdnd requests land here
+ if( rSelEvent.selection == XA_PRIMARY ||
+ rSelEvent.selection == mnClipboardAtom )
+ {
+
+#if defined DEBUG
+ char* pType = XGetAtomName( mpDisplay, rSelEvent.target );
+ fprintf( stderr, "Request for conversion of %s with type \"%s\"\n",
+
+ rSelEvent.selection == XA_PRIMARY ? "PRIMARY" : "CLIPBOARD", pType );
+ XFree( pType );
+#endif
+ if( ( rSelEvent.target == XA_STRING ||
+ rSelEvent.target == mnCompoundAtom )
+ && mpLastData && mpLastData->mnBytes )
+ {
+ bConvertable = TRUE;
+ XChangeProperty( mpDisplay, rSelEvent.requestor,
+ rSelEvent.property, XA_STRING,
+ 8, PropModeReplace,
+ mpLastData->mpBytes,
+ mpLastData->mnBytes );
+ aSendEvent.xselection.target = rSelEvent.target;
+ }
+ else if( rSelEvent.target == mnTargetsAtom )
+ {
+ bConvertable = TRUE;
+ Atom aAtom = XA_STRING;
+ XChangeProperty( mpDisplay, rSelEvent.requestor,
+ rSelEvent.property, XA_ATOM,
+ 32, PropModeReplace,
+ (unsigned char*)&aAtom, 1 );
+ aSendEvent.xselection.target = mnTargetsAtom;
+ }
+ }
+ else if( rSelEvent.selection == mnXdndSelection && meDragState != DtDragNone )
+ {
+ DtData aData;
+ aData.mpType = (unsigned char*)XGetAtomName( mpDisplay, rSelEvent.target );
+#if defined DEBUG
+ fprintf( stderr, "Request for convertion of XdndSelection with type \"%s\"\n", aData.mpType );
+#endif
+ maQueryDragDataHdl.Call( &aData );
+ if( aData.mnBytes > 0 )
+ {
+ bConvertable = TRUE;
+ XChangeProperty( mpDisplay, rSelEvent.requestor,
+ rSelEvent.property, rSelEvent.target,
+ 8, PropModeReplace,
+ aData.mpBytes,
+ aData.mnBytes );
+ aSendEvent.xselection.target = rSelEvent.target;
+ }
+ XFree( aData.mpType );
+ // drag and drop does NOT end here
+ // the target may ask more than once for the data
+ // hopefully this can work with the office
+ }
+ aSendEvent.xselection.property =
+ bConvertable ? rSelEvent.property : None;
+ if( ! XSendEvent( mpDisplay, rSelEvent.requestor,
+ False, 0, &aSendEvent ) )
+ fprintf( stderr, "HandleSelectionRequest: XSendEvent failed\n" );
+ }
+ else if( pEvent->type == ClientMessage )
+ {
+ int i = pEvent->xclient.message_type;
+
+ if( i == mnXdndEnter &&
+ ( pEvent->xclient.data.l[1] >> 24 ) <= XDND_PROTOCOL_VERSION &&
+ ! mpDropTarget )
+ {
+#if defined DEBUG
+ fprintf( stderr, "XdndEnter with XDND protocol version %d\n",
+ pEvent->xclient.data.l[1] >> 24 );
+#endif
+ // a drop begins
+
+ // search the correct target frame
+ for( i = 0; i < maDropzones.Count(); i++ )
+ {
+ SalFrame *pFrame = maDropzones.GetObject( i );
+ if( pFrame->maFrameData.GetWindow() ==
+ pEvent->xclient.window )
+ {
+ mpDropTarget = pFrame;
+ break;
+ }
+ }
+ if( ! mpDropTarget )
+ {
+#if defined DEBUG || defined DBG_UTIL
+ fprintf( stderr, "Received XdndEnter and have no corresponding dropzone !!!\n" );
+#endif
+ return;
+ }
+
+ maDropSource = pEvent->xclient.data.l[0];
+ // build a stringlist of types
+ while( maDropTypes.Count() )
+ delete maDropTypes.Remove( (ULONG)0 );
+ for( int i = 2; i < 5; i++ )
+ {
+ if( pEvent->xclient.data.l[i] != None )
+ {
+ char *pAtomName = XGetAtomName( mpDisplay, pEvent->xclient.data.l[i] );
+ maDropTypes.Insert( new String( pAtomName, RTL_TEXTENCODING_ISO_8859_1 ) );
+ XFree( pAtomName );
+ }
+ }
+ if( maDropTypes.Count() > 2 && (pEvent->xclient.data.l[1] & 1) )
+ {
+ unsigned long nCount;
+ Atom aType;
+ int nFormat;
+ unsigned long nBytesLeft;
+ Atom* pTypeData = 0;
+ if( XGetWindowProperty( mpDisplay, maDropSource,
+ mnXdndTypeList, 0, 256,
+ False, XA_ATOM,
+ &aType, &nFormat,
+ &nCount, &nBytesLeft,
+ (unsigned char**)(&pTypeData) ) )
+ {
+ if( aType == XA_ATOM && nFormat == 32 && nCount )
+ {
+ while( nCount )
+ {
+ char * pTypeName =
+ XGetAtomName( mpDisplay, pTypeData[ --nCount ] );
+ maDropTypes.Insert( new String( pTypeData[ nCount ], RTL_TEXTENCODING_ISO_8859_1 ) );
+ }
+ }
+ if( pTypeData )
+ XFree( pTypeData );
+ }
+ }
+
+ maBeginDropHdl.Call( NULL );
+ }
+ else if( i == mnXdndPosition && maDropSource != None && mpDropTarget )
+ {
+#if defined DEBUG
+ fprintf( stderr, "Received XdndPosition\n" );
+#endif
+ // remember time stamps
+ mnDropDataTime = pEvent->xclient.data.l[3];
+
+ // put x,y and action into a structure here
+ DtDropQuery aDropQuery;
+ aDropQuery.m_pFrame = mpDropTarget;
+ int x = pEvent->xclient.data.l[2] >> 16;
+ int y = pEvent->xclient.data.l[2] & 0xffff;
+ XLIB_Window aChild;
+ XTranslateCoordinates( mpDisplay, DefaultRootWindow( mpDisplay ),
+ mpDropTarget->maFrameData.GetWindow(),
+ x, y,
+ &aDropQuery.m_nX,
+ &aDropQuery.m_nY,
+ &aChild );
+ if( pEvent->xclient.data.l[4] == mnXdndActionLink )
+ aDropQuery.m_eAction = DtDropLink;
+ else if( pEvent->xclient.data.l[4] == mnXdndActionMove )
+ aDropQuery.m_eAction = DtDropMove;
+ else
+ aDropQuery.m_eAction = DtDropCopy;
+
+ mnLastDropX = aDropQuery.m_nX;
+ mnLastDropY = aDropQuery.m_nY;
+
+ // query for dropping on new position
+ DtDropAction eResult = (DtDropAction)maQueryDropHdl.Call( &aDropQuery );
+#if defined DEBUG
+ fprintf( stderr, "QueryDropHdl returned result " );
+ switch( eResult )
+ {
+ case DtDropNone: fprintf( stderr, "DtDropNone\n\n" );break;
+ case DtDropCopy: fprintf( stderr, "DtDropCopy\n\n" );break;
+ case DtDropLink: fprintf( stderr, "DtDropLink\n\n" );break;
+ case DtDropMove: fprintf( stderr, "DtDropMove\n\n" );break;
+ case DtDropAny: fprintf( stderr, "DtDropAny\n\n" );break;
+ default: fprintf( stderr, "Unknown !!!\n\n" );break;
+ }
+#endif
+
+ // give source a status
+ XEvent aSendEvent;
+ aSendEvent.type = ClientMessage;
+ aSendEvent.xclient.display = mpDisplay;
+ aSendEvent.xclient.window = maDropSource;
+ aSendEvent.xclient.message_type = mnXdndStatus;
+ aSendEvent.xclient.format = 32;
+ aSendEvent.xclient.data.l[0] = mpDropTarget->maFrameData.GetWindow();
+ aSendEvent.xclient.data.l[1] = 2;
+ switch( eResult )
+ {
+ case DtDropCopy:
+ case DtDropMove:
+ case DtDropLink:
+ case DtDropAny:
+ aSendEvent.xclient.data.l[1] |= 1;
+ default: ;
+ }
+ aSendEvent.xclient.data.l[2] = 0;
+ aSendEvent.xclient.data.l[3] = 0;
+ if( eResult == DtDropCopy )
+ aSendEvent.xclient.data.l[4] = mnXdndActionCopy;
+ else if( eResult == DtDropMove )
+ aSendEvent.xclient.data.l[4] = mnXdndActionMove;
+ else if( eResult == DtDropLink )
+ aSendEvent.xclient.data.l[4] = mnXdndActionLink;
+ else
+ aSendEvent.xclient.data.l[4] = None;
+ XSendEvent( mpDisplay, maDropSource, False, NoEventMask, &aSendEvent );
+ }
+ else if( i == mnXdndLeave && maDropSource != None )
+ {
+#if defined DEBUG
+ fprintf( stderr, "Received XdndLeave\n" );
+#endif
+ if( pEvent->xclient.data.l[0] == maDropSource )
+ {
+ maDropSource = None;
+ mpDropTarget = NULL;
+
+ DtDropQuery aDropQuery;
+ aDropQuery.m_nX = mnLastDropX;
+ aDropQuery.m_nY = mnLastDropY;
+ aDropQuery.m_eAction = DtDropNone;
+ aDropQuery.m_pFrame = mpDropTarget;
+ maDropFinishHdl.Call( &aDropQuery );
+
+ }
+ }
+ else if( i == mnXdndDrop && maDropSource != None )
+ {
+#if defined DEBUG
+ fprintf( stderr, "Received XdndDrop\n" );
+#endif
+ // remember time stamps
+ mnDropDataTime = pEvent->xclient.data.l[2];
+
+ DtDropQuery aDropQuery;
+ aDropQuery.m_nX = mnLastDropX;
+ aDropQuery.m_nY = mnLastDropY;
+ aDropQuery.m_eAction = DtDropAny;
+ aDropQuery.m_pFrame = mpDropTarget;
+ // the drop finish handler should relay the data types
+ // FinishDrop should be called then which retrieves the data
+ // FinishDrop must not be called after this handler returns
+ maDropFinishHdl.Call( &aDropQuery );
+ // finally send a drop finished
+ XEvent aSendEvent;
+ aSendEvent.type = ClientMessage;
+ aSendEvent.xclient.display = mpDisplay;
+ aSendEvent.xclient.window = maDropSource;
+ aSendEvent.xclient.message_type = mnXdndFinished;
+ aSendEvent.xclient.format = 32;
+ aSendEvent.xclient.data.l[0] = mpDropTarget->maFrameData.GetWindow();
+ aSendEvent.xclient.data.l[1] = 0;
+ aSendEvent.xclient.data.l[2] = 0;
+ aSendEvent.xclient.data.l[3] = 0;
+ aSendEvent.xclient.data.l[4] = 0;
+
+ XSendEvent( mpDisplay, maDropSource, True, NoEventMask, &aSendEvent );
+ maDropSource = None;
+ mpDropTarget = NULL;
+ }
+ else if( meDragState != DtDropNone &&
+ meDragState != DtWaitForDataRequest &&
+ pEvent->xclient.message_type == mnXdndStatus )
+ {
+ int nAction = pEvent->xclient.data.l[4];
+ // set pointer correctly
+ XLIB_Cursor aCursor;
+ if( pEvent->xclient.data.l[1] & 1 )
+ {
+ if( nAction == mnXdndActionCopy )
+ aCursor = mpSalDisplay->GetPointer( POINTER_COPYFILES );
+ else if( nAction == mnXdndActionMove )
+ aCursor = mpSalDisplay->GetPointer( POINTER_MOVEFILES );
+ else if( nAction == mnXdndActionLink )
+ aCursor = mpSalDisplay->GetPointer( POINTER_LINKFILE );
+ else
+ aCursor = mpSalDisplay->GetPointer( POINTER_CROP );
+ }
+ else
+ // target will not accept the drop
+ aCursor = mpSalDisplay->GetPointer( POINTER_NOTALLOWED );
+ XChangeActivePointerGrab( mpDisplay,
+ EVENTMASK_WHILE_DRAGGING,
+ aCursor, CurrentTime );
+#if defined DEBUG
+ char* pAction = nAction != None ?
+ XGetAtomName( mpDisplay, nAction ) : "None";
+ fprintf( stderr, "Received XdndStatus %s(%s)\n",
+ pEvent->xclient.data.l[1] & 1 ? "accept" : "deny",
+ pAction );
+ if( nAction != None )
+ XFree( pAction );
+#endif
+ meDragState = DtDragging;
+ SendXdndPosition( pEvent );
+ }
+ else if( meDragState != DtDragNone &&
+ pEvent->xclient.message_type == mnXdndFinished )
+ {
+#if defined DEBUG
+ fprintf( stderr, "Received XdndFinished\n" );
+#endif
+ maDragTarget = None;
+ maDragSource = None;
+ meDragState = DtDragNone;
+ }
+ }
+ else if( pEvent->type == MotionNotify ||
+ pEvent->type == XLIB_KeyPress ||
+ pEvent->type == KeyRelease
+ )
+ {
+ if( pEvent->type == XLIB_KeyPress )
+ {
+ char sDummy[2];
+ sDummy[0] = sDummy[1] = 0;
+ KeySym nKeySym = 0;
+ XLookupString( &pEvent->xkey, sDummy, 1, &nKeySym, NULL );
+ if( nKeySym == XK_Escape )
+ meDragState = DtDragNone;
+ }
+ if( meDragState != DtDragNone &&
+ meDragState != DtWaitForDataRequest )
+
+ {
+ // find XdndAware window beneath pointer
+ int nXdndVersion;
+ XLIB_Window aWindow = GetXdndAwareWindowBeneathPointer( nXdndVersion, pEvent );
+ if( maDragTarget != aWindow )
+ {
+ // send a XdndLeave to previous window
+ SendXdndLeave();
+ // then send a XdndEnter to new window
+ maDragTarget = aWindow;
+ SendXdndEnter();
+ }
+ // send a XdndPosition
+ SendXdndPosition( pEvent );
+ }
+ else
+ CheckXdndTimeout( pEvent->xmotion.time );
+ }
+ else if( pEvent->type == ButtonRelease )
+ {
+ if( meDragState != DtDragNone &&
+ meDragState != DtWaitForDataRequest )
+ {
+ int nXdndVersion;
+ XLIB_Window aWindow = GetXdndAwareWindowBeneathPointer( nXdndVersion, pEvent );
+ if( maDragTarget != aWindow )
+ {
+ SendXdndLeave();
+ maDragTarget = aWindow;
+ SendXdndEnter();
+ SendXdndPosition( pEvent );
+ }
+ if( maDragTarget != None )
+ {
+ // send XdndDrop
+ XEvent aEvent;
+ aEvent.type = ClientMessage;
+ aEvent.xclient.display = mpDisplay;
+ aEvent.xclient.window = maDragTarget;
+ aEvent.xclient.format = 32;
+ aEvent.xclient.message_type = mnXdndDrop;
+ aEvent.xclient.data.l[0] = maDragSource;
+ aEvent.xclient.data.l[1] = 0;
+ aEvent.xclient.data.l[2] = pEvent->xbutton.time;
+ XSendEvent( mpDisplay, maDragTarget, False,
+ NoEventMask, &aEvent );
+#if defined DEBUG
+ fprintf( stderr, "Sending XdndDrop\n" );
+#endif
+ meDragState = DtWaitForDataRequest;
+ mnWaitTimestamp = pEvent->xbutton.time;
+ }
+ else
+ {
+#if defined DEBUG
+ fprintf( stderr, "Received ButtonRelease and no DragTarget\n" );
+#endif
+ maDragTarget = None;
+ maDragSource = None;
+ meDragState = DtDragNone;
+ }
+ }
+ else
+ CheckXdndTimeout( pEvent->xbutton.time );
+ }
+}
+
+DtData* DtIntegrator::DropFinish( const String& rType )
+{
+ ByteString aTypeString( rType, RTL_TEXTENCODING_ISO_8859_1 );
+#if defined DEBUG
+ fprintf( stderr, "DtIntegerator::DropFinish( \"%s\" ) : ", aTypeString.GetBuffer() );
+#endif
+ if( maDropSource == None || mpDropTarget == NULL )
+ {
+#if defined DEBUG
+ fprintf( stderr, "failed\n" );
+#endif
+ return NULL;
+ }
+
+ DtData* pData = new DtData;
+ pData->meType = DtTypeKnown;
+ pData->mnX = mnLastDropX;
+ pData->mnY = mnLastDropY;
+
+ Atom aType = XInternAtom( mpDisplay, aTypeString.GetBuffer(), False );
+
+ // now initiate communication with selection owner
+ XConvertSelection( mpDisplay, mnXdndSelection,
+ aType, maExPropertyAtom, maSelectionWindow, mnDropDataTime );
+ // wait for selection notify
+ XEvent aXEvent;
+ int nTries;
+ for( nTries = 0;
+ ! XCheckTypedEvent( mpDisplay, SelectionNotify, &aXEvent ) &&
+ nTries <= MAX_TRY_CONVERTSELECTION ;
+ nTries++ )
+ usleep( 50000 );
+
+ // check if request could be converted
+ if( nTries >= MAX_TRY_CONVERTSELECTION ||
+ aXEvent.xselection.property != maExPropertyAtom )
+ {
+ delete pData;
+ pData = 0;
+ }
+ else
+ {
+ Atom aActualType;
+ int nActualFormat;
+ unsigned long nItems;
+ unsigned long nBytesAfter;
+ unsigned char *pBytes=0;
+ XGetWindowProperty( mpDisplay, maSelectionWindow, maExPropertyAtom,
+ 0, // long_offset
+ 65536, // long_length, a maximum of 256k will be retrieved
+ True, // delete property after reading
+ aType, // the type we want
+ &aActualType, &nActualFormat,
+ &nItems, &nBytesAfter, &pBytes );
+
+ if( pBytes )
+ {
+ pData->mnBytes = nItems * (nActualFormat/8);
+ pData->mpBytes = new unsigned char[ pData->mnBytes + 1 ];
+ memcpy( pData->mpBytes, pBytes, pData->mnBytes );
+ pData->mpBytes[ pData->mnBytes ] = 0;
+ XFree( pBytes );
+ }
+ else
+ {
+ delete pData;
+ pData = 0;
+ }
+ }
+
+#if defined DEBUG
+ fprintf( stderr, "%s\n", pData ? "success" : "failed" );
+#endif
+ return pData;
+}
+
+DtData* DtIntegrator::Paste()
+{
+ DtData* pDtData = 0;
+
+ // check if there IS something to copy
+ XLIB_Window aOwner = XGetSelectionOwner( mpDisplay, XA_PRIMARY );
+ if( aOwner == None || aOwner == maSelectionWindow )
+ return 0;
+
+ // get the proper Atoms
+ Atom aTypeAtom = XA_STRING;
+
+ // now initiate communication with selection owner
+ XConvertSelection( mpDisplay, XA_PRIMARY, aTypeAtom, maExPropertyAtom,
+ maSelectionWindow, CurrentTime );
+ // wait for selection notify
+ XEvent aXEvent;
+ int nTries;
+ for( nTries = 0;
+ ! XCheckTypedEvent( mpDisplay, SelectionNotify, &aXEvent ) &&
+ nTries <= MAX_TRY_CONVERTSELECTION ;
+ nTries++ )
+ usleep( 50000 );
+
+ // check if request could be converted
+ if( nTries >= MAX_TRY_CONVERTSELECTION ||
+ aXEvent.xselection.property != maExPropertyAtom )
+ {
+ // let us try CLIPBOARD selection
+ XConvertSelection( mpDisplay, mnClipboardAtom, aTypeAtom,
+ maExPropertyAtom, maSelectionWindow, CurrentTime );
+ for( nTries = 0;
+ ! XCheckTypedEvent( mpDisplay, SelectionNotify, &aXEvent ) &&
+ nTries < MAX_TRY_CONVERTSELECTION ;
+ nTries++ )
+ usleep( 50000 );
+ }
+
+ // check if request could be converted
+ if( nTries >= MAX_TRY_CONVERTSELECTION ||
+ aXEvent.xselection.property != maExPropertyAtom )
+ return 0;
+
+ Atom aActualType;
+ int nActualFormat;
+ unsigned long nItems;
+ unsigned long nBytesAfter;
+ unsigned char *pData=0;
+ XGetWindowProperty( mpDisplay, maSelectionWindow, maExPropertyAtom,
+ 0, // long_offset
+ 16384, // long_length, a maximum of 64k will e retrieved
+ True, // delete property after reading
+ XA_STRING, // the type we want
+ &aActualType, &nActualFormat,
+ &nItems, &nBytesAfter, &pData );
+
+ if( pData )
+ {
+ pDtData = new DtData;
+ pDtData->meType = DtTypeText;
+ pDtData->mnBytes = nItems * (nActualFormat/8);
+ pDtData->mpBytes = new unsigned char[ pDtData->mnBytes + 1 ];
+ memcpy( pDtData->mpBytes, pData, pDtData->mnBytes );
+ pDtData->mpBytes[ pDtData->mnBytes ] = 0;
+ pDtData->mnBytes += 1;
+ XFree( pData );
+ return pDtData;
+ }
+ return 0;
+}
+
+BOOL DtIntegrator::StartProcess( String& rFile, String& rParams, const String& rDir )
+{
+ String aFiles( rFile );
+ if( rParams.Len() )
+ {
+ aFiles += ' ';
+ aFiles += rParams;
+ }
+ // try to launch it
+ return LaunchProcess( aFiles, rDir );
+}
+
+DtIntegrator* DtIntegrator::CreateDtIntegrator( SalFrame* pFrame )
+{
+ // hack for sclient
+ if( ! pFrame && aIntegratorList.Count() )
+ return aIntegratorList.GetObject( 0 );
+
+ for( int i = 0; i < aIntegratorList.Count(); i++ )
+ {
+ DtIntegrator* pIntegrator = aIntegratorList.GetObject( i );
+ if( pIntegrator->mpDisplay == pFrame->maFrameData.GetXDisplay() )
+ return pIntegrator;
+ }
+
+ if( ! pFrame )
+ pFrame = GetSalData()->pFirstFrame_;
+
+#ifndef REMOTE_APPSERVER
+ Display* pDisplay = pFrame->maFrameData.GetXDisplay();
+ Atom nDtAtom;
+ void* pLibrary = NULL;
+
+ // check dt type
+ // CDE
+ nDtAtom = XInternAtom( pDisplay, "_DT_WM_READY", True );
+ if( nDtAtom && ( pLibrary = _LoadLibrary( "libDtSvc.so" ) ) )
+ {
+ // performance: do not dlopen DtSvc twice
+ CDEIntegrator::pDtSvcLib = pLibrary;
+ return new CDEIntegrator( pFrame );
+ }
+
+ nDtAtom = XInternAtom( pDisplay, "KWM_RUNNING", True );
+ if( nDtAtom ) // perhaps should check getenv( "KDEDIR" )
+ return new KDEIntegrator( pFrame );
+#endif
+ // default: generic implementation
+ return new DtIntegrator( pFrame );
+}
+
+void DtIntegrator::HandleXEvent( XEvent* pEvent )
+{
+ Display *pDisplay = pEvent->xany.display;
+ for( int i = 0; i < aIntegratorList.Count(); i++ )
+ {
+ DtIntegrator* pIntegrator = aIntegratorList.GetObject( i );
+ if( pIntegrator->mpDisplay == pDisplay )
+ {
+ pIntegrator->ImplHandleXEvent( pEvent );
+ break;
+ }
+ }
+}
+
+BOOL DtIntegrator::LaunchProcess( const String& rParam, const String& rDirectory )
+{
+ int nArg;
+
+ char *pDisplayName = DisplayString( mpDisplay );
+ int nToken = GetCommandLineTokenCount( rParam );
+
+ ::rtl::OUString* pArgs = new ::rtl::OUString[nToken];
+ for( nArg = 0; nArg < nToken ; nArg++ )
+ pArgs[ nArg ] = GetCommandLineToken( nArg, rParam );
+ NAMESPACE_VOS(OArgumentList) aArgList( pArgs+1, nToken-1 );
+ delete pArgs;
+
+ ::rtl::OUString aDisplay;
+ if( pDisplayName )
+ {
+ aDisplay = ::rtl::OUString::createFromAscii( "DISPLAY=" );
+ aDisplay += ::rtl::OUString::createFromAscii( pDisplayName );
+ }
+ NAMESPACE_VOS(OEnvironment) aEnvironment( 1, &aDisplay );
+
+ NAMESPACE_VOS( OProcess ) aOProcess( pArgs[0], rDirectory );
+
+ BOOL bSuccess = aOProcess.execute(
+ ( NAMESPACE_VOS( OProcess )::TProcessOption)
+ ( NAMESPACE_VOS( OProcess )::TOption_Detached |
+ NAMESPACE_VOS( OProcess )::TOption_SearchPath ),
+ aArgList, aEnvironment )
+ == NAMESPACE_VOS( OProcess )::E_None ? TRUE : FALSE;
+
+ return bSuccess;
+}
+
+DtDropAction DtIntegrator::ExecuteDrag( const StringList& rTypes, SalFrame* pDragFrame )
+{
+ int i;
+ Atom* pTypes = new Atom[rTypes.Count() ];
+
+#if defined DEBUG
+ fprintf( stderr, "DtIntegrator::ExecuteDrag: " );
+#endif
+ meDragState = DtDragging;
+
+ if( ! pDragFrame )
+ pDragFrame = maDropzones.GetObject( maDropzones.Count()-1 );
+ else
+ {
+ for( i = 0; i < maDropzones.Count(); i++ )
+ if( maDropzones.GetObject( i ) == pDragFrame )
+ break;
+ if( i >= maDropzones.Count() )
+ {
+#if defined DEBUG
+ fprintf( stderr, "DragFrame is no Dropzone !!! taking last dropzone as source instead ...\n" );
+#endif
+ pDragFrame = maDropzones.GetObject( maDropzones.Count()-1 );
+ }
+ }
+
+ maDragSource = pDragFrame->maFrameData.GetWindow();
+ // set up drag types
+ while( maDragTypes.Count() )
+ delete maDragTypes.Remove( (ULONG)0 );
+ for( i = 0; i < rTypes.Count(); i++ )
+ {
+ maDragTypes.Insert( new String( *rTypes.GetObject( i ) ), LIST_APPEND );
+ pTypes[ i ] = XInternAtom( mpDisplay,
+ ByteString( *rTypes.GetObject( i ), RTL_TEXTENCODING_ISO_8859_1 ).GetBuffer(),
+ False );
+#if defined DEBUG
+ fprintf( stderr, " \"%s\"",
+ ByteString( *rTypes.GetObject( i ), RTL_TEXTENCODING_ISO_8859_1 ).GetBuffer() );
+#endif
+ }
+#if defined DEBUG
+ fprintf( stderr, "\n" );
+#endif
+
+ // set the types in the property XdndTypeList
+ XChangeProperty( mpDisplay, maDragSource, mnXdndTypeList, XA_ATOM,
+ 32, PropModeReplace, (unsigned char*)pTypes,
+ rTypes.Count() );
+ delete pTypes;
+
+ XLIB_Cursor aCur = mpSalDisplay->GetPointer( POINTER_MOVEFILES );
+ XLIB_Window aRoot = DefaultRootWindow( mpDisplay );
+
+ // set cursor
+ XGrabPointer( mpDisplay, aRoot, False,
+ EVENTMASK_WHILE_DRAGGING,
+ GrabModeAsync, GrabModeAsync, None, aCur, CurrentTime );
+ XGrabKeyboard( mpDisplay, maDragSource, False, GrabModeAsync,
+ GrabModeAsync, CurrentTime );
+ XSetSelectionOwner( mpDisplay, mnXdndSelection,
+ maDragSource, CurrentTime );
+
+ while( meDragState != DtDragNone )
+ Application::Yield();
+
+ XSetSelectionOwner( mpDisplay, mnXdndSelection,
+ None, CurrentTime );
+ XUngrabKeyboard( mpDisplay, CurrentTime );
+ XUngrabPointer( mpDisplay, CurrentTime );
+
+ return DtDropCopy;
+}
+
+XLIB_Window DtIntegrator::GetXdndAwareWindowBeneathPointer( int& rVersion,
+ XEvent* pEvent)
+{
+ XLIB_Window aRoot = DefaultRootWindow( mpDisplay );
+ XLIB_Window aWindow = aRoot, aParent = aRoot;
+ int nXRoot, nYRoot, nX, nY;
+
+ if( pEvent->type == MotionNotify )
+ {
+ nX = pEvent->xmotion.x_root;
+ nY = pEvent->xmotion.y_root;
+ }
+ else if( pEvent->type == ButtonPress || pEvent->type == ButtonRelease )
+ {
+ nX = pEvent->xbutton.x_root;
+ nY = pEvent->xbutton.y_root;
+ }
+ else if( pEvent->type == XLIB_KeyPress || pEvent->type == KeyRelease )
+ {
+ nX = pEvent->xkey.x_root;
+ nY = pEvent->xkey.y_root;
+ }
+
+ rVersion = 0;
+ while( ! rVersion && aWindow != None )
+ {
+ XTranslateCoordinates( mpDisplay, aRoot, aParent,
+ nX, nY, &nXRoot, &nYRoot, &aWindow );
+ if( aWindow != None )
+ {
+ aParent = aWindow;
+
+ Atom aActualType;
+ int nActualFormat;
+ unsigned long nItems;
+ unsigned long nBytesAfter;
+ unsigned char *pData=0;
+ XGetWindowProperty( mpDisplay, aWindow,
+ mnXdndAware,
+ 0, 1, False, XA_ATOM,
+ &aActualType, &nActualFormat,
+ &nItems, &nBytesAfter, &pData );
+ if( pData &&
+ aActualType == XA_ATOM &&
+ nActualFormat == 32 &&
+ nItems == 1 )
+ {
+ rVersion = *((int*)pData );
+ }
+ if( pData )
+ XFree( pData );
+ }
+ }
+ if( ! rVersion )
+ return None;
+
+ return aWindow;
+}
+
+void DtIntegrator::SendXdndLeave()
+{
+ if( maDragTarget != None )
+ {
+ XEvent aEvent;
+ aEvent.type = ClientMessage;
+ aEvent.xclient.display = mpDisplay;
+ aEvent.xclient.window = maDragTarget;
+ aEvent.xclient.format = 32;
+ aEvent.xclient.message_type = mnXdndLeave;
+ aEvent.xclient.data.l[0] = maDragSource;
+ aEvent.xclient.data.l[1] = 0;
+ XSendEvent( mpDisplay, maDragTarget, False,
+ NoEventMask, &aEvent );
+#if defined DEBUG
+ fprintf( stderr, "Sending XdndLeave\n" );
+#endif
+ }
+}
+
+void DtIntegrator::SendXdndEnter()
+{
+ if( maDragTarget != None )
+ {
+ int i;
+ XEvent aEvent;
+
+ aEvent.type = ClientMessage;
+ aEvent.xclient.display = mpDisplay;
+ aEvent.xclient.window = maDragTarget;
+ aEvent.xclient.format = 32;
+ aEvent.xclient.message_type = mnXdndEnter;
+ aEvent.xclient.data.l[0] = maDragSource;
+ aEvent.xclient.data.l[1] = maDragTypes.Count() > 3 ? 1 : 0;
+ aEvent.xclient.data.l[1] |= XDND_PROTOCOL_VERSION << 24;
+ aEvent.xclient.data.l[2] = None;
+ aEvent.xclient.data.l[3] = None;
+ aEvent.xclient.data.l[4] = None;
+ for( i = 0; i < maDragTypes.Count() && i < 3; i++ )
+ aEvent.xclient.data.l[i+2] =
+ XInternAtom( mpDisplay,
+ ByteString( *maDragTypes.GetObject( i ), RTL_TEXTENCODING_ISO_8859_1 ).GetBuffer(),
+ False );
+ XSendEvent( mpDisplay, maDragTarget, False,
+ NoEventMask, &aEvent );
+#if defined DEBUG
+ fprintf( stderr, "Sending XdndEnter\n" );
+#endif
+ }
+}
+
+void DtIntegrator::SendXdndPosition( XEvent* pEvent )
+{
+ static int nLastSendX = -1;
+ static int nLastSendY = -1;
+ static int nLastState = 0, nState = 0;
+
+ if( pEvent->type == ButtonPress || pEvent->type == ButtonRelease )
+ {
+ mnLastDragX = pEvent->xbutton.x_root;
+ mnLastDragY = pEvent->xbutton.y_root;
+ mnLastDragTimestamp = pEvent->xbutton.time;
+ nState = pEvent->xbutton.state;
+ }
+ else if( pEvent->type == MotionNotify )
+ {
+ mnLastDragX = pEvent->xmotion.x_root;
+ mnLastDragY = pEvent->xmotion.y_root;
+ mnLastDragTimestamp = pEvent->xmotion.time;
+ nState = pEvent->xmotion.state;
+ }
+ else if( pEvent->type == XLIB_KeyPress || pEvent->type == KeyRelease )
+ {
+ mnLastDragX = pEvent->xkey.x_root;
+ mnLastDragY = pEvent->xkey.y_root;
+ mnLastDragTimestamp = pEvent->xkey.time;
+ nState = pEvent->xkey.state;
+ }
+ if( maDragTarget != None &&
+ meDragState != DtWaitForStatus &&
+ meDragState != DtWaitForDataRequest &&
+ ( mnLastDragX != nLastSendX ||
+ mnLastDragY != nLastSendY ||
+ nState != nLastState )
+ )
+ {
+ nLastSendX = mnLastDragX;
+ nLastSendY = mnLastDragY;
+ nLastState = nState;
+
+ XEvent aEvent;
+ aEvent.type = ClientMessage;
+ aEvent.xclient.display = mpDisplay;
+ aEvent.xclient.window = maDragTarget;
+ aEvent.xclient.format = 32;
+ aEvent.xclient.message_type = mnXdndPosition;
+ aEvent.xclient.data.l[0] = maDragSource;
+ aEvent.xclient.data.l[1] = 0;
+ aEvent.xclient.data.l[2] =
+ ( mnLastDragX << 16 ) | ( mnLastDragY );
+ aEvent.xclient.data.l[3] = mnLastDragTimestamp;
+ // Insert correct DropAction here
+ if( nLastState & ( ShiftMask | ControlMask ) )
+ aEvent.xclient.data.l[4] = mnXdndActionLink;
+ else if( nLastState & ShiftMask )
+ aEvent.xclient.data.l[4] = mnXdndActionMove;
+ else if( nLastState & ControlMask )
+ aEvent.xclient.data.l[4] = mnXdndActionCopy;
+ else
+ aEvent.xclient.data.l[4] = mnXdndActionCopy;
+
+ XSendEvent( mpDisplay, maDragTarget, False,
+ NoEventMask, &aEvent );
+ meDragState = DtWaitForStatus;
+ mnWaitTimestamp = mnLastDragTimestamp;
+#if defined DEBUG
+ fprintf( stderr, "Sending XdndPosition\n" );
+#endif
+ }
+}
+
+void DtIntegrator::CheckXdndTimeout( int nTime )
+{
+ if( meDragState == DtWaitForDataRequest &&
+ ( nTime - mnWaitTimestamp > 5000 ||
+ mnWaitTimestamp > nTime ) )
+ {
+#if defined DEBUG
+ fprintf( stderr, "Timeout on DtWaitForRequestData\n" );
+#endif
+ maDragTarget = None;
+ maDragSource = None;
+ meDragState = DtDragNone;
+ }
+ else if( meDragState == DtWaitForStatus &&
+ ( nTime - mnWaitTimestamp > 5000 ||
+ mnWaitTimestamp > nTime ) )
+ {
+#if defined DEBUG
+ fprintf( stderr, "Timeout on DtWaitForStatus\n" );
+#endif
+ meDragState = DtDragging;
+ }
+}
+
+BOOL DtIntegrator::GetSystemLook( SystemLookInfo& rInfo )
+{
+ return FALSE;
+}
diff --git a/vcl/unx/source/gdi/makefile.mk b/vcl/unx/source/gdi/makefile.mk
new file mode 100644
index 000000000000..4fabb41d3d6a
--- /dev/null
+++ b/vcl/unx/source/gdi/makefile.mk
@@ -0,0 +1,124 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salgdi
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(OS)"=="MACOSX"
+
+dummy:
+ @echo "Nothing to build for Mac OS X"
+
+.ELSE # "$(OS)"=="MACOSX"
+
+.IF "$(remote)"==""
+SLOFILES= \
+ $(SLO)$/salgdi2.obj \
+ $(SLO)$/salbmp.obj \
+ $(SLO)$/salgdi.obj \
+ $(SLO)$/salvd.obj \
+ $(SLO)$/salprn.obj \
+ $(SLO)$/salogl.obj \
+ $(SLO)$/salpimpl.obj \
+ $(SLO)$/charnames.obj \
+ $(SLO)$/dtint.obj \
+ $(SLO)$/cdeint.obj \
+ $(SLO)$/kdeint.obj \
+ $(SLO)$/salconfig.obj \
+ $(SLO)$/salcvt.obj \
+ $(SLO)$/ansi1252.obj \
+ $(SLO)$/xfont.obj \
+ $(SLO)$/xlfd_attr.obj \
+ $(SLO)$/xlfd_extd.obj \
+ $(SLO)$/xlfd_smpl.obj \
+ $(SLO)$/salgdi3.obj
+
+.ENDIF
+
+.ENDIF # "$(OS)"=="MACOSX"
+
+# --- Targets ------------------------------------------------------
+
+ALL: $(INCCOM)$/rtsname.hxx ALLTAR
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
+
+XSALSETLIBNAME=libspa$(UPD)$(DLLPOSTFIX).so
+
+$(INCCOM)$/rtsname.hxx:
+ rm -f $(INCCOM)$/rtsname.hxx ; \
+ echo "#define _XSALSET_LIBNAME "\"$(XSALSETLIBNAME)\" > $(INCCOM)$/rtsname.hxx
+
+salpimpl.cxx: $(INCCOM)$/rtsname.hxx
diff --git a/vcl/unx/source/gdi/salbmp.cxx b/vcl/unx/source/gdi/salbmp.cxx
new file mode 100644
index 000000000000..bb0feb821a91
--- /dev/null
+++ b/vcl/unx/source/gdi/salbmp.cxx
@@ -0,0 +1,885 @@
+/*************************************************************************
+ *
+ * $RCSfile: salbmp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALBMP_CXX
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/shm.h>
+#include <prex.h>
+#include <postx.h>
+#include <salunx.h>
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define SAL_DRAWPIXMAP_MAX_EXT 4096
+
+// -------------
+// - SalBitmap -
+// -------------
+
+ImplSalBitmapCache* SalBitmap::mpCache = NULL;
+ULONG SalBitmap::mnCacheInstCount = 0;
+
+// -----------------------------------------------------------------------------
+
+SalBitmap::SalBitmap() :
+ mpDIB( NULL ),
+ mpDDB( NULL )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+SalBitmap::~SalBitmap()
+{
+ Destroy();
+}
+
+// -----------------------------------------------------------------------------
+
+void SalBitmap::ImplCreateCache()
+{
+ if( !mnCacheInstCount++ )
+ mpCache = new ImplSalBitmapCache;
+}
+
+// -----------------------------------------------------------------------------
+
+void SalBitmap::ImplDestroyCache()
+{
+ DBG_ASSERT( mnCacheInstCount, "SalBitmap::ImplDestroyCache(): underflow" );
+
+ if( mnCacheInstCount && !--mnCacheInstCount )
+ delete mpCache, mpCache = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void SalBitmap::ImplRemovedFromCache()
+{
+ if( mpDDB )
+ delete mpDDB, mpDDB = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+BitmapBuffer* SalBitmap::ImplCreateDIB( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal )
+{
+ DBG_ASSERT( nBitCount == 1 || nBitCount == 4 || nBitCount == 8 || nBitCount == 24, "Unsupported BitCount!" );
+
+ BitmapBuffer* pDIB;
+
+ if( rSize.Width() && rSize.Height() )
+ {
+ pDIB = new BitmapBuffer;
+
+ if( pDIB )
+ {
+ const USHORT nColors = ( nBitCount <= 8 ) ? ( 1 << nBitCount ) : 0;
+
+ pDIB->mnFormat = BMP_FORMAT_BOTTOM_UP;
+
+ switch( nBitCount )
+ {
+ case( 1 ): pDIB->mnFormat |= BMP_FORMAT_1BIT_MSB_PAL; break;
+ case( 4 ): pDIB->mnFormat |= BMP_FORMAT_4BIT_MSN_PAL; break;
+ case( 8 ): pDIB->mnFormat |= BMP_FORMAT_8BIT_PAL; break;
+
+ default:
+ pDIB->mnFormat |= BMP_FORMAT_24BIT_TC_BGR;
+ break;
+ }
+
+ pDIB->mnWidth = rSize.Width();
+ pDIB->mnHeight = rSize.Height();
+ pDIB->mnScanlineSize = AlignedWidth4Bytes( pDIB->mnWidth * nBitCount );
+ pDIB->mnBitCount = nBitCount;
+
+ if( nColors )
+ {
+ pDIB->maPalette = rPal;
+ pDIB->maPalette.SetEntryCount( nColors );
+ }
+
+ pDIB->mpBits = new BYTE[ pDIB->mnScanlineSize * pDIB->mnHeight ];
+ rtl_zeroMemory( pDIB->mpBits, pDIB->mnScanlineSize * pDIB->mnHeight );
+ }
+ }
+ else
+ pDIB = NULL;
+
+ return pDIB;
+}
+
+// -----------------------------------------------------------------------------
+
+BitmapBuffer* SalBitmap::ImplCreateDIB( Drawable aDrawable,
+ long nDrawableDepth,
+ long nX, long nY,
+ long nWidth, long nHeight )
+{
+ BitmapBuffer* pDIB = NULL;
+
+ if( aDrawable && nWidth && nHeight && nDrawableDepth )
+ {
+ SalDisplay* pSalDisp = GetSalData()->GetCurDisp();
+ SalXLib* pXLib = pSalDisp->GetXLib();
+ Display* pXDisp = pSalDisp->GetDisplay();
+
+ // do not die on XError here
+ // alternatively one could check the coordinates for being offscreen
+ // but this call can actually work on servers with backing store
+ // defaults even if the rectangle is offscreen
+ // so better catch the XError
+ BOOL bXError = pXLib->GetIgnoreXErrors();
+ pXLib->SetIgnoreXErrors( TRUE );
+ XImage* pImage = XGetImage( pXDisp, aDrawable, nX, nY, nWidth, nHeight, AllPlanes, ZPixmap );
+ BOOL bWasError = pXLib->WasXError();
+ pXLib->SetIgnoreXErrors( bXError );
+
+ if( ! bWasError && pImage && pImage->data )
+ {
+ const SalTwoRect aTwoRect = { 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight };
+ BitmapBuffer aSrcBuf;
+ ULONG nDstFormat = BMP_FORMAT_BOTTOM_UP;
+ const BitmapPalette* pDstPal = NULL;
+
+ aSrcBuf.mnFormat = BMP_FORMAT_TOP_DOWN;
+ aSrcBuf.mnWidth = nWidth;
+ aSrcBuf.mnHeight = nHeight;
+ aSrcBuf.mnBitCount = pImage->bits_per_pixel;
+ aSrcBuf.mnScanlineSize = pImage->bytes_per_line;
+ aSrcBuf.mpBits = (BYTE*) pImage->data;
+
+ pImage->red_mask = pSalDisp->GetVisual()->red_mask;
+ pImage->green_mask = pSalDisp->GetVisual()->green_mask;
+ pImage->blue_mask = pSalDisp->GetVisual()->blue_mask;
+
+ switch( aSrcBuf.mnBitCount )
+ {
+ case( 1 ):
+ {
+ aSrcBuf.mnFormat |= ( LSBFirst == pImage->bitmap_bit_order ? BMP_FORMAT_1BIT_LSB_PAL : BMP_FORMAT_1BIT_MSB_PAL );
+ nDstFormat |= BMP_FORMAT_1BIT_MSB_PAL;
+ }
+ break;
+
+ case( 4 ):
+ {
+ aSrcBuf.mnFormat |= ( LSBFirst == pImage->bitmap_bit_order ? BMP_FORMAT_4BIT_LSN_PAL : BMP_FORMAT_4BIT_MSN_PAL );
+ nDstFormat |= BMP_FORMAT_4BIT_MSN_PAL;
+ }
+ break;
+
+ case( 8 ):
+ {
+ aSrcBuf.mnFormat |= BMP_FORMAT_8BIT_PAL;
+ nDstFormat |= BMP_FORMAT_8BIT_PAL;
+ }
+ break;
+
+ case( 16 ):
+ {
+ aSrcBuf.mnFormat |= BMP_FORMAT_16BIT_TC_MASK;
+ nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
+
+ if( LSBFirst == pImage->byte_order )
+ aSrcBuf.maColorMask = ColorMask( pImage->red_mask, pImage->green_mask, pImage->blue_mask );
+ else
+ aSrcBuf.maColorMask = ColorMask( SWAPSHORT( pImage->red_mask ), SWAPSHORT( pImage->green_mask ), SWAPSHORT( pImage->blue_mask ) );
+ }
+ break;
+
+ case( 24 ):
+ {
+ if( ( LSBFirst == pImage->byte_order ) && ( pImage->red_mask == 0xFF ) )
+ aSrcBuf.mnFormat |= BMP_FORMAT_24BIT_TC_RGB;
+ else
+ aSrcBuf.mnFormat |= BMP_FORMAT_24BIT_TC_BGR;
+
+ nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
+ }
+ break;
+
+ case( 32 ):
+ {
+ if( LSBFirst == pImage->byte_order )
+ aSrcBuf.mnFormat |= ( pSalDisp->GetVisual()->red_mask == 0xFF ? BMP_FORMAT_32BIT_TC_RGBA : BMP_FORMAT_32BIT_TC_BGRA );
+ else
+ aSrcBuf.mnFormat |= ( pSalDisp->GetVisual()->red_mask == 0xFF ? BMP_FORMAT_32BIT_TC_ABGR : BMP_FORMAT_32BIT_TC_ARGB );
+
+ nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
+ }
+ break;
+ }
+
+ BitmapPalette& rPal = aSrcBuf.maPalette;
+
+ if( aSrcBuf.mnBitCount == 1 )
+ {
+ rPal.SetEntryCount( 2 );
+ pDstPal = &rPal;
+
+ rPal[ 0 ] = Color( COL_BLACK );
+ rPal[ 1 ] = Color( COL_WHITE );
+ }
+ else if( aSrcBuf.mnBitCount <= 8 )
+ {
+ SalColormap& rColMap = pSalDisp->GetColormap();
+ const USHORT nCols = Min( (USHORT)rColMap.GetUsed(), 1 << nDrawableDepth );
+
+ rPal.SetEntryCount( nCols );
+ pDstPal = &rPal;
+
+ for( USHORT i = 0; i < nCols; i++ )
+ {
+ const SalColor nColor( rColMap.GetColor( i ) );
+ BitmapColor& rBmpCol = rPal[ i ];
+
+ rBmpCol.SetRed( SALCOLOR_RED( nColor ) );
+ rBmpCol.SetGreen( SALCOLOR_GREEN( nColor ) );
+ rBmpCol.SetBlue( SALCOLOR_BLUE( nColor ) );
+ }
+ }
+
+ pDIB = StretchAndConvert( aSrcBuf, aTwoRect, nDstFormat, const_cast<BitmapPalette*>(pDstPal) );
+ XDestroyImage( pImage );
+ }
+ }
+
+ return pDIB;
+}
+
+// -----------------------------------------------------------------------------
+
+XImage* SalBitmap::ImplCreateXImage( SalDisplay *pSalDisp, long nDepth, const SalTwoRect& rTwoRect ) const
+{
+ XImage* pImage = NULL;
+
+ if( !mpDIB && mpDDB )
+ {
+ ( (SalBitmap*) this )->mpDIB = ImplCreateDIB( mpDDB->ImplGetPixmap(),
+ mpDDB->ImplGetDepth(),
+ 0, 0,
+ mpDDB->ImplGetWidth(),
+ mpDDB->ImplGetHeight() );
+ }
+
+ if( mpDIB && mpDIB->mnWidth && mpDIB->mnHeight )
+ {
+ Display* pXDisp = pSalDisp->GetDisplay();
+ long nWidth = rTwoRect.mnDestWidth;
+ long nHeight = rTwoRect.mnDestHeight;
+
+ if( 1 == GetBitCount() )
+ nDepth = 1;
+
+ pImage = XCreateImage( pXDisp, pSalDisp->GetVisual()->GetVisual(),
+ nDepth, ( 1 == nDepth ) ? XYBitmap :ZPixmap, 0, NULL,
+ nWidth, nHeight, 32, 0 );
+
+ if( pImage )
+ {
+ BitmapBuffer* pDstBuf;
+ ULONG nDstFormat = BMP_FORMAT_TOP_DOWN;
+ BitmapPalette* pPal = NULL;
+ ColorMask* pMask = NULL;
+
+ switch( pImage->bits_per_pixel )
+ {
+ case( 1 ):
+ nDstFormat |= ( LSBFirst == pImage->bitmap_bit_order ? BMP_FORMAT_1BIT_LSB_PAL : BMP_FORMAT_1BIT_MSB_PAL );
+ break;
+
+ case( 4 ):
+ nDstFormat |= ( LSBFirst == pImage->bitmap_bit_order ? BMP_FORMAT_4BIT_LSN_PAL : BMP_FORMAT_4BIT_MSN_PAL );
+ break;
+
+ case( 8 ):
+ nDstFormat |= BMP_FORMAT_8BIT_PAL;
+ break;
+
+ case( 16 ):
+ {
+ nDstFormat |= BMP_FORMAT_16BIT_TC_MASK;
+
+ if( LSBFirst == pImage->byte_order )
+ pMask = new ColorMask( pImage->red_mask, pImage->green_mask, pImage->blue_mask );
+ else
+ pMask = new ColorMask( SWAPSHORT( pImage->red_mask ), SWAPSHORT( pImage->green_mask ), SWAPSHORT( pImage->blue_mask ) );
+ }
+ break;
+
+ case( 24 ):
+ {
+ if( ( LSBFirst == pImage->byte_order ) && ( pImage->red_mask == 0xFF ) )
+ nDstFormat |= BMP_FORMAT_24BIT_TC_RGB;
+ else
+ nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
+ }
+ break;
+
+ case( 32 ):
+ {
+ if( LSBFirst == pImage->byte_order )
+ nDstFormat |= ( pImage->red_mask == 0xFF ? BMP_FORMAT_32BIT_TC_RGBA : BMP_FORMAT_32BIT_TC_BGRA );
+ else
+ nDstFormat |= ( pImage->red_mask == 0xFF ? BMP_FORMAT_32BIT_TC_ABGR : BMP_FORMAT_32BIT_TC_ARGB );
+ }
+ break;
+ }
+
+ if( pImage->depth == 1 )
+ {
+ pPal = new BitmapPalette( 2 );
+ (*pPal)[ 0 ] = Color( COL_BLACK );
+ (*pPal)[ 1 ] = Color( COL_WHITE );
+ }
+ else if( pImage->depth <= 8 )
+ {
+ SalColormap& rColMap = pSalDisp->GetColormap();
+ const USHORT nCols = Min( (USHORT)rColMap.GetUsed(), 1 << pImage->depth );
+
+ pPal = new BitmapPalette( nCols );
+
+ for( USHORT i = 0; i < nCols; i++ )
+ {
+ const SalColor nColor( rColMap.GetColor( i ) );
+ BitmapColor& rBmpCol = (*pPal)[ i ];
+
+ rBmpCol.SetRed( SALCOLOR_RED( nColor ) );
+ rBmpCol.SetGreen( SALCOLOR_GREEN( nColor ) );
+ rBmpCol.SetBlue( SALCOLOR_BLUE( nColor ) );
+ }
+ }
+
+ pDstBuf = StretchAndConvert( *mpDIB, rTwoRect, nDstFormat, pPal, pMask );
+ delete pPal;
+ delete pMask;
+
+ if( pDstBuf && pDstBuf->mpBits )
+ {
+ // set data in buffer as data member in pImage
+ pImage->data = (char*) pDstBuf->mpBits;
+
+ // destroy buffer; don't destroy allocated data in buffer
+ delete pDstBuf;
+ }
+ else
+ {
+ XDestroyImage( pImage );
+ pImage = NULL;
+ }
+ }
+ }
+
+ return pImage;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL SalBitmap::ImplCreateFromDrawable( Drawable aDrawable, long nDrawableDepth,
+ long nX, long nY, long nWidth, long nHeight )
+{
+ Destroy();
+
+ if( aDrawable && nWidth && nHeight && nDrawableDepth )
+ mpDDB = new ImplSalDDB( aDrawable, nDrawableDepth, nX, nY, nWidth, nHeight );
+
+ return( mpDDB != NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+void SalBitmap::ImplDraw( Drawable aDrawable, long nDrawableDepth,
+ const SalTwoRect& rTwoRect, const GC& rGC ) const
+{
+ if( !mpDDB || !mpDDB->ImplMatches( nDrawableDepth, rTwoRect ) )
+ {
+ if( mpDDB )
+ {
+ // do we already have a DIB? if not, create aDIB from current DDB first
+ if( !mpDIB )
+ {
+ ( (SalBitmap*) this )->mpDIB = ImplCreateDIB( mpDDB->ImplGetPixmap(),
+ mpDDB->ImplGetDepth(),
+ 0, 0,
+ mpDDB->ImplGetWidth(),
+ mpDDB->ImplGetHeight() );
+ }
+
+ delete mpDDB, ( (SalBitmap*) this )->mpDDB = NULL;
+ }
+
+ if( mpCache )
+ mpCache->ImplRemove( const_cast<SalBitmap*>(this) );
+
+ SalTwoRect aTwoRect( rTwoRect );
+
+ // create new DDB from DIB
+ if( aTwoRect.mnSrcWidth == aTwoRect.mnDestWidth &&
+ aTwoRect.mnSrcHeight == aTwoRect.mnDestHeight )
+ {
+ const Size aSize( GetSize() );
+
+ aTwoRect.mnSrcX = aTwoRect.mnSrcY = aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
+ aTwoRect.mnSrcWidth = aTwoRect.mnDestWidth = aSize.Width();
+ aTwoRect.mnSrcHeight = aTwoRect.mnDestHeight = aSize.Height();
+ }
+
+ XImage* pImage = ImplCreateXImage( GetSalData()->GetCurDisp(),
+ nDrawableDepth, aTwoRect );
+
+ if( pImage )
+ {
+ ( (SalBitmap*) this )->mpDDB = new ImplSalDDB( pImage, aDrawable, aTwoRect );
+ delete[] pImage->data, pImage->data = NULL;
+ XDestroyImage( pImage );
+
+ if( mpCache )
+ mpCache->ImplAdd( const_cast<SalBitmap*>(this), mpDDB->ImplGetMemSize() );
+ }
+ }
+
+ if( mpDDB )
+ mpDDB->ImplDraw( aDrawable, nDrawableDepth, rTwoRect, rGC );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal )
+{
+ Destroy();
+ mpDIB = ImplCreateDIB( rSize, nBitCount, rPal );
+
+ return( mpDIB != NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp )
+{
+ Destroy();
+
+ if( rSalBmp.mpDIB )
+ {
+ const Size aSize( rSalBmp.GetSize() );
+
+ mpDIB = ImplCreateDIB( rSalBmp.GetSize(), rSalBmp.GetBitCount(), rSalBmp.mpDIB->maPalette );
+
+ if( mpDIB )
+ memcpy( mpDIB->mpBits, rSalBmp.mpDIB->mpBits, mpDIB->mnScanlineSize * mpDIB->mnHeight );
+ }
+ else
+ {
+ DBG_ASSERT( !rSalBmp.mpDDB, "trying to copy construct SalBitmap with DDB => NYI" );
+ }
+
+ return( !rSalBmp.mpDIB || ( mpDIB != NULL ) );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, USHORT nNewBitCount )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void SalBitmap::Destroy()
+{
+ if( mpDIB )
+ {
+ delete[] mpDIB->mpBits;
+ delete mpDIB, mpDIB = NULL;
+ }
+
+ if( mpDDB )
+ delete mpDDB, mpDDB = NULL;
+
+ if( mpCache )
+ mpCache->ImplRemove( this );
+}
+
+// -----------------------------------------------------------------------------
+
+Size SalBitmap::GetSize() const
+{
+ Size aSize;
+
+ if( mpDIB )
+ aSize.Width() = mpDIB->mnWidth, aSize.Height() = mpDIB->mnHeight;
+ else if( mpDDB )
+ aSize.Width() = mpDDB->ImplGetWidth(), aSize.Height() = mpDDB->ImplGetHeight();
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------------
+
+USHORT SalBitmap::GetBitCount() const
+{
+ USHORT nBitCount;
+
+ if( mpDIB )
+ nBitCount = mpDIB->mnBitCount;
+ else if( mpDDB )
+ {
+ nBitCount = mpDDB->ImplGetDepth();
+
+ if( nBitCount && nBitCount > 1 )
+ {
+ if( nBitCount <= 4 )
+ nBitCount = 4;
+ else if( nBitCount <= 8 )
+ nBitCount = 8;
+ else
+ nBitCount = 24;
+ }
+ }
+ else
+ nBitCount = 0;
+
+ return nBitCount;
+}
+
+// -----------------------------------------------------------------------------
+
+BitmapBuffer* SalBitmap::AcquireBuffer( BOOL bReadOnly )
+{
+ if( !mpDIB && mpDDB )
+ {
+ mpDIB = ImplCreateDIB( mpDDB->ImplGetPixmap(), mpDDB->ImplGetDepth(),
+ 0, 0, mpDDB->ImplGetWidth(), mpDDB->ImplGetHeight() );
+ }
+
+ return mpDIB;
+}
+
+// -----------------------------------------------------------------------------
+
+void SalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BOOL bReadOnly )
+{
+ if( !bReadOnly )
+ {
+ if( mpDDB )
+ delete mpDDB, mpDDB = NULL;
+
+ if( mpCache )
+ mpCache->ImplRemove( this );
+ }
+}
+
+// --------------
+// - ImplSalDDB -
+// --------------
+
+ImplSalDDB::ImplSalDDB( XImage* pImage, Drawable aDrawable, const SalTwoRect& rTwoRect ) :
+ maPixmap ( 0 ),
+ maTwoRect ( rTwoRect ),
+ mnDepth ( pImage->depth )
+{
+ SalDisplay* pSalDisp = GetSalData()->GetCurDisp();
+ Display* pXDisp = pSalDisp->GetDisplay();
+
+ if( maPixmap = XCreatePixmap( pXDisp, aDrawable, ImplGetWidth(), ImplGetHeight(), ImplGetDepth() ) )
+ {
+ XGCValues aValues;
+ GC aGC;
+ int nValues = GCFunction;
+
+ aValues.function = GXcopy;
+
+ if( 1 == mnDepth )
+ {
+ nValues |= ( GCForeground | GCBackground );
+ aValues.foreground = 1, aValues.background = 0;
+ }
+
+ aGC = XCreateGC( pXDisp, maPixmap, nValues, &aValues );
+ XPutImage( pXDisp, maPixmap, aGC, pImage, 0, 0, 0, 0, maTwoRect.mnDestWidth, maTwoRect.mnDestHeight );
+ XFreeGC( pXDisp, aGC );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+ImplSalDDB::ImplSalDDB( Drawable aDrawable, long nDrawableDepth, long nX, long nY, long nWidth, long nHeight ) :
+ mnDepth( nDrawableDepth )
+{
+ SalDisplay* pSalDisp = GetSalData()->GetCurDisp();
+ Display* pXDisp = pSalDisp->GetDisplay();
+
+ if( maPixmap = XCreatePixmap( pXDisp, aDrawable, nWidth, nHeight, nDrawableDepth ) )
+ {
+ XGCValues aValues;
+ GC aGC;
+ int nValues = GCFunction;
+
+ aValues.function = GXcopy;
+
+ if( 1 == mnDepth )
+ {
+ nValues |= ( GCForeground | GCBackground );
+ aValues.foreground = 1, aValues.background = 0;
+ }
+
+ aGC = XCreateGC( pXDisp, maPixmap, nValues, &aValues );
+ ImplDraw( aDrawable, nDrawableDepth, maPixmap, mnDepth,
+ nX, nY, nWidth, nHeight, 0, 0, aGC );
+ XFreeGC( pXDisp, aGC );
+
+ maTwoRect.mnSrcX = maTwoRect.mnSrcY = maTwoRect.mnDestX = maTwoRect.mnDestY = 0;
+ maTwoRect.mnSrcWidth = maTwoRect.mnDestWidth = nWidth;
+ maTwoRect.mnSrcHeight = maTwoRect.mnDestHeight = nHeight;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+ImplSalDDB::~ImplSalDDB()
+{
+ if( maPixmap && ImplGetSVData() )
+ XFreePixmap( GetSalData()->GetCurDisp()->GetDisplay(), maPixmap );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ImplSalDDB::ImplMatches( long nDepth, const SalTwoRect& rTwoRect ) const
+{
+ BOOL bRet = FALSE;
+
+ if( ( maPixmap != 0 ) && ( ( mnDepth == nDepth ) || ( 1 == mnDepth ) ) )
+ {
+ if( rTwoRect.mnSrcX == maTwoRect.mnSrcX && rTwoRect.mnSrcY == maTwoRect.mnSrcY &&
+ rTwoRect.mnSrcWidth == maTwoRect.mnSrcWidth && rTwoRect.mnSrcHeight == maTwoRect.mnSrcHeight &&
+ rTwoRect.mnDestWidth == maTwoRect.mnDestWidth && rTwoRect.mnDestHeight == maTwoRect.mnDestHeight )
+ {
+ // absolutely indentically
+ bRet = TRUE;
+ }
+ else if( rTwoRect.mnSrcWidth == rTwoRect.mnDestWidth && rTwoRect.mnSrcHeight == rTwoRect.mnDestHeight &&
+ maTwoRect.mnSrcWidth == maTwoRect.mnDestWidth && maTwoRect.mnSrcHeight == maTwoRect.mnDestHeight &&
+ rTwoRect.mnSrcX >= maTwoRect.mnSrcX && rTwoRect.mnSrcY >= maTwoRect.mnSrcY &&
+ ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) <= ( maTwoRect.mnSrcX + maTwoRect.mnSrcWidth ) &&
+ ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) <= ( maTwoRect.mnSrcY + maTwoRect.mnSrcHeight ) )
+ {
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplSalDDB::ImplDraw( Drawable aDrawable, long nDrawableDepth, const SalTwoRect& rTwoRect, const GC& rGC ) const
+{
+ ImplDraw( maPixmap, mnDepth, aDrawable, nDrawableDepth,
+ rTwoRect.mnSrcX - maTwoRect.mnSrcX, rTwoRect.mnSrcY - maTwoRect.mnSrcY,
+ rTwoRect.mnDestWidth, rTwoRect.mnDestHeight,
+ rTwoRect.mnDestX, rTwoRect.mnDestY, rGC );
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplSalDDB::ImplDraw( Drawable aSrcDrawable, long nSrcDrawableDepth,
+ Drawable aDstDrawable, long nDstDrawableDepth,
+ long nSrcX, long nSrcY,
+ long nDestWidth, long nDestHeight,
+ long nDestX, long nDestY, const GC& rGC )
+{
+ SalDisplay* pSalDisp = GetSalData()->GetCurDisp();
+ Display* pXDisp = pSalDisp->GetDisplay();
+
+ if( 1 == nSrcDrawableDepth )
+ {
+ XCopyPlane( pXDisp, aSrcDrawable, aDstDrawable, rGC,
+ nSrcX, nSrcY, nDestWidth, nDestHeight, nDestX, nDestY, 1 );
+ }
+ else
+ {
+ if( nDestWidth > SAL_DRAWPIXMAP_MAX_EXT )
+ {
+ // !!! Broken XCopyArea
+ XCopyArea( pXDisp, aSrcDrawable, aDstDrawable, rGC,
+ nSrcX, nSrcY, nDestWidth, nDestHeight, nDestX, nDestY );
+ }
+ else
+ {
+ XCopyArea( pXDisp, aSrcDrawable, aDstDrawable, rGC,
+ nSrcX, nSrcY, nDestWidth, nDestHeight, nDestX, nDestY );
+ }
+ }
+}
+
+// ----------------------
+// - ImplSalBitmapCache -
+// ----------------------
+
+struct ImplBmpObj
+{
+ SalBitmap* mpBmp;
+ ULONG mnMemSize;
+ ULONG mnFlags;
+
+ ImplBmpObj( SalBitmap* pBmp, ULONG nMemSize, ULONG nFlags ) :
+ mpBmp( pBmp ), mnMemSize( nMemSize ), mnFlags( nFlags ) {}
+};
+
+// -----------------------------------------------------------------------------
+
+ImplSalBitmapCache::ImplSalBitmapCache() :
+ mnTotalSize( 0UL )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ImplSalBitmapCache::~ImplSalBitmapCache()
+{
+ ImplClear();
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplSalBitmapCache::ImplAdd( SalBitmap* pBmp, ULONG nMemSize, ULONG nFlags )
+{
+ ImplBmpObj* pObj;
+ BOOL bFound = FALSE;
+
+ for( pObj = (ImplBmpObj*) maBmpList.Last(); pObj && !bFound; pObj = (ImplBmpObj*) maBmpList.Prev() )
+ if( pObj->mpBmp == pBmp )
+ bFound = TRUE;
+
+ mnTotalSize += nMemSize;
+
+ if( bFound )
+ {
+ mnTotalSize -= pObj->mnMemSize;
+ pObj->mnMemSize = nMemSize, pObj->mnFlags = nFlags;
+ }
+ else
+ maBmpList.Insert( new ImplBmpObj( pBmp, nMemSize, nFlags ), LIST_APPEND );
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplSalBitmapCache::ImplRemove( SalBitmap* pBmp )
+{
+ for( ImplBmpObj* pObj = (ImplBmpObj*) maBmpList.Last(); pObj; pObj = (ImplBmpObj*) maBmpList.Prev() )
+ {
+ if( pObj->mpBmp == pBmp )
+ {
+ maBmpList.Remove( pObj );
+ pObj->mpBmp->ImplRemovedFromCache();
+ mnTotalSize -= pObj->mnMemSize;
+ delete pObj;
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplSalBitmapCache::ImplClear()
+{
+ for( ImplBmpObj* pObj = (ImplBmpObj*) maBmpList.First(); pObj; pObj = (ImplBmpObj*) maBmpList.Next() )
+ {
+ pObj->mpBmp->ImplRemovedFromCache();
+ delete pObj;
+ }
+
+ maBmpList.Clear();
+ mnTotalSize = 0;
+}
diff --git a/vcl/unx/source/gdi/salcvt.cxx b/vcl/unx/source/gdi/salcvt.cxx
new file mode 100644
index 000000000000..49359471a25f
--- /dev/null
+++ b/vcl/unx/source/gdi/salcvt.cxx
@@ -0,0 +1,434 @@
+/*************************************************************************
+ *
+ * $RCSfile: salcvt.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef SAL_CONVERTER_CACHE_HXX_
+#include "salcvt.hxx"
+#endif
+
+
+SalConverterCache::SalConverterCache()
+{
+ mpConverter = (ConverterT*)calloc( sizeof(ConverterT), RTL_TEXTENCODING_STD_COUNT );
+}
+
+SalConverterCache::~SalConverterCache()
+{
+ for ( int i = 0; i < RTL_TEXTENCODING_STD_COUNT; i++ )
+ {
+ if ( mpConverter[i].mpU2T != NULL )
+ rtl_destroyUnicodeToTextConverter( mpConverter[i].mpU2T );
+ if ( mpConverter[i].mpT2U != NULL )
+ rtl_destroyTextToUnicodeConverter( mpConverter[i].mpT2U );
+ }
+ free( mpConverter );
+}
+
+// ---> FIXME
+#include <stdio.h>
+// <---
+
+rtl_UnicodeToTextConverter
+SalConverterCache::GetU2TConverter( rtl_TextEncoding nEncoding )
+{
+ if ( nEncoding < RTL_TEXTENCODING_STD_COUNT )
+ {
+ if ( mpConverter[ nEncoding ].mpU2T == NULL )
+ {
+ mpConverter[ nEncoding ].mpU2T =
+ rtl_createUnicodeToTextConverter( nEncoding );
+// ---> FIXME
+if ( mpConverter[ nEncoding ].mpU2T == NULL )
+ fprintf( stderr, "failed to create Unicode -> %s converter\n",
+ pGetEncodingName(nEncoding) );
+// <---
+ }
+ return mpConverter[ nEncoding ].mpU2T;
+ }
+ return NULL;
+}
+
+rtl_TextToUnicodeConverter
+SalConverterCache::GetT2UConverter( rtl_TextEncoding nEncoding )
+{
+ if ( nEncoding < RTL_TEXTENCODING_STD_COUNT )
+ {
+ if ( mpConverter[ nEncoding ].mpT2U == NULL )
+ {
+ mpConverter[ nEncoding ].mpT2U =
+ rtl_createTextToUnicodeConverter( nEncoding );
+// ---> FIXME
+if ( mpConverter[ nEncoding ].mpT2U == NULL )
+ fprintf( stderr, "failed to create %s -> Unicode converter\n",
+ pGetEncodingName(nEncoding) );
+// <---
+ }
+ return mpConverter[ nEncoding ].mpT2U;
+ }
+ return NULL;
+}
+
+Bool
+SalConverterCache::IsSingleByteEncoding( rtl_TextEncoding nEncoding )
+{
+ if ( nEncoding < RTL_TEXTENCODING_STD_COUNT )
+ {
+ if ( ! mpConverter[ nEncoding ].mbValid )
+ {
+ mpConverter[ nEncoding ].mbValid = True;
+
+ rtl_TextEncodingInfo aTextEncInfo;
+ aTextEncInfo.StructSize = sizeof( aTextEncInfo );
+ rtl_getTextEncodingInfo( nEncoding, &aTextEncInfo );
+
+ if ( aTextEncInfo.MinimumCharSize == aTextEncInfo.MaximumCharSize
+ && aTextEncInfo.MinimumCharSize == 1)
+ mpConverter[ nEncoding ].mbSingleByteEncoding = True;
+ else
+ mpConverter[ nEncoding ].mbSingleByteEncoding = False;
+ }
+
+ return mpConverter[ nEncoding ].mbSingleByteEncoding;
+ }
+ return False;
+}
+
+// check whether the character set nEncoding contains the unicode
+// code point nChar. This list has been compiled from the according
+// ttmap files in /usr/openwin/lib/X11/fonts/TrueType/ttmap/
+Bool
+SalConverterCache::EncodingHasChar( rtl_TextEncoding nEncoding,
+ sal_Unicode nChar )
+{
+ Bool bMatch = False;
+
+ switch ( nEncoding )
+ {
+ case RTL_TEXTENCODING_DONTKNOW:
+ bMatch = False;
+ break;
+
+ case RTL_TEXTENCODING_MS_1252:
+ case RTL_TEXTENCODING_ISO_8859_1:
+ bMatch = ( nChar >= 0x0000 && nChar <= 0x00ff );
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_2:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x017e )
+ || ( nChar >= 0x02c7 && nChar <= 0x02dd );
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_4:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x017e )
+ || ( nChar >= 0x02c7 && nChar <= 0x02db );
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_5:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x00ad )
+ || ( nChar >= 0x0401 && nChar <= 0x045f )
+ || ( nChar == 0x2116 );
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_6:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x0600 && nChar <= 0x06ff )
+ || ( nChar >= 0xfb50 && nChar <= 0xfffe );
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_7:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x00bd )
+ || ( nChar == 0x02bd )
+ || ( nChar >= 0x0384 && nChar <= 0x03ce )
+ || ( nChar >= 0x2014 && nChar <= 0x2019 );
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_8:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x00f7 )
+ || ( nChar >= 0x05d0 && nChar <= 0x05ea )
+ || ( nChar == 0x2017 );
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_9:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x015f );
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_13:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x017e )
+ || ( nChar >= 0x2019 && nChar <= 0x201e );
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_15:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x00ff )
+ || ( nChar >= 0x0152 && nChar <= 0x017e )
+ || ( nChar >= 0x20ac && nChar <= 0x20ac );
+ break;
+
+ case RTL_TEXTENCODING_JIS_X_0201:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0xff61 && nChar <= 0xff9f );
+ break;
+
+ case RTL_TEXTENCODING_MS_1251:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x00bb )
+ || ( nChar >= 0x0401 && nChar <= 0x045f )
+ || ( nChar >= 0x0490 && nChar <= 0x0491 )
+ || ( nChar >= 0x2013 && nChar <= 0x203a )
+ || ( nChar >= 0x2116 && nChar <= 0x2122 )
+ || ( nChar == 0xfffe );
+ break;
+
+ case RTL_TEXTENCODING_KOI8_R:
+ bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
+ || ( nChar >= 0x00a0 && nChar <= 0x00b7 )
+ || ( nChar == 0x00f7 )
+ || ( nChar >= 0x0401 && nChar <= 0x0451 )
+ || ( nChar >= 0x2219 && nChar <= 0x221a )
+ || ( nChar >= 0x2248 && nChar <= 0x2265 )
+ || ( nChar >= 0x2320 && nChar <= 0x2321 )
+ || ( nChar >= 0x2500 && nChar <= 0x25a0 );
+ break;
+
+ case RTL_TEXTENCODING_UNICODE:
+ bMatch = True;
+ break;
+
+ default:
+ // XXX really convert the unicode char into the encoding
+ // and check for conversion errors, this is expensive !
+ rtl_UnicodeToTextConverter aConverter;
+ rtl_UnicodeToTextContext aContext;
+
+ aConverter = GetU2TConverter(nEncoding);
+ aContext = rtl_createUnicodeToTextContext( aConverter );
+
+ // ---> FIXME
+ if ( aConverter == NULL )
+ return False;
+ // <---
+
+ sal_Char pConversionBuffer[ 32 ];
+ sal_uInt32 nConversionInfo;
+ sal_Size nConvertedChars;
+ sal_uInt32 nCodePoint;
+ sal_Size nSize;
+
+ nSize = rtl_convertUnicodeToText( aConverter, aContext,
+ &nChar, 1, pConversionBuffer, sizeof(pConversionBuffer),
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR,
+ &nConversionInfo, &nConvertedChars );
+
+ rtl_destroyUnicodeToTextContext( aConverter, aContext );
+
+ bMatch = (nConvertedChars == 1)
+ && (nSize == 1 || nSize == 2) // XXX Fix me this is a hack
+ && ((nConversionInfo & RTL_UNICODETOTEXT_INFO_ERROR) == 0);
+ break;
+ }
+
+ return bMatch;
+}
+
+// wrapper for rtl_convertUnicodeToText that handles the usual cases for
+// textconversion in drawtext and gettextwidth routines
+sal_Size
+ConvertStringUTF16( const sal_Unicode *pText, int nTextLen,
+ sal_Char *pBuffer, sal_Size nBufferSize,
+ rtl_UnicodeToTextConverter aConverter )
+{
+ const sal_uInt32 nCvtFlags =
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_QUESTIONMARK
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_QUESTIONMARK ;
+ sal_uInt32 nCvtInfo;
+ sal_Size nCvtChars;
+
+ rtl_UnicodeToTextContext aContext =
+ rtl_createUnicodeToTextContext( aConverter );
+
+ sal_Size nSize = rtl_convertUnicodeToText( aConverter, aContext,
+ pText, nTextLen, pBuffer, nBufferSize,
+ nCvtFlags, &nCvtInfo, &nCvtChars );
+
+ rtl_destroyUnicodeToTextContext( aConverter, aContext );
+
+ return nSize;
+}
+
+typedef struct {
+ const rtl_TextEncoding nEncoding;
+ const char* pEncoding;
+} DescriptionT;
+
+const DescriptionT pRTLEncoding[] = {
+ { RTL_TEXTENCODING_DONTKNOW, "DONTKNOW" },
+ { RTL_TEXTENCODING_MS_1252, "MS_1252" },
+ { RTL_TEXTENCODING_APPLE_ROMAN, "APPLE_ROMAN" },
+ { RTL_TEXTENCODING_IBM_437, "IBM_437" },
+ { RTL_TEXTENCODING_IBM_850, "IBM_850" },
+ { RTL_TEXTENCODING_IBM_860, "IBM_860" },
+ { RTL_TEXTENCODING_IBM_861, "IBM_861" },
+ { RTL_TEXTENCODING_IBM_863, "IBM_863" },
+ { RTL_TEXTENCODING_IBM_865, "IBM_865" },
+ { RTL_TEXTENCODING_SYMBOL, "SYMBOL" },
+ { RTL_TEXTENCODING_ASCII_US, "ASCII_US" },
+ { RTL_TEXTENCODING_ISO_8859_1, "ISO_8859_1" },
+ { RTL_TEXTENCODING_ISO_8859_2, "ISO_8859_2" },
+ { RTL_TEXTENCODING_ISO_8859_3, "ISO_8859_3" },
+ { RTL_TEXTENCODING_ISO_8859_4, "ISO_8859_4" },
+ { RTL_TEXTENCODING_ISO_8859_5, "ISO_8859_5" },
+ { RTL_TEXTENCODING_ISO_8859_6, "ISO_8859_6" },
+ { RTL_TEXTENCODING_ISO_8859_7, "ISO_8859_7" },
+ { RTL_TEXTENCODING_ISO_8859_8, "ISO_8859_8" },
+ { RTL_TEXTENCODING_ISO_8859_9, "ISO_8859_9" },
+ { RTL_TEXTENCODING_ISO_8859_14, "ISO_8859_14" },
+ { RTL_TEXTENCODING_ISO_8859_15, "ISO_8859_15" },
+ { RTL_TEXTENCODING_IBM_737, "IBM_737" },
+ { RTL_TEXTENCODING_IBM_775, "IBM_775" },
+ { RTL_TEXTENCODING_IBM_852, "IBM_852" },
+ { RTL_TEXTENCODING_IBM_855, "IBM_855" },
+ { RTL_TEXTENCODING_IBM_857, "IBM_857" },
+ { RTL_TEXTENCODING_IBM_862, "IBM_862" },
+ { RTL_TEXTENCODING_IBM_864, "IBM_864" },
+ { RTL_TEXTENCODING_IBM_866, "IBM_866" },
+ { RTL_TEXTENCODING_IBM_869, "IBM_869" },
+ { RTL_TEXTENCODING_MS_874, "MS_874" },
+ { RTL_TEXTENCODING_MS_1250, "MS_1250" },
+ { RTL_TEXTENCODING_MS_1251, "MS_1251" },
+ { RTL_TEXTENCODING_MS_1253, "MS_1253" },
+ { RTL_TEXTENCODING_MS_1254, "MS_1254" },
+ { RTL_TEXTENCODING_MS_1255, "MS_1255" },
+ { RTL_TEXTENCODING_MS_1256, "MS_1256" },
+ { RTL_TEXTENCODING_MS_1257, "MS_1257" },
+ { RTL_TEXTENCODING_MS_1258, "MS_1258" },
+ { RTL_TEXTENCODING_APPLE_ARABIC, "APPLE_ARABIC" },
+ { RTL_TEXTENCODING_APPLE_CENTEURO, "APPLE_CENTEURO" },
+ { RTL_TEXTENCODING_APPLE_CROATIAN, "APPLE_CROATIAN" },
+ { RTL_TEXTENCODING_APPLE_CYRILLIC, "APPLE_CYRILLIC" },
+ { RTL_TEXTENCODING_APPLE_DEVANAGARI,"APPLE_DEVANAGARI" },
+ { RTL_TEXTENCODING_APPLE_FARSI, "APPLE_FARSI" },
+ { RTL_TEXTENCODING_APPLE_GREEK, "APPLE_GREEK" },
+ { RTL_TEXTENCODING_APPLE_GUJARATI, "APPLE_GUJARATI" },
+ { RTL_TEXTENCODING_APPLE_GURMUKHI, "APPLE_GURMUKHI" },
+ { RTL_TEXTENCODING_APPLE_HEBREW, "APPLE_HEBREW" },
+ { RTL_TEXTENCODING_APPLE_ICELAND, "APPLE_ICELAND" },
+ { RTL_TEXTENCODING_APPLE_ROMANIAN, "APPLE_ROMANIAN" },
+ { RTL_TEXTENCODING_APPLE_THAI, "APPLE_THAI" },
+ { RTL_TEXTENCODING_APPLE_TURKISH, "APPLE_TURKISH" },
+ { RTL_TEXTENCODING_APPLE_UKRAINIAN, "APPLE_UKRAINIAN" },
+ { RTL_TEXTENCODING_APPLE_CHINSIMP, "APPLE_CHINSIMP" },
+ { RTL_TEXTENCODING_APPLE_CHINTRAD, "APPLE_CHINTRAD" },
+ { RTL_TEXTENCODING_APPLE_JAPANESE, "APPLE_JAPANESE" },
+ { RTL_TEXTENCODING_APPLE_KOREAN, "APPLE_KOREAN" },
+ { RTL_TEXTENCODING_MS_932, "MS_932" },
+ { RTL_TEXTENCODING_MS_936, "MS_936" },
+ { RTL_TEXTENCODING_MS_949, "MS_949" },
+ { RTL_TEXTENCODING_MS_950, "MS_950" },
+ { RTL_TEXTENCODING_SHIFT_JIS, "SHIFT_JIS" },
+ { RTL_TEXTENCODING_GB_2312, "GB_2312" },
+ { RTL_TEXTENCODING_GBT_12345, "GBT_12345" },
+ { RTL_TEXTENCODING_GBK, "GBK" },
+ { RTL_TEXTENCODING_BIG5, "BIG5" },
+ { RTL_TEXTENCODING_EUC_JP, "EUC_JP" },
+ { RTL_TEXTENCODING_EUC_CN, "EUC_CN" },
+ { RTL_TEXTENCODING_EUC_TW, "EUC_TW" },
+ { RTL_TEXTENCODING_ISO_2022_JP, "ISO_2022_JP" },
+ { RTL_TEXTENCODING_ISO_2022_CN, "ISO_2022_CN" },
+ { RTL_TEXTENCODING_KOI8_R, "KOI8_R" },
+ { RTL_TEXTENCODING_UTF7, "UTF7" },
+ { RTL_TEXTENCODING_UTF8, "UTF8" },
+ { RTL_TEXTENCODING_ISO_8859_10, "ISO_8859_10" },
+ { RTL_TEXTENCODING_ISO_8859_13, "ISO_8859_13" },
+ { RTL_TEXTENCODING_EUC_KR, "EUC_KR" },
+ { RTL_TEXTENCODING_ISO_2022_KR, "ISO_2022_KR" },
+ { RTL_TEXTENCODING_JIS_X_0208, "JISX_0208_1983" },
+ { RTL_TEXTENCODING_JIS_X_0201, "JISX_0201_1976" },
+ { RTL_TEXTENCODING_JIS_X_0212, "JISX_0212_1990" },
+ #ifdef __notdef__
+ { RTL_TEXTENCODING_KSC_5601_1992, "KSC_5601_1992" },
+ { RTL_TEXTENCODING_TIS_620_2533, "TIS_620_2533" },
+ { RTL_TEXTENCODING_SUNUDC_1997, "SUNUDC_1997" },
+ #endif
+ { RTL_TEXTENCODING_STD_COUNT, "STD_COUNT" },
+ { RTL_TEXTENCODING_USER_START, "USER_START" },
+ { RTL_TEXTENCODING_USER_END, "USER_END" },
+ { RTL_TEXTENCODING_UCS4, "UCS4" },
+ { RTL_TEXTENCODING_UCS2, "UCS2" },
+ { RTL_TEXTENCODING_UNICODE, "UNICODE" }
+};
+
+extern "C" const char*
+pGetEncodingName( rtl_TextEncoding nEncoding )
+{
+ for ( int i = 0; i < sizeof(pRTLEncoding)/sizeof(DescriptionT); i++ )
+ if ( nEncoding == pRTLEncoding[i].nEncoding )
+ return pRTLEncoding[i].pEncoding;
+
+ static const char p_nil[] = "not_in_list";
+ return p_nil;
+}
+
diff --git a/vcl/unx/source/gdi/salcvt.hxx b/vcl/unx/source/gdi/salcvt.hxx
new file mode 100644
index 000000000000..540f879af9d5
--- /dev/null
+++ b/vcl/unx/source/gdi/salcvt.hxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * $RCSfile: salcvt.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef SAL_CONVERTER_CACHE_HXX_
+#define SAL_CONVERTER_CACHE_HXX_
+
+#ifndef _SALUNX_H
+#include <salunx.h>
+#endif
+#ifndef _RTL_TENCINFO_H
+#include <rtl/tencinfo.h>
+#endif
+#ifndef _RTL_TEXTCVT_H
+#include <rtl/textcvt.h>
+#endif
+
+extern "C" const char*
+pGetEncodingName( rtl_TextEncoding nEncoding );
+
+//
+// Cache TextToUnicode and UnicodeToText converter and conversion info which is
+// used in DrawXYZ routines and in the Event loop
+//
+
+class SalConverterCache {
+
+ public:
+ SalConverterCache();
+ ~SalConverterCache();
+ Bool EncodingHasChar(
+ rtl_TextEncoding nEncoding, sal_Unicode nChar );
+ rtl_UnicodeToTextConverter
+ GetU2TConverter( rtl_TextEncoding nEncoding );
+ rtl_TextToUnicodeConverter
+ GetT2UConverter( rtl_TextEncoding nEncoding );
+ Bool IsSingleByteEncoding( rtl_TextEncoding nEncoding );
+
+ private:
+
+ typedef struct {
+ rtl_UnicodeToTextConverter mpU2T;
+ rtl_TextToUnicodeConverter mpT2U;
+ Bool mbSingleByteEncoding;
+ Bool mbValid;
+ } ConverterT;
+
+ ConverterT *mpConverter;
+};
+
+// wrapper for rtl_convertUnicodeToText that handles the usual cases for
+// textconversion in drawtext routines
+sal_Size
+ConvertStringUTF16( const sal_Unicode *pText, int nTextLen,
+ sal_Char *pBuffer, sal_Size nBufferSize,
+ rtl_UnicodeToTextConverter aConverter );
+
+
+#endif /* SAL_CONVERTER_CACHE_HXX_ */
+
diff --git a/vcl/unx/source/gdi/salgdi.cxx b/vcl/unx/source/gdi/salgdi.cxx
new file mode 100644
index 000000000000..856502a294ba
--- /dev/null
+++ b/vcl/unx/source/gdi/salgdi.cxx
@@ -0,0 +1,975 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALGDI_CXX
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <prex.h>
+#include <X11/Xproto.h>
+#include <postx.h>
+
+#include <salunx.h>
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+
+#include <tools/debug.hxx>
+
+#ifndef PRINTER_DUMMY
+#define Font XLIB_Font
+#define Region XLIB_Region
+#include <xprinter/xp.h>
+#undef Font
+#undef Region
+#endif
+
+// -=-= SalPolyLine =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#define STATIC_POINTS 64
+
+class SalPolyLine
+{
+ XPoint Points_[STATIC_POINTS];
+ XPoint *pFirst_;
+public:
+ inline SalPolyLine( ULONG nPoints );
+ inline SalPolyLine( ULONG nPoints, const SalPoint *p );
+ inline ~SalPolyLine();
+ inline XPoint &operator [] ( ULONG n ) const
+ { return pFirst_[n]; }
+};
+
+inline SalPolyLine::SalPolyLine( ULONG nPoints )
+ : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ )
+{}
+
+inline SalPolyLine::SalPolyLine( ULONG nPoints, const SalPoint *p )
+ : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ )
+{
+ for( ULONG i = 0; i < nPoints; i++ )
+ {
+ pFirst_[i].x = (short)p[i].mnX;
+ pFirst_[i].y = (short)p[i].mnY;
+ }
+ pFirst_[nPoints] = pFirst_[0]; // close polyline
+}
+
+inline SalPolyLine::~SalPolyLine()
+{ if( pFirst_ != Points_ ) delete pFirst_; }
+
+#undef STATIC_POINTS
+// -=-= SalGraphicsData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalGraphicsData::SalGraphicsData()
+{
+ hDrawable_ = None;
+
+ pClipRegion_ = NULL;
+ pPaintRegion_ = NULL;
+
+ pPenGC_ = NULL;
+ nPenPixel_ = 0;
+ nPenColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
+
+ pFontGC_ = NULL;
+// xFont_ = NULL;
+ aScale_ = Fraction( 1, 1 );
+ nTextPixel_ = 0;
+ nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
+
+ pBrushGC_ = NULL;
+ nBrushPixel_ = 0;
+ nBrushColor_ = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White
+ hBrush_ = None;
+
+ pMonoGC_ = NULL;
+ pCopyGC_ = NULL;
+ pMaskGC_ = NULL;
+ pInvertGC_ = NULL;
+ pInvert50GC_ = NULL;
+ pStippleGC_ = NULL;
+ pTrackingGC_ = NULL;
+
+ bWindow_ = FALSE;
+ bPrinter_ = FALSE;
+ bVirDev_ = FALSE;
+ bPenGC_ = FALSE;
+ bFontGC_ = FALSE;
+ bBrushGC_ = FALSE;
+ bMonoGC_ = FALSE;
+ bCopyGC_ = FALSE;
+ bInvertGC_ = FALSE;
+ bInvert50GC_ = FALSE;
+ bStippleGC_ = FALSE;
+ bTrackingGC_ = FALSE;
+ bXORMode_ = FALSE;
+ bDitherBrush_ = FALSE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalGraphicsData::~SalGraphicsData()
+{
+ Display *pDisplay = GetXDisplay();
+
+ DBG_ASSERT( !pPaintRegion_, "pPaintRegion_" )
+ if( pClipRegion_ ) XDestroyRegion( pClipRegion_ );
+
+ if( hBrush_ ) XFreePixmap( pDisplay, hBrush_ );
+ if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ );
+ if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ );
+ if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ );
+ if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ );
+ if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ );
+ if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ );
+ if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ );
+ if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ );
+ if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ );
+ if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+beta void SalGraphicsData::DeInit()
+{
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalGraphicsData::SetClipRegion( GC pGC, XLIB_Region pXReg ) const
+{
+ Display *pDisplay = GetXDisplay();
+
+ int n = 0;
+ XLIB_Region Regions[3];
+
+ if( pClipRegion_ /* && !XEmptyRegion( pClipRegion_ ) */ )
+ Regions[n++] = pClipRegion_;
+// if( pPaintRegion_ /* && !XEmptyRegion( pPaintRegion_ ) */ )
+// Regions[n++] = pPaintRegion_;
+ if( pXReg && !XEmptyRegion( pXReg ) )
+ Regions[n++] = pXReg;
+
+ if( 0 == n )
+ XSetClipMask( pDisplay, pGC, None );
+ else if( 1 == n )
+ XSetRegion( pDisplay, pGC, Regions[0] );
+ else
+ {
+ XLIB_Region pTmpRegion = XCreateRegion();
+ XIntersectRegion( Regions[0], Regions[1], pTmpRegion );
+// if( 3 == n )
+// XIntersectRegion( Regions[2], pTmpRegion, pTmpRegion );
+ XSetRegion( pDisplay, pGC, pTmpRegion );
+ XDestroyRegion( pTmpRegion );
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final GC SalGraphicsData::SelectPen()
+{
+ Display *pDisplay = GetXDisplay();
+
+ DBG_ASSERT( nPenColor_ != 0xFFFFFFFF, "Pen Transparent" );
+
+ if( !pPenGC_ )
+ {
+ XGCValues values;
+ values.subwindow_mode = IncludeInferiors;
+ values.fill_rule = EvenOddRule; // Pict import/ Gradient
+ values.graphics_exposures = True;
+
+ pPenGC_ = XCreateGC( pDisplay, hDrawable_,
+ GCSubwindowMode | GCFillRule | GCGraphicsExposures,
+ &values );
+ }
+
+ if( !bPenGC_ )
+ {
+ XSetForeground( pDisplay, pPenGC_, nPenPixel_ );
+ XSetFunction ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy );
+ SetClipRegion( pPenGC_ );
+ bPenGC_ = TRUE;
+ }
+
+ return pPenGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final GC SalGraphicsData::SelectBrush()
+{
+ Display *pDisplay = GetXDisplay();
+
+ DBG_ASSERT( nBrushColor_ != 0xFFFFFFFF, "Brush Transparent" );
+
+ if( !pBrushGC_ )
+ {
+ XGCValues values;
+ values.subwindow_mode = IncludeInferiors;
+ values.fill_rule = EvenOddRule; // Pict import/ Gradient
+ values.graphics_exposures = True;
+
+ pBrushGC_ = XCreateGC( pDisplay, hDrawable_,
+ GCSubwindowMode | GCFillRule | GCGraphicsExposures,
+ &values );
+ }
+
+ if( !bBrushGC_ )
+ {
+ if( !bDitherBrush_ )
+ {
+ XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
+ XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ );
+ if( bPrinter_ )
+ XSetTile( pDisplay, pBrushGC_, None );
+ }
+ else
+ {
+ // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't allways reflect
+ // changes of the tile. PROPERTY_BUG_Tile doesn't fix this !
+ if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile)
+ XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
+
+ XSetFillStyle ( pDisplay, pBrushGC_, FillTiled );
+ XSetTile ( pDisplay, pBrushGC_, hBrush_ );
+ }
+ XSetFunction ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy );
+ SetClipRegion( pBrushGC_ );
+ bBrushGC_ = TRUE;
+ }
+
+ return pBrushGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final GC SalGraphicsData::GetTrackingGC()
+{
+ const char dash_list[2] = {2, 2};
+
+ if( !pTrackingGC_ )
+ {
+ XGCValues values;
+
+ values.graphics_exposures = True;
+ values.foreground = xColormap_->GetBlackPixel()
+ ^ xColormap_->GetWhitePixel();
+ values.function = GXxor;
+ values.line_width = 1;
+ values.line_style = LineOnOffDash;
+
+ pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(),
+ GCGraphicsExposures | GCForeground | GCFunction
+ | GCLineWidth | GCLineStyle,
+ &values );
+ XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 );
+ }
+
+ if( !bTrackingGC_ )
+ {
+ SetClipRegion( pTrackingGC_ );
+ bTrackingGC_ = TRUE;
+ }
+
+ return pTrackingGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphicsData::DrawLines( ULONG nPoints,
+ const SalPolyLine &rPoints,
+ GC pGC )
+{
+ // errechne wie viele Linien XWindow auf einmal zeichnen kann
+ ULONG nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq))
+ / sizeof(xPoint);
+ if( nMaxLines > nPoints ) nMaxLines = nPoints;
+
+ // gebe alle Linien aus, die XWindows zeichnen kann.
+ ULONG n;
+ for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 )
+ XDrawLines( GetXDisplay(),
+ GetDrawable(),
+ pGC,
+ &rPoints[n],
+ nMaxLines,
+ CoordModeOrigin );
+
+ if( n < nPoints )
+ XDrawLines( GetXDisplay(),
+ GetDrawable(),
+ pGC,
+ &rPoints[n],
+ nPoints - n,
+ CoordModeOrigin );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// Dithern: Calculate a dither-pixmap and make a brush of it
+#define P_DELTA 51
+#define DMAP( v, m ) ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA))
+
+final BOOL SalGraphicsData::GetDitherPixmap( SalColor nSalColor )
+{
+ static const short nOrdDither8Bit[ 8 ][ 8 ] =
+ {
+ 0, 38, 9, 48, 2, 40, 12, 50,
+ 25, 12, 35, 22, 28, 15, 37, 24,
+ 6, 44, 3, 41, 8, 47, 5, 44,
+ 32, 19, 28, 16, 34, 21, 31, 18,
+ 1, 40, 11, 49, 0, 39, 10, 48,
+ 27, 14, 36, 24, 26, 13, 36, 23,
+ 8, 46, 4, 43, 7, 45, 4, 42,
+ 33, 20, 30, 17, 32, 20, 29, 16
+ };
+
+ // test for correct depth (8bit)
+ if( GetColormap().GetVisual()->GetDepth() != 8 )
+ return FALSE;
+
+ char pBits[64];
+ char *pBitsPtr = pBits;
+
+ // Set the pallette-entries for the dithering tile
+ UINT8 nSalColorRed = SALCOLOR_RED ( nSalColor );
+ UINT8 nSalColorGreen = SALCOLOR_GREEN ( nSalColor );
+ UINT8 nSalColorBlue = SALCOLOR_BLUE ( nSalColor );
+
+ for( int nY = 0; nY < 8; nY++ )
+ {
+ for( int nX = 0; nX < 8; nX++ )
+ {
+ short nMagic = nOrdDither8Bit[nY][nX];
+ UINT8 nR = P_DELTA * DMAP( nSalColorRed, nMagic );
+ UINT8 nG = P_DELTA * DMAP( nSalColorGreen, nMagic );
+ UINT8 nB = P_DELTA * DMAP( nSalColorBlue, nMagic );
+
+ *pBitsPtr++ = GetColormap().GetPixel( MAKE_SALCOLOR( nR, nG, nB ) );
+ }
+ }
+
+ // create the tile as ximage and an according pixmap -> caching
+ XImage *pImage = XCreateImage( GetXDisplay(),
+ GetColormap().GetXVisual(),
+ 8,
+ ZPixmap,
+ 0, // offset
+ pBits, // data
+ 8, 8, // width & height
+ 8, // bitmap_pad
+ 0 ); // (default) bytes_per_line
+
+ if ( GetDisplay()->GetProperties() & PROPERTY_BUG_Tile )
+ {
+ if (hBrush_)
+ XFreePixmap (GetXDisplay(), hBrush_);
+ hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 );
+ }
+ else
+ if( !hBrush_ )
+ hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 );
+
+ // put the ximage to the pixmap
+ XPutImage( GetXDisplay(),
+ hBrush_,
+ GetDisplay()->GetCopyGC(),
+ pImage,
+ 0, 0, // Source
+ 0, 0, // Destination
+ 8, 8 ); // width & height
+
+ // destroy image-frame but not palette-data
+ pImage->data = NULL;
+ XDestroyImage( pImage );
+
+ return TRUE;
+}
+
+// -=-= SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalGraphics::SalGraphics()
+{ }
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalGraphics::~SalGraphics()
+{ }
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::GetResolution( long &rDPIX, long &rDPIY ) // const
+{
+ SalDisplay *pDisplay = _GetDisplay();
+
+ rDPIX = pDisplay->GetResolution().A();
+ rDPIY = pDisplay->GetResolution().B();
+ if ( rDPIY < 96 )
+ {
+ rDPIX = Divide( rDPIX * 96, rDPIY );
+ rDPIY = 96;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::GetScreenFontResolution( long &rDPIX, long &rDPIY ) // const
+{
+ GetResolution ( rDPIX, rDPIY );
+
+ if( rDPIY < 108 )
+ {
+ rDPIX = Divide( rDPIX * 108, rDPIY );
+ rDPIY = 108;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final USHORT SalGraphics::GetBitCount() // const
+{ return _GetVisual()->GetDepth(); }
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::ResetClipRegion()
+{
+ if( _GetClipRegion() )
+ {
+ _IsPenGC() = FALSE;
+ _IsFontGC() = FALSE;
+ _IsBrushGC() = FALSE;
+ _IsMonoGC() = FALSE;
+ _IsCopyGC() = FALSE;
+ _IsInvertGC() = FALSE;
+ _IsInvert50GC() = FALSE;
+ _IsStippleGC() = FALSE;
+ _IsTrackingGC() = FALSE;
+
+ XDestroyRegion( _GetClipRegion() );
+ _GetClipRegion() = NULL;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::BeginSetClipRegion( ULONG )
+{
+ if( _GetClipRegion() )
+ XDestroyRegion( _GetClipRegion() );
+ _GetClipRegion() = XCreateRegion();
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+BOOL SalGraphics::UnionClipRegion( long nX, long nY, long nDX, long nDY )
+{
+#ifdef DBG_UTIL
+ if( nDX <= 0 || nX + nDX > 32767 )
+ fprintf( stderr, "CombineClipRegion %ld %ld\n", nX, nDX );
+ if( nDY <= 0 || nX + nDY > 32767 )
+ fprintf( stderr, "CombineClipRegion %ld %ld\n", nY, nDY );
+#endif
+ if (!nDX || !nDY)
+ return TRUE;
+
+ XRectangle aRect;
+ aRect.x = (short)nX;
+ aRect.y = (short)nY;
+ aRect.width = (unsigned short)nDX;
+ aRect.height = (unsigned short)nDY;
+
+ XUnionRectWithRegion( &aRect, _GetClipRegion(), _GetClipRegion() );
+
+ return TRUE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::EndSetClipRegion()
+{
+ _IsPenGC() = FALSE;
+ _IsFontGC() = FALSE;
+ _IsBrushGC() = FALSE;
+ _IsMonoGC() = FALSE;
+ _IsCopyGC() = FALSE;
+ _IsInvertGC() = FALSE;
+ _IsInvert50GC() = FALSE;
+ _IsStippleGC() = FALSE;
+ _IsTrackingGC() = FALSE;
+
+// if( _GetPaintRegion() )
+// XIntersectRegion( _GetClipRegion(), _GetPaintRegion(), _GetClipRegion() );
+// else
+
+ if( XEmptyRegion( _GetClipRegion() ) )
+ {
+ XDestroyRegion( _GetClipRegion() );
+ _GetClipRegion() = NULL;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::SetLineColor()
+{
+ if( _GetPenColor() != 0xFFFFFFFF )
+ {
+ _GetPenColor() = 0xFFFFFFFF;
+ _IsPenGC() = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::SetLineColor( SalColor nSalColor )
+{
+ if( _GetPenColor() != nSalColor )
+ {
+ _GetPenColor() = nSalColor;
+ _GetPenPixel() = _GetPixel( nSalColor );
+ _IsPenGC() = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::SetFillColor()
+{
+ if( _GetBrushColor() != 0xFFFFFFFF )
+ {
+ _IsDitherBrush() = FALSE;
+ _GetBrushColor() = 0xFFFFFFFF;
+ _IsBrushGC() = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::SetFillColor( SalColor nSalColor )
+{
+ if( _GetBrushColor() != nSalColor )
+ {
+ _IsDitherBrush() = FALSE;
+ _GetBrushColor() = nSalColor;
+ _GetBrushPixel() = _GetPixel( nSalColor );
+ if( TrueColor != _GetColormap().GetVisual()->GetClass()
+ && _GetColor( _GetBrushPixel() ) != _GetBrushColor()
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray
+ && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) )
+ _IsDitherBrush() = maGraphicsData.GetDitherPixmap(nSalColor);
+ _IsBrushGC() = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::SetROPLineColor( SalROPColor nROPColor )
+{
+ switch( nROPColor )
+ {
+ case SAL_ROP_0 : // 0
+ _GetPenPixel() = (Pixel)0;
+ break;
+ case SAL_ROP_1 : // 1
+ _GetPenPixel() = (Pixel)(1 << _GetVisual()->GetDepth()) - 1;
+ break;
+ case SAL_ROP_INVERT : // 2
+ _GetPenPixel() = (Pixel)(1 << _GetVisual()->GetDepth()) - 1;
+ break;
+ }
+ _GetPenColor() = _GetColor( _GetPenPixel() );
+ _IsPenGC() = FALSE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::SetROPFillColor( SalROPColor nROPColor )
+{
+ switch( nROPColor )
+ {
+ case SAL_ROP_0 : // 0
+ _GetBrushPixel() = (Pixel)0;
+ break;
+ case SAL_ROP_1 : // 1
+ _GetBrushPixel() = (Pixel)(1 << _GetVisual()->GetDepth()) - 1;
+ break;
+ case SAL_ROP_INVERT : // 2
+ _GetBrushPixel() = (Pixel)(1 << _GetVisual()->GetDepth()) - 1;
+ break;
+ }
+ _IsDitherBrush() = FALSE;
+ _GetBrushColor() = _GetColor( _GetBrushPixel() );
+ _IsBrushGC() = FALSE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::SetXORMode( BOOL bSet )
+{
+ if( !_IsXORMode() == bSet )
+ {
+ _IsXORMode() = bSet;
+ _IsPenGC() = FALSE;
+ _IsBrushGC() = FALSE;
+ _IsMonoGC() = FALSE;
+ _IsCopyGC() = FALSE;
+ _IsInvertGC() = FALSE;
+ _IsInvert50GC() = FALSE;
+ _IsStippleGC() = FALSE;
+ _IsTrackingGC() = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::DrawPixel( long nX, long nY )
+{
+ if( _GetPenColor() != 0xFFFFFFFF )
+ XDrawPoint( _GetXDisplay(), _GetDrawable(), _SelectPen(), nX, nY );
+}
+
+final void SalGraphics::DrawPixel( long nX, long nY, SalColor nSalColor )
+{
+ if( nSalColor != 0xFFFFFFFF )
+ {
+ Display *pDisplay = _GetXDisplay();
+
+ if( _GetPenColor() == 0xFFFFFFFF && !_IsPenGC() )
+ {
+ SetLineColor( nSalColor );
+ XDrawPoint( pDisplay, _GetDrawable(), _SelectPen(), nX, nY );
+ _GetPenColor() = 0xFFFFFFFF;
+ _IsPenGC() = False;
+ }
+ else
+ {
+ GC pGC = _SelectPen();
+
+ if( nSalColor != _GetPenColor() )
+ XSetForeground( pDisplay, pGC, _GetPixel( nSalColor ) );
+
+ XDrawPoint( pDisplay, _GetDrawable(), pGC, nX, nY );
+
+ if( nSalColor != _GetPenColor() )
+ XSetForeground( pDisplay, pGC, _GetPenPixel() );
+ }
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::DrawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ if( _GetPenColor() != 0xFFFFFFFF )
+ {
+ if ( _GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine )
+ {
+ GC aGC = _SelectPen();
+ XDrawPoint (_GetXDisplay(), _GetDrawable(), aGC, (int)nX1, (int)nY1);
+ XDrawPoint (_GetXDisplay(), _GetDrawable(), aGC, (int)nX2, (int)nY2);
+ XDrawLine (_GetXDisplay(), _GetDrawable(), aGC, nX1, nY1, nX2, nY2 );
+ }
+ else
+ XDrawLine( _GetXDisplay(), _GetDrawable(),_SelectPen(),
+ nX1, nY1, nX2, nY2 );
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalGraphics::DrawRect( long nX, long nY, long nDX, long nDY )
+{
+ if( _GetBrushColor() != 0xFFFFFFFF )
+ XFillRectangle( _GetXDisplay(),
+ _GetDrawable(),
+ _SelectBrush(),
+ nX, nY, nDX, nDY );
+
+ // Beschreibung DrawRect verkehrt, deshalb -1
+ if( _GetPenColor() != 0xFFFFFFFF )
+ XDrawRectangle( _GetXDisplay(),
+ _GetDrawable(),
+ _SelectPen(),
+ nX, nY, nDX-1, nDY-1 );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#if 0
+// Ausgetauscht durch SalGraphics::Invert
+final void SalGraphics::InvertTracking( ULONG nPoints, const SalPoint *pPtAry )
+{
+ SalPolyLine Points( nPoints, pPtAry );
+
+ maGraphicsData.DrawLines( nPoints, Points, _GetTrackingGC() );
+}
+#endif
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::DrawPolyLine( ULONG nPoints, const SalPoint *pPtAry )
+{
+ if( _GetPenColor() != 0xFFFFFFFF )
+ {
+ SalPolyLine Points( nPoints, pPtAry );
+
+ maGraphicsData.DrawLines( nPoints, Points, _SelectPen() );
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::DrawPolygon( ULONG nPoints, const SalPoint* pPtAry )
+{
+ if( nPoints < 3 )
+ {
+ if( !nPoints )
+ {
+#ifdef DBG_UTIL
+ fprintf( stderr, "SalGraphics::DrawPolygon !nPoints\n" );
+#endif
+ }
+ else if( !_IsXORMode() )
+ {
+ if( 1 == nPoints )
+ DrawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
+ else
+ DrawLine( pPtAry[0].mnX, pPtAry[0].mnY,
+ pPtAry[1].mnX, pPtAry[1].mnY );
+ }
+ return;
+ }
+
+ SalPolyLine Points( nPoints, pPtAry );
+
+ nPoints++;
+
+ if( _GetBrushColor() != 0xFFFFFFFF )
+ XFillPolygon( _GetXDisplay(),
+ _GetDrawable(),
+ _SelectBrush(),
+ &Points[0], nPoints,
+ Complex, CoordModeOrigin );
+
+ if( _GetPenColor() != 0xFFFFFFFF )
+ maGraphicsData.DrawLines( nPoints, Points, _SelectPen() );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalGraphics::DrawPolyPolygon( ULONG nPoly,
+ const ULONG *pPoints,
+ PCONSTSALPOINT *pPtAry )
+{
+ if( _GetBrushColor() != 0xFFFFFFFF )
+ {
+ ULONG i, n;
+ XLIB_Region pXRegA = NULL;
+
+#ifdef CLIPPING
+ Size aOutSize = pOutDev->GetOutputSizePixel();
+
+ ClipRectangle aClippingRect( Point(0,0),
+ Point(aOutSize.Width(), aOutSize.Height()) );
+
+ ULONG nMax = pPoints[0];
+ for( i = 1; i < nPoly; i++ )
+ if( pPoints[i] > nMax )
+ nMax = pPoints[i];
+
+ SalPolyLine Points( nMax * 2 );
+
+ for( i = 0; i < nPoly; i++ )
+ {
+ n = aClippingRect.ClipPolygon( pPoints[i], pPtAry[i], &Points[0] );
+#else
+ for( i = 0; i < nPoly; i++ ) {
+ n = pPoints[i];
+ SalPolyLine Points( n, pPtAry[i] );
+#endif
+ if( n > 2 )
+ {
+ XLIB_Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule );
+ if( !pXRegA )
+ pXRegA = pXRegB;
+ else
+ {
+ XXorRegion( pXRegA, pXRegB, pXRegA );
+ XDestroyRegion( pXRegB );
+ }
+ }
+ }
+
+ if( pXRegA )
+ {
+ XRectangle aXRect;
+ XClipBox( pXRegA, &aXRect );
+
+ GC pGC = _SelectBrush();
+ maGraphicsData.SetClipRegion( pGC, pXRegA ); // ??? doppelt
+ XDestroyRegion( pXRegA );
+ _IsBrushGC() = FALSE;
+
+ XFillRectangle( _GetXDisplay(),
+ _GetDrawable(),
+ pGC,
+ aXRect.x, aXRect.y, aXRect.width, aXRect.height );
+ }
+ }
+
+ if( _GetPenColor() != 0xFFFFFFFF )
+ for( ULONG i = 0; i < nPoly; i++ )
+ DrawPolyLine( pPoints[i], pPtAry[i] );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+beta void SalGraphics::Invert( ULONG nPoints,
+ const SalPoint* pPtAry,
+ SalInvert nFlags )
+{
+ SalDisplay *pDisp = _GetDisplay();
+ SalPolyLine Points ( nPoints, pPtAry );
+
+ GC pGC;
+ if( SAL_INVERT_50 & nFlags )
+ pGC = maGraphicsData.GetInvert50GC();
+ else
+ if ( SAL_INVERT_TRACKFRAME & nFlags )
+ pGC = maGraphicsData.GetTrackingGC();
+ else
+ pGC = maGraphicsData.GetInvertGC();
+
+ maGraphicsData.DrawLines ( nPoints, Points, pGC );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#if 0
+ struct XpEPS_trf
+ {
+ double origin_x, origin_y;
+ double scale_x, scale_y;
+ double rotate;
+ };
+ struct XpBox
+ {
+ double llx,lly;
+ double urx,ury;
+ };
+ extern "C" void* XpEPS_Put( Display*, FILE*, struct XpEPS_trf* );
+ extern "C" struct XpBox* XpEPS_GetBoundingBox( Display*, FILE* );
+#endif
+
+BOOL SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize )
+{
+#ifndef PRINTER_DUMMY
+ if( _IsPrinter() )
+ {
+ // convert \r to \n (#60367#, EPS-files with mac format)
+ // this should not tangle with other lineends
+ // in postscript files \r and \n count as whitespace
+ // so they can only be addressed directly as hex codes <0a> etc.
+ char* pRun = (char*)pPtr;
+ while( (ULONG)(pRun - (char*)pPtr) < nSize )
+ {
+ if( *pRun == '\r' )
+ *pRun = '\n';
+ pRun++;
+ }
+
+ FILE* fp = tmpfile();
+ if( ! fp )
+ return FALSE;
+ fwrite( pPtr, 1, nSize, fp );
+ fseek( fp, 0, SEEK_SET );
+
+ // holt die BoundingBox in pixel
+ XpBox* pBox = XpEPS_GetBoundingBox( _GetXDisplay(), fp );
+ fseek( fp, 0, SEEK_SET );
+ XpEPS_trf aTransfer;
+ aTransfer.origin_x = nX;
+ aTransfer.origin_y = nY;
+ aTransfer.rotate = 0;
+ if( pBox )
+ {
+ aTransfer.scale_x = ((double)nWidth)/( pBox->urx - pBox->llx );
+ aTransfer.scale_x = aTransfer.scale_x < 0 ?
+ -aTransfer.scale_x : aTransfer.scale_x;
+ aTransfer.scale_y = ((double)nHeight)/( pBox->lly - pBox->ury );
+ aTransfer.scale_y = aTransfer.scale_y < 0 ?
+ -aTransfer.scale_y : aTransfer.scale_y;
+ }
+ else
+ {
+ aTransfer.scale_x = 1;
+ aTransfer.scale_y = 1;
+#if defined DEBUG
+ fprintf( stderr, "Warning: XpEPS_GetBoundingBox returned NULL\n" );
+#endif
+ }
+
+ XpEPS_Put( _GetXDisplay(), fp, &aTransfer );
+ fclose( fp ); // deletes tmpfile
+ free( pBox );
+
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
diff --git a/vcl/unx/source/gdi/salgdi2.cxx b/vcl/unx/source/gdi/salgdi2.cxx
new file mode 100644
index 000000000000..49d547533586
--- /dev/null
+++ b/vcl/unx/source/gdi/salgdi2.cxx
@@ -0,0 +1,810 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALGDI2_CXX
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <stdio.h>
+
+#include <salunx.h>
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef PRINTER_DUMMY
+#define Font XLIB_Font
+#define Region XLIB_Region
+#include <xprinter/xp.h>
+#undef Font
+#undef Region
+#endif
+
+#undef SALGDI2_TESTTRANS
+
+// -=-= debugging =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifdef DBG_UTIL
+
+static void sal_PrintImage( char *s, XImage*p )
+{
+ fprintf( stderr, "%s %d %d %d\n", s, p->depth, p->width, p->height );
+ int nW = Min( 64, p->width*p->bits_per_pixel >> 3 );
+ for( int i = 0; i < Min( 16, p->height ); i++ )
+ {
+ for( int j = 0; j < nW; j++ )
+ fprintf( stderr, "%02X", (UINT8)p->data[i*p->bytes_per_line+j] );
+ fprintf( stderr, "\n" );
+ }
+}
+
+#endif // DBG_UTIL
+
+// -----------------------------------------------------------------------------
+
+#if defined DEBUG && defined SALGDI2_TESTTRANS
+#define DBG_TESTTRANS( _def_drawable ) \
+{ \
+ XCopyArea( pXDisp, _def_drawable, aDrawable, _GetCopyGC(), \
+ 0, 0, \
+ pPosAry->mnDestWidth, pPosAry->mnDestHeight, \
+ 0, 0 ); \
+}
+#else // DEBUG && defined SALGDI2_TESTTRANS
+#define DBG_TESTTRANS( _def_drawable )
+#endif // DEBUG && defined SALGDI2_TESTTRANS
+
+// -=-= SalGraphicsData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final GC SalGraphicsData::CreateGC( Drawable hDrawable, unsigned long nMask )
+{
+ XGCValues values;
+
+ values.graphics_exposures = True;
+ values.foreground = xColormap_->GetBlackPixel()
+ ^ xColormap_->GetWhitePixel();
+ values.function = GXxor;
+ values.line_width = 1;
+ values.fill_style = FillStippled;
+ values.stipple = GetDisplay()->GetInvert50();
+
+ return XCreateGC( GetXDisplay(), hDrawable, nMask, &values );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final inline GC SalGraphicsData::GetMonoGC( Pixmap hPixmap )
+{
+ if( !pMonoGC_ )
+ pMonoGC_ = CreateGC( hPixmap );
+
+ if( !bMonoGC_ )
+ {
+ SetClipRegion( pMonoGC_ );
+ bMonoGC_ = TRUE;
+ }
+
+ return pMonoGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final inline GC SalGraphicsData::GetCopyGC()
+{
+ if( bXORMode_ ) return GetInvertGC();
+
+ if( !pCopyGC_ )
+ pCopyGC_ = CreateGC( GetDrawable() );
+
+ if( !bCopyGC_ )
+ {
+ SetClipRegion( pCopyGC_ );
+ bCopyGC_ = TRUE;
+ }
+ return pCopyGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final GC SalGraphicsData::GetInvertGC()
+{
+ if( !pInvertGC_ )
+ pInvertGC_ = CreateGC( GetDrawable(),
+ GCGraphicsExposures
+ | GCForeground
+ | GCFunction
+ | GCLineWidth );
+
+ if( !bInvertGC_ )
+ {
+ SetClipRegion( pInvertGC_ );
+ bInvertGC_ = TRUE;
+ }
+ return pInvertGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final GC SalGraphicsData::GetInvert50GC()
+{
+ if( !pInvert50GC_ )
+ {
+ XGCValues values;
+
+ values.graphics_exposures = True;
+ values.foreground = xColormap_->GetWhitePixel();
+ values.background = xColormap_->GetBlackPixel();
+ values.function = GXinvert;
+ values.line_width = 1;
+ values.line_style = LineSolid;
+ unsigned long nValueMask =
+ GCGraphicsExposures
+ | GCForeground
+ | GCBackground
+ | GCFunction
+ | GCLineWidth
+ | GCLineStyle
+ | GCFillStyle
+ | GCStipple;
+
+ char* pEnv = getenv( "SAL_DO_NOT_USE_INVERT50" );
+ if( pEnv && ! strcasecmp( pEnv, "true" ) )
+ {
+ values.fill_style = FillSolid;
+ nValueMask &= ~ GCStipple;
+ }
+ else
+ {
+ values.fill_style = FillStippled;
+ values.stipple = GetDisplay()->GetInvert50();
+ }
+
+ pInvert50GC_ = XCreateGC( GetXDisplay(), GetDrawable(),
+ nValueMask,
+ &values );
+ }
+
+ if( !bInvert50GC_ )
+ {
+ SetClipRegion( pInvert50GC_ );
+ bInvert50GC_ = TRUE;
+ }
+ return pInvert50GC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final inline GC SalGraphicsData::GetStippleGC()
+{
+ if( !pStippleGC_ )
+ pStippleGC_ = CreateGC( GetDrawable(),
+ GCGraphicsExposures
+ | GCFillStyle
+ | GCLineWidth );
+
+ if( !bStippleGC_ )
+ {
+ XSetFunction( GetXDisplay(), pStippleGC_, bXORMode_ ? GXxor : GXcopy );
+ SetClipRegion( pStippleGC_ );
+ bStippleGC_ = TRUE;
+ }
+
+ return pStippleGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final int SalGraphicsData::Clip( XLIB_Region pRegion,
+ int &nX,
+ int &nY,
+ unsigned int &nDX,
+ unsigned int &nDY,
+ int &nSrcX,
+ int &nSrcY ) const
+{
+ XRectangle aRect;
+ XClipBox( pRegion, &aRect );
+
+ if( nX + nDX <= aRect.x || nX >= aRect.x + aRect.width )
+ return RectangleOut;
+ if( nY + nDY <= aRect.y || nY >= aRect.y + aRect.height )
+ return RectangleOut;
+
+ if( nX < aRect.x )
+ {
+ nSrcX += aRect.x - nX;
+ nDX -= aRect.x - nX;
+ nX = aRect.x;
+ }
+ else if( nX + nDX > aRect.x + aRect.width )
+ nDX = aRect.x + aRect.width - nX;
+
+ if( nY < aRect.y )
+ {
+ nSrcY += aRect.y - nY;
+ nDY -= aRect.y - nY;
+ nY = aRect.y;
+ }
+ else if( nY + nDY > aRect.y + aRect.height )
+ nDY = aRect.y + aRect.height - nY;
+
+ return RectangleIn;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final int SalGraphicsData::Clip( int &nX,
+ int &nY,
+ unsigned int &nDX,
+ unsigned int &nDY,
+ int &nSrcX,
+ int &nSrcY ) const
+
+{
+ if( pPaintRegion_
+ && RectangleOut == Clip( pPaintRegion_, nX, nY, nDX, nDY, nSrcX, nSrcY ) )
+ return RectangleOut;
+
+ if( pClipRegion_
+ && RectangleOut == Clip( pClipRegion_, nX, nY, nDX, nDY, nSrcX, nSrcY ) )
+ return RectangleOut;
+
+ int nPaint;
+ if( pPaintRegion_ )
+ {
+ nPaint = XRectInRegion( pPaintRegion_, nX, nY, nDX, nDY );
+ if( RectangleOut == nPaint )
+ return RectangleOut;
+ }
+ else
+ nPaint = RectangleIn;
+
+ int nClip;
+ if( pClipRegion_ )
+ {
+ nClip = XRectInRegion( pClipRegion_, nX, nY, nDX, nDY );
+ if( RectangleOut == nClip )
+ return RectangleOut;
+ }
+ else
+ nClip = RectangleIn;
+
+ return RectangleIn == nClip && RectangleIn == nPaint
+ ? RectangleIn
+ : RectanglePart;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final GC SalGraphicsData::SetMask( int &nX,
+ int &nY,
+ unsigned int &nDX,
+ unsigned int &nDY,
+ int &nSrcX,
+ int &nSrcY,
+ Pixmap hClipMask )
+{
+ int n = Clip( nX, nY, nDX, nDY, nSrcX, nSrcY );
+ if( RectangleOut == n )
+ return NULL;
+
+ Display *pDisplay = GetXDisplay();
+
+ if( !pMaskGC_ )
+ pMaskGC_ = CreateGC( GetDrawable() );
+
+ if( RectangleIn == n )
+ {
+ XSetClipMask( pDisplay, pMaskGC_, hClipMask );
+ XSetClipOrigin( pDisplay, pMaskGC_, nX - nSrcX, nY - nSrcY );
+ return pMaskGC_;
+ }
+
+ // - - - - create alternate clip pixmap for region clipping - - - -
+ Pixmap hPixmap = XCreatePixmap( pDisplay, hClipMask, nDX, nDY, 1 );
+
+ if( !hPixmap )
+ {
+#if defined DEBUG || defined DBG_UTIL
+ fprintf( stderr, "SalGraphicsData::SetMask !hPixmap\n" );
+#endif
+ return NULL;
+ }
+
+ // - - - - reset pixmap; all 0 - - - - - - - - - - - - - - - - - - -
+ XFillRectangle( pDisplay,
+ hPixmap,
+ GetDisplay()->GetMonoGC(),
+ 0, 0,
+ nDX, nDY );
+
+ // - - - - copy pixmap only within region - - - - - - - - - - - - -
+ GC pMonoGC = GetMonoGC( hPixmap );
+ XSetClipOrigin( pDisplay, pMonoGC, -nX, -nY );
+ XCopyArea( pDisplay,
+ hClipMask, // Source
+ hPixmap, // Destination
+ pMonoGC,
+ nSrcX, nSrcY, // Source
+ nDX, nDY, // Width & Height
+ 0, 0 ); // Destination
+
+ XSetClipMask( pDisplay, pMaskGC_, hPixmap );
+ XSetClipOrigin( pDisplay, pMaskGC_, nX, nY );
+
+ XFreePixmap( pDisplay, hPixmap );
+ return pMaskGC_;
+}
+
+// -=-= SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::CopyBits( const SalTwoRect *pPosAry,
+ SalGraphics *pSrcGraphics )
+{
+ if( pPosAry->mnSrcWidth <= 0
+ || pPosAry->mnSrcHeight <= 0
+ || pPosAry->mnDestWidth <= 0
+ || pPosAry->mnDestHeight <= 0 )
+ {
+ return;
+ }
+
+ int n;
+ if( !pSrcGraphics )
+ {
+ pSrcGraphics = this;
+ n = 2;
+ }
+ else if( pSrcGraphics->_IsWindow() )
+ // window or compatible virtual device
+ if( pSrcGraphics->_GetDisplay() == _GetDisplay() )
+ n = 2; // same Display
+ else
+ n = 1; // printer or other display
+ else if( pSrcGraphics->_IsVirtualDevice() )
+ // printer compatible virtual device
+ if( _IsPrinter() )
+ n = 2; // printer or compatible virtual device == same display
+ else
+ n = 1; // window or compatible virtual device
+ else
+ n = 0;
+
+ if( n == 2
+ && pPosAry->mnSrcWidth == pPosAry->mnDestWidth
+ && pPosAry->mnSrcHeight == pPosAry->mnDestHeight )
+ {
+ if( _IsXORMode()
+ && !pSrcGraphics->_IsVirtualDevice()
+ && (_GetDisplay()->GetProperties() & PROPERTY_BUG_XCopyArea_GXxor) )
+ {
+ Pixmap hPixmap = XCreatePixmap( _GetXDisplay(),
+ pSrcGraphics->_GetDrawable(), // source
+ pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
+ pSrcGraphics->GetBitCount() );
+ XCopyArea( _GetXDisplay(),
+ pSrcGraphics->_GetDrawable(), // source
+ hPixmap, // destination
+ _GetDisplay()->GetCopyGC(), // no clipping
+ pPosAry->mnSrcX, pPosAry->mnSrcY,
+ pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
+ 0, 0 ); // destination
+ XCopyArea( _GetXDisplay(),
+ hPixmap, // source
+ _GetDrawable(), // destination
+ maGraphicsData.GetInvertGC(), // destination clipping
+ 0, 0, // source
+ pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
+ pPosAry->mnDestX, pPosAry->mnDestY );
+ XFreePixmap( _GetXDisplay(), hPixmap );
+ }
+ else
+ XCopyArea( _GetXDisplay(),
+ pSrcGraphics->_GetDrawable(), // source
+ _GetDrawable(), // destination
+ maGraphicsData.GetCopyGC(), // destination clipping
+ pPosAry->mnSrcX, pPosAry->mnSrcY,
+ pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
+ pPosAry->mnDestX, pPosAry->mnDestY );
+ }
+ else if( n )
+ {
+ SalBitmap *pDDB = pSrcGraphics->GetBitmap( pPosAry->mnSrcX,
+ pPosAry->mnSrcY,
+ pPosAry->mnSrcWidth,
+ pPosAry->mnSrcHeight );
+
+ if( !pDDB )
+ {
+ stderr0( "SalGraphics::CopyBits !pSrcGraphics->GetBitmap()\n" );
+ return;
+ }
+
+ SalTwoRect aPosAry( *pPosAry );
+
+ aPosAry.mnSrcX = 0, aPosAry.mnSrcY = 0;
+ DrawBitmap( &aPosAry, *pDDB );
+
+ delete pDDB;
+ }
+ else
+ stderr0( "SalGraphics::CopyBits from Printer not yet implemented\n" );
+}
+
+// --------------------------------------------------------------------------
+
+final void SalGraphics::CopyArea ( long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ USHORT nFlags )
+{
+ SalTwoRect aPosAry;
+
+ aPosAry.mnDestX = nDestX;
+ aPosAry.mnDestY = nDestY;
+ aPosAry.mnDestWidth = nSrcWidth;
+ aPosAry.mnDestHeight = nSrcHeight;
+
+ aPosAry.mnSrcX = nSrcX;
+ aPosAry.mnSrcY = nSrcY;
+ aPosAry.mnSrcWidth = nSrcWidth;
+ aPosAry.mnSrcHeight = nSrcHeight;
+
+ CopyBits ( &aPosAry, 0 );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap )
+{
+ SalDisplay* pSalDisp = maGraphicsData.GetDisplay();
+ Display* pXDisp = pSalDisp->GetDisplay();
+ const Drawable aDrawable( maGraphicsData.GetDrawable() );
+ const SalColormap& rColMap = pSalDisp->GetColormap();
+ const long nDepth = maGraphicsData.GetDisplay()->GetVisual()->GetDepth();
+ GC aGC( maGraphicsData.GetCopyGC() );
+ XGCValues aOldVal, aNewVal;
+ int nValues = GCForeground | GCBackground;
+
+ // set foreground/background values for 1Bit bitmaps
+ XGetGCValues( pXDisp, aGC, nValues, &aOldVal );
+ aNewVal.foreground = rColMap.GetWhitePixel(), aNewVal.background = rColMap.GetBlackPixel();
+ XChangeGC( pXDisp, aGC, nValues, &aNewVal );
+
+ if( _IsPrinter() )
+ {
+ SalTwoRect aTwoRect = { pPosAry->mnSrcX, pPosAry->mnSrcY, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
+ 0, 0, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight };
+ XImage* pImage = rSalBitmap.ImplCreateXImage( pSalDisp, nDepth, aTwoRect );
+
+ if( pImage )
+ {
+ XpStretchPutImage( maGraphicsData.GetDisplay()->GetDisplay(), aDrawable, aGC, pImage,
+ 0, 0, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight,
+ pPosAry->mnDestX, pPosAry->mnDestY, pPosAry->mnDestWidth, pPosAry->mnDestHeight );
+
+ delete[] pImage->data, pImage->data = NULL;
+ XDestroyImage( pImage );
+ }
+ }
+ else
+ rSalBitmap.ImplDraw( aDrawable, nDepth, *pPosAry, aGC );
+
+ XChangeGC( pXDisp, aGC, nValues, &aOldVal );
+ XFlush( pXDisp );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+final void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap,
+ const SalBitmap& rTransBitmap )
+{
+ DBG_ASSERT( !_IsPrinter(), "Drawing of transparent bitmaps on printer devices is strictly forbidden" );
+
+ SalDisplay* pSalDisp = maGraphicsData.GetDisplay();
+ Display* pXDisp = pSalDisp->GetDisplay();
+ Drawable aDrawable( maGraphicsData.GetDrawable() );
+ const USHORT nDepth = pSalDisp->GetVisual()->GetDepth();
+ Pixmap aFG( XCreatePixmap( pXDisp, aDrawable, pPosAry->mnDestWidth,
+ pPosAry->mnDestHeight, nDepth ) );
+ Pixmap aBG( XCreatePixmap( pXDisp, aDrawable, pPosAry->mnDestWidth,
+ pPosAry->mnDestHeight, nDepth ) );
+
+ if( aFG && aBG )
+ {
+ GC aTmpGC;
+ XGCValues aValues;
+ const SalColormap& rColMap = pSalDisp->GetColormap();
+ const int nBlack = rColMap.GetBlackPixel(), nWhite = rColMap.GetWhitePixel();
+ const int nValues = GCFunction | GCForeground | GCBackground;
+ SalTwoRect aTmpRect( *pPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0;
+
+ // draw paint bitmap in pixmap #1
+ aValues.function = GXcopy, aValues.foreground = nWhite, aValues.background = nBlack;
+ aTmpGC = XCreateGC( pXDisp, aFG, nValues, &aValues );
+ rSalBitmap.ImplDraw( aFG, nDepth, aTmpRect, aTmpGC );
+ DBG_TESTTRANS( aFG );
+
+ // draw background in pixmap #2
+ XCopyArea( pXDisp, aDrawable, aBG, aTmpGC,
+ pPosAry->mnDestX, pPosAry->mnDestY,
+ pPosAry->mnDestWidth, pPosAry->mnDestHeight,
+ 0, 0 );
+ DBG_TESTTRANS( aBG );
+
+ // mask out paint bitmap in pixmap #1 (transparent areas 0)
+ aValues.function = GXand, aValues.foreground = 0x00000000, aValues.background = 0xffffffff;
+ XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
+ rTransBitmap.ImplDraw( aFG, 1, aTmpRect, aTmpGC );
+ DBG_TESTTRANS( aFG );
+
+ // mask out background in pixmap #2 (nontransparent areas 0)
+ aValues.function = GXand, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
+ XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
+ rTransBitmap.ImplDraw( aBG, 1, aTmpRect, aTmpGC );
+ DBG_TESTTRANS( aBG );
+
+ // merge pixmap #1 and pixmap #2 in pixmap #2
+ aValues.function = GXxor, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
+ XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
+ XCopyArea( pXDisp, aFG, aBG, aTmpGC,
+ 0, 0,
+ pPosAry->mnDestWidth, pPosAry->mnDestHeight,
+ 0, 0 );
+ DBG_TESTTRANS( aBG );
+
+ // copy pixmap #2 (result) to background
+ XCopyArea( pXDisp, aBG, aDrawable, maGraphicsData.GetCopyGC(),
+ 0, 0,
+ pPosAry->mnDestWidth, pPosAry->mnDestHeight,
+ pPosAry->mnDestX, pPosAry->mnDestY );
+ DBG_TESTTRANS( aBG );
+
+ XFreeGC( pXDisp, aTmpGC );
+ XFlush( pXDisp );
+ }
+ else
+ DrawBitmap( pPosAry, rSalBitmap );
+
+ if( aFG )
+ XFreePixmap( pXDisp, aFG );
+
+ if( aBG )
+ XFreePixmap( pXDisp, aBG );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap,
+ SalColor nTransparentColor )
+{
+ DBG_ERROR( "::DrawBitmap with transparent color not supported" );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::DrawMask( const SalTwoRect* pPosAry, const SalBitmap &rSalBitmap,
+ SalColor nMaskColor )
+{
+ SalDisplay* pSalDisp = maGraphicsData.GetDisplay();
+ Display* pXDisp = pSalDisp->GetDisplay();
+ Drawable aDrawable( maGraphicsData.GetDrawable() );
+ Pixmap aStipple( XCreatePixmap( pXDisp, aDrawable,
+ pPosAry->mnDestWidth,
+ pPosAry->mnDestHeight, 1 ) );
+
+ if( aStipple )
+ {
+ SalTwoRect aTwoRect( *pPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
+ GC aTmpGC;
+ XGCValues aValues;
+
+ // create a stipple bitmap first (set bits are changed to unset bits and vice versa)
+ aValues.function = GXcopyInverted;
+ aValues.foreground = 1, aValues.background = 0;
+ aTmpGC = XCreateGC( pXDisp, aStipple, GCFunction | GCForeground | GCBackground, &aValues );
+ rSalBitmap.ImplDraw( aStipple, 1, aTwoRect, aTmpGC );
+ XFreeGC( pXDisp, aTmpGC );
+
+ // Set stipple and draw rectangle
+ GC aStippleGC( maGraphicsData.GetStippleGC() );
+ int nX = pPosAry->mnDestX, nY = pPosAry->mnDestY;
+
+ XSetStipple( pXDisp, aStippleGC, aStipple );
+ XSetTSOrigin( pXDisp, aStippleGC, nX, nY );
+ XSetForeground( pXDisp, aStippleGC, _GetPixel( nMaskColor ) );
+ XFillRectangle( pXDisp, aDrawable, aStippleGC,
+ nX, nY,
+ pPosAry->mnDestWidth, pPosAry->mnDestHeight );
+ XFreePixmap( pXDisp, aStipple );
+ XFlush( pXDisp );
+ }
+ else
+ DrawBitmap( pPosAry, rSalBitmap );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalBitmap *SalGraphics::GetBitmap( long nX, long nY, long nDX, long nDY )
+{
+ if( _IsPrinter() && !_IsVirtualDevice() )
+ return NULL;
+
+ if( _IsWindow() && !_IsVirtualDevice() )
+ {
+ // normalize
+ if( nDX < 0 )
+ {
+ nX += nDX;
+ nDX = -nDX;
+ }
+ if ( nDY < 0 )
+ {
+ nY += nDY;
+ nDY = -nDY;
+ }
+
+ XWindowAttributes aAttrib;
+
+ XGetWindowAttributes( _GetXDisplay(), _GetDrawable(), &aAttrib );
+ if( aAttrib.map_state != IsViewable )
+ {
+ stderr0( "SalGraphics::GetBitmap drawable not viewable\n" );
+ return NULL;
+ }
+
+ // am Window clippen (eg)
+ if ( nX < 0 )
+ {
+ nDX += nX;
+ nX = 0;
+ }
+ if ( nY < 0 )
+ {
+ nDY += nY;
+ nY = 0;
+ }
+ if( nX + nDX > aAttrib.width )
+ nDX = aAttrib.width - nX;
+ if( nY + nDY > aAttrib.height )
+ nDY = aAttrib.height - nY;
+
+ // nun alles ok ?
+ if( nDX <= 0 || nDY <= 0 )
+ {
+ stderr0( "SalGraphics::GetBitmap zero sized bitmap after clipping\n" );
+ return NULL;
+ }
+ }
+
+ SalBitmap* pSalBitmap = new SalBitmap;
+ USHORT nBitCount = GetBitCount();
+
+ if( &_GetDisplay()->GetColormap() != &_GetColormap() )
+ nBitCount = 1;
+
+ pSalBitmap->ImplCreateFromDrawable( _GetDrawable(), nBitCount, nX, nY, nDX, nDY );
+
+ return pSalBitmap;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalColor SalGraphics::GetPixel( long nX, long nY )
+{
+ if( _IsWindow() && !_IsVirtualDevice() )
+ {
+ XWindowAttributes aAttrib;
+
+ XGetWindowAttributes( _GetXDisplay(), _GetDrawable(), &aAttrib );
+ if( aAttrib.map_state != IsViewable )
+ {
+ stderr0( "SalGraphics::GetPixel drawable not viewable\n" );
+ return 0;
+ }
+ }
+
+ XImage *pXImage = XGetImage( _GetXDisplay(),
+ _GetDrawable(),
+ nX, nY,
+ 1, 1,
+ AllPlanes,
+ ZPixmap );
+ if( !pXImage )
+ {
+ stderr0( "SalGraphics::GetPixel !XGetImage()\n" );
+ return 0;
+ }
+
+ XColor aXColor;
+
+ aXColor.pixel = XGetPixel( pXImage, 0, 0 );
+ XDestroyImage( pXImage );
+
+ return _GetColormap().GetColor( aXColor.pixel );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphics::Invert( long nX,
+ long nY,
+ long nDX,
+ long nDY,
+ SalInvert nFlags )
+{
+ SalDisplay *pDisp = _GetDisplay();
+
+ GC pGC;
+ if( SAL_INVERT_50 & nFlags )
+ {
+ pGC = maGraphicsData.GetInvert50GC();
+ XFillRectangle( _GetXDisplay(), _GetDrawable(), pGC, nX, nY, nDX, nDY );
+ }
+ else
+ if ( SAL_INVERT_TRACKFRAME & nFlags )
+ {
+ pGC = maGraphicsData.GetTrackingGC();
+ XDrawRectangle( _GetXDisplay(), _GetDrawable(), pGC, nX, nY, nDX, nDY );
+ }
+ else
+ {
+ pGC = maGraphicsData.GetInvertGC();
+ XFillRectangle( _GetXDisplay(), _GetDrawable(), pGC, nX, nY, nDX, nDY );
+ }
+}
+
diff --git a/vcl/unx/source/gdi/salgdi3.cxx b/vcl/unx/source/gdi/salgdi3.cxx
new file mode 100644
index 000000000000..5b738f2a5de8
--- /dev/null
+++ b/vcl/unx/source/gdi/salgdi3.cxx
@@ -0,0 +1,1074 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi3.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALGDI3_CXX
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <assert.h>
+#include <alloca.h>
+
+#include <salunx.h>
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+#ifndef _STRING_HXX
+#include <tools/string.hxx>
+#endif
+#ifndef _SV_POLY_HXX
+#include <poly.hxx>
+#endif
+#ifndef _RTL_TENCINFO_H
+#include <rtl/tencinfo.h>
+#endif
+
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+
+#ifndef PRINTER_DUMMY
+#define Font XLIB_Font
+#define Region XLIB_Region
+#include <xprinter/xp.h>
+#undef Font
+#undef Region
+#endif
+
+#ifndef ANSI1252_HXX_
+#include "ansi1252.hxx"
+#endif
+#ifndef XLFD_ATTRIBUTE_HXX
+#include "xlfd_attr.hxx"
+#endif
+#ifndef XLFD_SIMPLE_HXX
+#include "xlfd_smpl.hxx"
+#endif
+#ifndef XLFD_EXTENDED_HXX
+#include "xlfd_extd.hxx"
+#endif
+#ifndef SAL_CONVERTER_CACHE_HXX_
+#include "salcvt.hxx"
+#endif
+#include <osl/types.h>
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef PRINTER_DUMMY
+static void
+FaxPhoneComment( Display* pDisplay, const sal_Unicode* pStr, USHORT nLen )
+{
+ #define FAX_PHONE_TOKEN "@@#"
+ #define FAX_PHONE_TOKEN_LENGTH 3
+ #define FAX_END_TOKEN "@@"
+
+ USHORT nPos;
+ ByteString aPhone( pStr, nLen, gsl_getSystemTextEncoding() );
+
+ static ByteString aPhoneNumber;
+ static BOOL bIsCollecting = FALSE;
+
+ if( ! bIsCollecting )
+ {
+ if( ( nPos = aPhone.Search( FAX_PHONE_TOKEN ) ) != STRING_NOTFOUND )
+ {
+ aPhone.Erase( 0, nPos + FAX_PHONE_TOKEN_LENGTH );
+ bIsCollecting = TRUE;
+ aPhoneNumber.Erase();
+ }
+ }
+ if( bIsCollecting )
+ {
+ if( ( nPos = aPhone.Search( FAX_END_TOKEN ) ) != STRING_NOTFOUND )
+ {
+ aPhone.Erase( nPos );
+ bIsCollecting = FALSE;
+ }
+ aPhoneNumber += aPhone;
+ if( ! bIsCollecting )
+ {
+ aPhone = "PhoneNumber(";
+ aPhone += aPhoneNumber;
+ aPhone += ")\n";
+ XpPSComment( pDisplay, aPhone.GetBuffer() );
+ aPhoneNumber = ByteString();
+ }
+ }
+ if( aPhoneNumber.Len() > 1024 )
+ {
+ bIsCollecting = FALSE;
+ aPhoneNumber = ByteString();
+ }
+}
+#endif
+
+// ----------------------------------------------------------------------------
+//
+// SalDisplay
+//
+// ----------------------------------------------------------------------------
+
+XlfdStorage*
+SalDisplay::GetXlfdList()
+{
+ if ( mpFontList != NULL )
+ {
+ return mpFontList;
+ }
+ else
+ {
+ // on a display an xlfd of *-0-0-75-75-* means this is a scalable
+ // bitmap font, thus it is ugly and thus to avoid. On a printer
+ // *-0-0-300-300-* means this is a printer resident font thus nice
+ // thus to prefer :-(
+ eDeviceT eDevice = this->IsDisplay() ? eDeviceDisplay : eDevicePrinter;
+
+ mpFactory = new AttributeProvider( eDevice );
+ mpFontList = new XlfdStorage();
+
+ int i, nFontCount;
+ const int nMaxCount = 64 * 1024 - 1;
+ Display *pDisplay = GetDisplay();
+ char **ppFontList = XListFonts(pDisplay, "-*", nMaxCount, &nFontCount);
+
+ //
+ // create a list of simple Xlfd font information
+ //
+
+ Xlfd *pXlfdList = (Xlfd*)malloc( nFontCount * sizeof(Xlfd) );
+ int nXlfdCount = 0;
+
+ for ( i = 0; i < nFontCount; i++ )
+ {
+ if ( pXlfdList[ nXlfdCount ].FromString(ppFontList[i], mpFactory) )
+ ++nXlfdCount;
+ }
+
+ XFreeFontNames( ppFontList );
+
+ // classification information is needed for sorting, classification
+ // of charset (i.e. iso8859-1 <-> ansi-1252) depends on wether the
+ // display points to a printer or to a real display. On a printer all
+ // iso8859-1 fonts are really capable of ansi-1252
+ mpFactory->AddClassification();
+ // add some pretty print description
+ mpFactory->AddAnnotation();
+ // misc feature checking
+ mpFactory->TagFeature();
+
+ // sort according to font style
+ qsort( pXlfdList, nXlfdCount, sizeof(Xlfd), XlfdCompare );
+
+ //
+ // create a font list with merged encoding information
+ //
+
+ BitmapXlfdStorage aBitmapList;
+ ScalableXlfd *pScalableFont = NULL;
+ PrinterFontXlfd *pPrinterFont = NULL;
+
+ int nFrom = 0;
+ for ( i = 0; i < nXlfdCount; i++ )
+ {
+ // exclude openlook glyph and cursor
+ Attribute *pAttr = mpFactory->RetrieveFamily(pXlfdList[i].mnFamily);
+ if ( pAttr->HasFeature( XLFD_FEATURE_OL_GLYPH
+ | XLFD_FEATURE_OL_CURSOR) )
+ {
+ continue;
+ }
+ // exclude fonts with unknown encoding
+ if ( pXlfdList[i].GetEncoding() == RTL_TEXTENCODING_DONTKNOW )
+ {
+ continue;
+ }
+
+ Bool bSameOutline = pXlfdList[i].SameFontoutline(pXlfdList + nFrom);
+ XlfdFonttype eType = pXlfdList[i].Fonttype();
+
+ // flush the old merged font list if the name doesn't match any more
+ if ( !bSameOutline )
+ {
+ mpFontList->Add( pScalableFont ); pScalableFont = NULL;
+ mpFontList->Add( pPrinterFont ); pPrinterFont = NULL;
+ mpFontList->Add( &aBitmapList ); aBitmapList.Reset();
+ }
+
+ // merge the font or generate a new one
+ switch( eType )
+ {
+ case eTypeScalable:
+
+ if ( pScalableFont == NULL )
+ pScalableFont = new ScalableXlfd;
+ pScalableFont->AddEncoding(pXlfdList + i);
+
+ break;
+
+ case eTypeBitmap:
+
+ aBitmapList.AddBitmapFont( pXlfdList + i );
+
+ break;
+
+ case eTypePrinterBuiltIn:
+ case eTypePrinterDownload:
+
+ if ( pPrinterFont == NULL )
+ pPrinterFont = new PrinterFontXlfd;
+ pPrinterFont->AddEncoding( pXlfdList + i );
+
+ break;
+
+ case eTypeScalableBitmap:
+ default:
+
+ break;
+ }
+
+ nFrom = i;
+ }
+
+ // flush the merged list into the global list
+ mpFontList->Add( pScalableFont );
+ mpFontList->Add( pPrinterFont );
+ mpFontList->Add( &aBitmapList );
+
+ // cleanup the list of simple font information
+ if ( pXlfdList != NULL )
+ free( pXlfdList );
+
+ return mpFontList;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+ExtendedFontStruct*
+SalDisplay::GetFont( ExtendedXlfd *pRequestedFont, int nPixelSize )
+{
+ if( !pFontCache_ )
+ {
+ mpCvtCache = new SalConverterCache;
+ pFontCache_ = new SalFontCache( 64, 64, 16 ); // ???
+ }
+ else
+ {
+ ExtendedFontStruct *pItem;
+ for ( pItem = pFontCache_->First();
+ pItem != NULL;
+ pItem = pFontCache_->Next() )
+ {
+ if ( pItem->Match(pRequestedFont, nPixelSize) )
+ {
+ if( pFontCache_->GetCurPos() )
+ {
+ pFontCache_->Remove( pItem );
+ pFontCache_->Insert( pItem, 0UL );
+ }
+ return pItem;
+ }
+ }
+ }
+
+ // before we expand the cache, we look for very old and unused items
+ if( pFontCache_->Count() >= 64 )
+ {
+ ExtendedFontStruct *pItem;
+ for ( pItem = pFontCache_->Last();
+ pItem != NULL;
+ pItem = pFontCache_->Prev() )
+ {
+ if( 1 == pItem->GetRefCount() )
+ {
+ pFontCache_->Remove( pItem );
+ pItem->ReleaseRef();
+
+ if( pFontCache_->Count() < 64 )
+ break;
+ }
+ }
+ }
+
+ ExtendedFontStruct *pItem = new ExtendedFontStruct( GetDisplay(),
+ nPixelSize, pRequestedFont, mpCvtCache );
+ pFontCache_->Insert( pItem, 0UL );
+ pItem->AddRef();
+
+ return pItem;
+}
+
+// ---------------------------------------------------------------------------
+
+void
+SalDisplay::DestroyFontCache()
+{
+ if( pFontCache_ )
+ {
+ ExtendedFontStruct *pItem = pFontCache_->First();
+ while( pItem )
+ {
+ delete pItem;
+ pItem = pFontCache_->Next();
+ }
+ delete pFontCache_;
+ }
+ if( mpFontList )
+ {
+ mpFontList->Dispose();
+ delete mpFontList;
+ }
+ if ( mpFactory )
+ {
+ delete mpFactory;
+ }
+ if ( mpCvtCache )
+ {
+ delete mpCvtCache;
+ }
+
+ pFontCache_ = (SalFontCache*)NULL;
+ mpFontList = (XlfdStorage*)NULL;
+ mpFactory = (AttributeProvider*)NULL;
+ mpCvtCache = (SalConverterCache*)NULL;
+}
+
+// ----------------------------------------------------------------------------
+//
+// SalGraphicsData
+//
+// ----------------------------------------------------------------------------
+
+GC
+SalGraphicsData::SelectFont()
+{
+ Display *pDisplay = GetXDisplay();
+
+ if( !pFontGC_ )
+ {
+ XGCValues values;
+ values.subwindow_mode = IncludeInferiors;
+ values.fill_rule = EvenOddRule; // Pict import/ Gradient
+ values.graphics_exposures = True;
+ values.foreground = nTextPixel_;
+
+ pFontGC_ = XCreateGC( pDisplay, hDrawable_,
+ GCSubwindowMode | GCFillRule
+ | GCGraphicsExposures | GCForeground,
+ &values );
+ }
+
+ if( !bFontGC_ )
+ {
+ XSetForeground( pDisplay, pFontGC_, nTextPixel_ );
+ SetClipRegion( pFontGC_ );
+ bFontGC_ = TRUE;
+ }
+
+ return pFontGC_;
+}
+
+//--------------------------------------------------------------------------
+
+// Select the max size of a font, which is token for real
+// This routine is (and should be) called only once, the result should be
+// stored in some static variable
+
+static int
+GetMaxFontHeight()
+{
+ #define DEFAULT_MAXFONTHEIGHT 250
+
+ int nMaxFontHeight = 0;
+
+ char *FontHeight = getenv ("SAL_MAXFONTHEIGHT");
+ if (FontHeight)
+ nMaxFontHeight = atoi (FontHeight);
+
+ if (nMaxFontHeight <= 0)
+ nMaxFontHeight = DEFAULT_MAXFONTHEIGHT;
+
+ return nMaxFontHeight;
+}
+
+void
+SalGraphicsData::SetFont( const ImplFontSelectData *pEntry )
+{
+ bFontGC_ = FALSE;
+ xFont_ = NULL; // ->ReleaseRef()
+ aScale_ = Fraction( 1, 1 );
+ nFontOrientation_ = pEntry->mnOrientation;
+
+ if( pEntry->mpFontData && pEntry->mpFontData->mpSysData )
+ {
+ ExtendedXlfd *pSysFont = (ExtendedXlfd*)pEntry->mpFontData->mpSysData;
+ static int nMaxFontHeight = GetMaxFontHeight();
+
+ USHORT nH, nW;
+ if( bWindow_ )
+ {
+ // see BugId #44528# FontWork (-> #45038#) and as well Bug #47127#
+ if( pEntry->mnHeight > nMaxFontHeight )
+ nH = nMaxFontHeight;
+ else if( pEntry->mnHeight > 2 )
+ nH = pEntry->mnHeight;
+ else
+ nH = 2;
+ nW = 0; // pEntry->mnWidth;
+ }
+ else
+ {
+ nH = pEntry->mnHeight;
+ nW = pEntry->mnWidth;
+ }
+
+ xFont_ = GetDisplay()->GetFont( pSysFont, nH );
+ if( pEntry->mnHeight > nMaxFontHeight || pEntry->mnHeight < 2 )
+ aScale_ = Fraction( pEntry->mnHeight, nH );
+ }
+ else
+ {
+ #ifdef DEBUG
+ // XXX Fix me: provide a fallback for poor font installations
+ // we may be reach this if no font matches the GUI font
+ // MS Sans Serif;Geneva;Helv;WarpSans;Dialog;Lucida; ... */
+ fprintf( stderr, "SalGraphicsData::SetFont: Invalid Font Selection\n" );
+ #endif
+ }
+}
+
+//--------------------------------------------------------------------------
+
+static sal_Unicode
+SwapBytes( const sal_Unicode nIn )
+{
+ return ((nIn >> 8) & 0x00ff) | ((nIn << 8) & 0xff00);
+}
+
+
+// draw string in a specific multibyte encoding
+static void
+ConvertTextItem16( XTextItem16* pTextItem,
+ SalConverterCache* pCvt, rtl_TextEncoding nEncoding )
+{
+ if ( pTextItem && pTextItem->nchars > 0 )
+ {
+ // convert the string into the font encoding
+ sal_Size nSize;
+ sal_Size nBufferSize = pTextItem->nchars * 2;
+ sal_Char *pBuffer = (sal_Char*)alloca( nBufferSize );
+
+ nSize = ConvertStringUTF16( (sal_Unicode*)pTextItem->chars, pTextItem->nchars,
+ pBuffer, nBufferSize, pCvt->GetU2TConverter(nEncoding));
+
+ sal_Char *pTextChars = (sal_Char*)pTextItem->chars;
+ int n = 0, m = 0;
+
+ if ( nEncoding == RTL_TEXTENCODING_GB_2312
+ || nEncoding == RTL_TEXTENCODING_GBT_12345
+ || nEncoding == RTL_TEXTENCODING_GBK
+ || nEncoding == RTL_TEXTENCODING_BIG5 )
+ {
+ // GB and Big5 needs special treatment since chars can be single or
+ // double byte: encoding is
+ // [ 0x00 - 0x7f ] | [ 0x81 - 0xfe ] [ 0x40 - 0x7e 0x80 - 0xfe ]
+ while ( n < nSize )
+ {
+ if ( (unsigned char)pBuffer[ n ] < 0x80 )
+ {
+ pTextChars[ m++ ] = 0x0;
+ pTextChars[ m++ ] = pBuffer[ n++ ];
+ }
+ else
+ {
+ pTextChars[ m++ ] = pBuffer[ n++ ];
+ pTextChars[ m++ ] = pBuffer[ n++ ];
+ }
+ }
+ pTextItem->nchars = m / 2;
+ }
+ else
+ if ( pCvt->IsSingleByteEncoding(nEncoding) )
+ {
+ // Single Byte encoding has to be padded
+ while ( n < nSize )
+ {
+ pTextChars[ m++ ] = 0x0;
+ pTextChars[ m++ ] = pBuffer[ n++ ];
+ }
+ pTextItem->nchars = nSize;
+ }
+ else
+ {
+ while ( n < nSize )
+ {
+ pTextChars[ m++ ] = pBuffer[ n++ ];
+ }
+ pTextItem->nchars = nSize / 2;
+ }
+ }
+}
+
+// XXX this is a hack since XPrinter is not multibyte capable
+// XXX for printing this routine is called for each character
+void
+XPrinterDrawText16( Display* pDisplay, Drawable nDrawable, GC nGC,
+ int nX, int nY, int nAngle, XTextItem16 *pTextItem16, int nItem )
+{
+ // convert XTextItem16 to XTextItem
+ XTextItem *pTextItem = (XTextItem*)alloca( nItem * sizeof(XTextItem) );
+
+ for ( int nCurItem = 0; nCurItem < nItem; nCurItem++ )
+ {
+ int nChars = pTextItem16[ nCurItem ].nchars;
+ char* pDstCharPtr = (char*)alloca( nChars * sizeof(char) );
+ XChar2b* pSrcCharPtr = pTextItem16[ nCurItem ].chars;
+
+ pTextItem[ nCurItem ].chars = pDstCharPtr;
+ pTextItem[ nCurItem ].nchars = nChars;
+ pTextItem[ nCurItem ].delta = pTextItem16[ nCurItem ].delta;
+ pTextItem[ nCurItem ].font = pTextItem16[ nCurItem ].font;
+
+ for ( int nCurChar = 0;
+ nCurChar < nChars;
+ nCurChar++, pDstCharPtr++, pSrcCharPtr++ )
+ {
+ *pDstCharPtr = (char)pSrcCharPtr->byte2;
+ }
+ }
+
+ if ( nAngle != 0 )
+ {
+ for ( int nCurItem = 0; nCurItem < nItem; nCurItem++ )
+ {
+ // XXX FIXME this is broken, because nX and nY is not sufficiently updated
+ XSetFont( pDisplay, nGC, pTextItem[ nItem ].font );
+ if ( XSalCanDrawRotString(pDisplay, nGC) )
+ {
+ XSalDrawRotString( pDisplay, nDrawable, nGC, nX, nY,
+ pTextItem[ nCurItem ].chars, pTextItem[ nCurItem ].nchars, nAngle );
+ }
+ else
+ {
+ XDrawString( pDisplay, nDrawable, nGC, nX, nY,
+ pTextItem[ nCurItem ].chars, pTextItem[ nCurItem ].nchars );
+ }
+ }
+ }
+ else
+ {
+ XDrawText( pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem );
+ }
+}
+
+// draw string in one of the fonts / encodings that are available in the
+// extended font
+static void
+DrawString( Display *pDisplay, Drawable nDrawable, GC nGC,
+ int nX, int nY, const sal_Unicode *pStr, int nLength, int nAngle,
+ SalConverterCache *pCvt, ExtendedFontStruct *pFont )
+{
+ // sanity check
+ if ( pFont == NULL || nLength == 0 )
+ return;
+
+ rtl_TextEncoding nAsciiEnc = pFont->GetAsciiEncoding();
+
+ if ( nAsciiEnc == RTL_TEXTENCODING_UNICODE )
+ {
+ // plain Unicode, can handle all chars and can be handled straight forward
+ XFontStruct* pFontStruct = pFont->GetFontStruct( nAsciiEnc );
+
+ if ( pFontStruct == NULL )
+ return;
+
+ XSetFont( pDisplay, nGC, pFontStruct->fid );
+
+ #ifdef OSL_LITENDIAN
+ sal_Unicode *pBuffer = (sal_Unicode*)alloca( nLength * sizeof(sal_Unicode) );
+ for ( int i = 0; i < nLength; i++ )
+ pBuffer[ i ] = SwapBytes(pStr[ i ]) ;
+ #else
+ sal_Unicode *pBuffer = const_cast<sal_Unicode*>(pStr);
+ #endif
+
+ XDrawString16( pDisplay, nDrawable, nGC, nX, nY, (XChar2b*)pBuffer, nLength );
+ }
+ else
+ {
+ // convert the string to a XTextItem16 with each item chars having the
+ // encoding matching the font of fontid
+ XTextItem16 *pTextItem = (XTextItem16*)alloca( nLength * sizeof(XTextItem16) );
+ XChar2b *pMBChar = (XChar2b*)alloca( nLength * sizeof(XChar2b) );
+ memcpy( pMBChar, pStr, nLength * sizeof(XChar2b) );
+
+ rtl_TextEncoding nEncoding = nAsciiEnc;
+ XFontStruct* pFontStruct = pFont->GetFontStruct( nEncoding );
+
+ if ( pFontStruct == NULL )
+ return;
+
+ for ( int nChar = 0, nItem = -1; nChar < nLength; nChar++ )
+ {
+ rtl_TextEncoding nOldEnc = nEncoding;
+ pFont->GetFontStruct( pStr[nChar], &nEncoding, &pFontStruct, pCvt );
+
+ if ( (nItem != -1) && (pFontStruct->fid == pTextItem[ nItem ].font) )
+ {
+ pTextItem[ nItem ].nchars += 1;
+ }
+ else
+ {
+ if ( nItem != -1 )
+ ConvertTextItem16( &pTextItem[ nItem ], pCvt, nOldEnc );
+
+ ++nItem;
+
+ pTextItem[ nItem ].chars = pMBChar + nChar;
+ pTextItem[ nItem ].delta = 0;
+ pTextItem[ nItem ].font = pFontStruct->fid;
+ pTextItem[ nItem ].nchars = 1;
+ }
+ }
+ ConvertTextItem16( &pTextItem[ nItem ], pCvt, nEncoding );
+ ++nItem;
+
+ if ( XSalIsDisplay( pDisplay ) )
+ XDrawText16( pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem );
+ else
+ XPrinterDrawText16( pDisplay, nDrawable, nGC, nX, nY, nAngle,
+ pTextItem, nItem );
+ }
+}
+
+//--------------------------------------------------------------------------
+
+void
+SalGraphicsData::DrawText( long nX, long nY,
+ const sal_Unicode *pStr, USHORT nLen )
+{
+#ifndef PRINTER_DUMMY
+ if( bPrinter_ )
+ FaxPhoneComment( GetXDisplay(), pStr, nLen );
+#endif
+
+ #ifdef __notdef__
+ // XXX Fix me this part is not unicode / multibyte aware
+
+ // Bug: #45670#
+ // some monospace ISO8859-1 fonts have a hole between chars 128 and 159
+ // some applications assume these characters have also the default width
+ if( ! bPrinter_ &&
+ PITCH_FIXED == xFont_->GetFont()->mePitch &&
+ nLen > 1 )
+ {
+ XFontStruct *pXFS = GetFontInfo();
+ long nWidth = xFont_->GetDim()->GetWidth();
+
+ if( xFont_->GetFixedWidth() != nWidth
+ || xFont_->GetDefaultWidth() != nWidth )
+ {
+ unsigned int min_char = pXFS->min_char_or_byte2;
+ unsigned int max_char = pXFS->max_char_or_byte2;
+ XCharStruct *pXCS = pXFS->per_char - min_char;
+
+ for( USHORT i = 0; i < nLen-1; i++ )
+ {
+ unsigned int c = ((unsigned char*)pStr)[i];
+
+ long nW = c < min_char || c > max_char || ! pXFS->per_char
+ ? xFont_->GetDefaultWidth()
+ : pXCS[c].width;
+
+ if( nW != nWidth )
+ {
+ long *pDXAry = new long[nLen];
+
+ for( i = 0; i < nLen; i++ )
+ pDXAry[i] = nWidth * (i+1);
+
+ DrawText( nX, nY, pStr, nLen, pDXAry );
+
+ delete pDXAry;
+
+ return;
+ }
+ }
+ }
+ }
+
+ #endif /* __notdef__ */
+
+ Display *pDisplay = GetXDisplay();
+ SalConverterCache *pCvt = GetDisplay()->GetConverter();
+ GC pGC = SelectFont();
+
+ DrawString( pDisplay, hDrawable_, pGC, nX, nY,
+ pStr, nLen, nFontOrientation_ * 64 / 10, pCvt, xFont_ );
+}
+
+void
+SalGraphics::DrawText( long nX, long nY, const xub_Unicode* pStr, USHORT nLen )
+{
+ maGraphicsData.DrawText( nX, nY, pStr, nLen );
+}
+
+//--------------------------------------------------------------------------
+
+static BOOL
+CheckNoNegativeCoordinateWorkaround()
+{
+ /* Motivation: one of our clients uses a Solaris 2.4 X86 system with an
+ XServer for the Matrox Mystique graphics card. This board/server
+ sometimes does not draw Text with negative x-coordinates into a
+ virtual device (for unknown reasons). A stock X-server just clips the
+ part in the negative area. */
+ static int nCheck = -2;
+ if( nCheck == -2 )
+ {
+ char* pCmp = getenv( "SAL_NO_NEGATIVE_TEXT_OFFSET" );
+ if( pCmp && ! strncasecmp( pCmp, "true", 4 ) )
+ nCheck = 1;
+ else
+ nCheck = 0;
+ }
+ return nCheck ? TRUE : FALSE;
+}
+
+void
+SalGraphicsData::DrawText(
+ long nX, long nY,
+ const sal_Unicode* pStr, USHORT nLen, const long* pDXAry )
+{
+ #ifndef PRINTER_DUMMY
+ if( bPrinter_ )
+ FaxPhoneComment( GetXDisplay(), pStr, nLen );
+ #endif
+ GC pGC = SelectFont();
+
+ // workaround for problems with negative coordinates
+ long* pTmpAry = NULL;
+ if( nX < 0 && CheckNoNegativeCoordinateWorkaround() )
+ {
+ long nOldX = nX;
+ while( nX < 0 )
+ {
+ nX = nOldX + *pDXAry;
+ pStr++, pDXAry++, nLen--;
+ if( nLen < 1 )
+ return;
+ }
+ pTmpAry = new long[ nLen ];
+ for( int q = 0; q < nLen-1; q++ )
+ pTmpAry[q] = pDXAry[q] - ( nX - nOldX );
+ pDXAry = pTmpAry;
+ }
+
+ // draw every single character
+ SalConverterCache *pCvt = GetDisplay()->GetConverter();
+ int angle = nFontOrientation_ * 64 / 10;
+ Polygon aPolygon(1);
+ Point aOrigin( nX, nY );
+ Point aCharPos;
+
+ DrawString( GetXDisplay(), hDrawable_, pGC,
+ aOrigin.X(), aOrigin.Y(), pStr, 1, angle, pCvt, xFont_ );
+
+ for( int i = 1; i < nLen ; i++ )
+ {
+ aCharPos = Point( aOrigin.X() + pDXAry[ i - 1 ], aOrigin.Y() );
+ aPolygon.SetPoint( aCharPos, 0 );
+ aPolygon.Rotate( aOrigin, nFontOrientation_ );
+ aCharPos = aPolygon.GetPoint( 0 );
+
+ DrawString( GetXDisplay(), hDrawable_, pGC,
+ aCharPos.X(), aCharPos.Y(), pStr + i, 1, angle, pCvt, xFont_ );
+ }
+
+ if( pTmpAry )
+ delete pTmpAry;
+}
+
+// ----------------------------------------------------------------------------
+//
+// SalGraphics
+//
+// ----------------------------------------------------------------------------
+
+USHORT
+SalGraphics::SetFont( ImplFontSelectData *pEntry )
+{
+ maGraphicsData.SetFont( pEntry );
+ return _IsPrinter() ? SAL_SETFONT_USEDRAWTEXTARRAY : 0;
+}
+
+// ----------------------------------------------------------------------------
+
+void
+SalGraphics::DrawTextArray( long nX, long nY,
+ const xub_Unicode *pStr, USHORT nLen, const long *pDXAry )
+{
+ maGraphicsData.DrawText( nX, nY, pStr, nLen, pDXAry );
+}
+
+// ----------------------------------------------------------------------------
+
+void
+SalGraphics::SetTextColor( SalColor nSalColor )
+{
+ if( _GetTextColor() != nSalColor )
+ {
+ _GetTextColor() = nSalColor;
+ _GetTextPixel() = _GetPixel( nSalColor );
+ _IsFontGC() = FALSE;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void
+SalGraphics::GetDevFontList( ImplDevFontList *pList )
+{
+ XlfdStorage* pFonts = _GetDisplay()->GetXlfdList();
+
+ for ( int nIdx = 0; nIdx < pFonts->GetCount(); nIdx++ )
+ {
+ ImplFontData *pFontData = new ImplFontData;
+ pFonts->Get(nIdx)->ToImplFontData( pFontData );
+ pList->Add( pFontData );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+inline long
+sal_DivideNeg( long n1, long n2 )
+{
+ return ( n1 < 0 ) ? (n1 - n2 / 2) / n2 : (n1 + n2 / 2) / n2;
+}
+
+void
+SalGraphics::GetFontMetric( ImplFontMetricData *pMetric )
+{
+ ExtendedFontStruct* pFont = maGraphicsData.xFont_;
+
+ if ( pFont != NULL )
+ {
+ pFont->ToImplFontMetricData( pMetric );
+
+ if( XSalCanDrawRotString( maGraphicsData.GetXDisplay(), None ) )
+ pMetric->mnOrientation = maGraphicsData.nFontOrientation_;
+
+ long n;
+
+ n = maGraphicsData.aScale_.GetNumerator();
+ if( n != 1 )
+ {
+ pMetric->mnWidth *= n;
+ pMetric->mnAscent *= n;
+ pMetric->mnDescent *= n;
+ pMetric->mnLeading *= n;
+ pMetric->mnSlant *= n;
+ }
+
+ n = maGraphicsData.aScale_.GetDenominator();
+ if( n != 1 )
+ {
+ pMetric->mnWidth = Divide( pMetric->mnWidth, n );
+ pMetric->mnAscent = sal_DivideNeg( pMetric->mnAscent, n );
+ pMetric->mnDescent = sal_DivideNeg( pMetric->mnDescent, n );
+ pMetric->mnLeading = sal_DivideNeg( pMetric->mnLeading, n );
+ pMetric->mnSlant = sal_DivideNeg( pMetric->mnSlant, n );
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+static long
+InitializeWidthArray( long *pWidthArray, sal_Size nItems, int nValue = 0 )
+{
+ const long nPrecision = 1;
+
+ for ( int i = 0; i < nItems; i++, pWidthArray++ )
+ *pWidthArray = nValue;
+
+ return nPrecision;
+}
+
+long
+SalGraphics::GetCharWidth( USHORT nChar1, USHORT nChar2, long *pWidthAry )
+{
+ // return the precision of the calculated charwidth, e.g. 1000 = 3 digits
+ // defaultet to 1 for now
+ const long nPrecision = 1;
+ int nRequestedWidth = nChar2 - nChar1 + 1;
+ int nCharWidth;
+
+ // XXX sanity check, this may happen if no font at all is installed
+ // or no system font matches the requirements for the user interface
+ if ( maGraphicsData.xFont_ == NULL )
+ return InitializeWidthArray( pWidthAry, nRequestedWidth, 12 );
+
+ // the font should know it's metrics best
+ SalDisplay *pSalDisplay = maGraphicsData.GetDisplay();
+
+ nCharWidth = maGraphicsData.xFont_->GetCharWidth(
+ pSalDisplay->GetConverter(), nChar1, nChar2, pWidthAry );
+
+ // XXX sanity check, this may happen if the font cannot be loaded/queried
+ // either because of a garbled fontpath or because of invalid fontfile
+ if ( nCharWidth != nRequestedWidth )
+ InitializeWidthArray( pWidthAry + nCharWidth,
+ nRequestedWidth - nCharWidth );
+
+ // handle internal scaling
+ const long nNumerator = maGraphicsData.aScale_.GetNumerator();
+ const long nDenominator = maGraphicsData.aScale_.GetDenominator();
+ long *pPtr;
+ sal_Unicode nChar;
+
+ if ( nNumerator != 1 )
+ for( pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++)
+ *pPtr *= nNumerator;
+ if ( nDenominator != 1 )
+ for( pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++)
+ *pPtr = Divide( *pPtr, nDenominator );
+
+ // return
+ return nPrecision;
+}
+
+// ---------------------------------------------------------------------------
+
+extern unsigned char TranslateCharName( char* );
+
+ULONG
+SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData *pKernPairs )
+{
+ if( ! _IsPrinter() )
+ return 0;
+
+ // get pair kerning table ( internal data from xprinter )
+ int i, nCurPair=0;
+
+ // XXX Fix me, improve this to be multi encoding aware: merge kern
+ // pair list for all encodings available in the xfont
+ rtl_TextEncoding nEncoding = maGraphicsData.xFont_->GetAsciiEncoding();
+ XFontStruct *pXFS = maGraphicsData.xFont_->GetFontStruct( nEncoding );
+ XExtData *pXES = pXFS->ext_data;
+
+ for( i = 0; pXES && i < 2; i++, pXES = pXES->next );
+ if( i < 2 )
+ return 0;
+ XpPairKernData* pXpPKD = (XpPairKernData*)(pXES->private_data);
+ PairKernData* pPKD = pXpPKD->pkd;
+
+ for( i = 0, nCurPair=0; i < pXpPKD->numOfPairs; i++ )
+ {
+ unsigned char c1 = TranslateCharName( pPKD[i].name1 );
+ unsigned char c2 = TranslateCharName( pPKD[i].name2 );
+ if( c1 && c2 )
+ {
+ if( pKernPairs && nCurPair < nPairs )
+ {
+ pKernPairs[ nCurPair ].mnChar1 = c1;
+ pKernPairs[ nCurPair ].mnChar2 = c2;
+ pKernPairs[ nCurPair ].mnKern =
+ (long)(pPKD[i].xamt * pXpPKD->pointsize / 1000 );
+ }
+ nCurPair++;
+ }
+ }
+
+ return nCurPair;
+}
+
+// ---------------------------------------------------------------------------
+
+BOOL
+SalGraphics::GetGlyphBoundRect( xub_Unicode c,
+ long *pX, long *pY, long *pDX, long *pDY )
+{
+ return FALSE;
+}
+
+// ---------------------------------------------------------------------------
+
+ULONG
+SalGraphics::GetGlyphOutline( xub_Unicode c,
+ USHORT **ppPolySizes, SalPoint **ppPoints, BYTE **ppFlags )
+{
+ return 0;
+}
+
diff --git a/vcl/unx/source/gdi/salogl.cxx b/vcl/unx/source/gdi/salogl.cxx
new file mode 100644
index 000000000000..ef2566788549
--- /dev/null
+++ b/vcl/unx/source/gdi/salogl.cxx
@@ -0,0 +1,393 @@
+/*************************************************************************
+ *
+ * $RCSfile: salogl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALOGL_CXX
+
+#include <salunx.h>
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+
+#ifndef _SV_SALOGL_HXX
+#include <salogl.hxx>
+#endif
+
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+// ------------
+// - Lib-Name -
+// ------------
+
+#define OGL_LIBNAME "libGL.so"
+// ----------
+// - Macros -
+// ----------
+
+// NETBSD has neither RTLD_GLOBAL nor RTLD_NOW
+#ifdef NETBSD
+#define DLOPEN_MODE 0
+#else
+#define DLOPEN_MODE (RTLD_NOW | RTLD_GLOBAL)
+#endif
+
+
+// -----------------
+// - Statics init. -
+// -----------------
+
+// Members
+GLXContext SalOpenGL::maGLXContext = 0;
+Display* SalOpenGL::mpDisplay = 0;
+XVisualInfo* SalOpenGL::mpVisualInfo = 0;
+BOOL SalOpenGL::mbHaveGLVisual = FALSE;
+
+void * SalOpenGL::mpGLLib = 0;
+ULONG SalOpenGL::mnOGLState = OGL_STATE_UNLOADED;
+
+GLXContext (*SalOpenGL::pCreateContext)( Display *, XVisualInfo *, GLXContext, Bool ) = 0;
+void (*SalOpenGL::pDestroyContext)( Display *, GLXContext ) = 0;
+GLXContext (*SalOpenGL::pGetCurrentContext)( ) = 0;
+Bool (*SalOpenGL::pMakeCurrent)( Display *, GLXDrawable, GLXContext ) = 0;
+void (*SalOpenGL::pSwapBuffers)( Display*, GLXDrawable ) = 0;
+int (*SalOpenGL::pGetConfig)( Display*, XVisualInfo*, int, int* ) = 0;
+void (*SalOpenGL::pFlush)() = 0;
+
+// -------------
+// - SalOpenGL -
+// -------------
+
+SalOpenGL::SalOpenGL( SalGraphics* pGraphics )
+{
+ mpDisplay = pGraphics->maGraphicsData.GetXDisplay();
+ mpVisualInfo = pGraphics->maGraphicsData.GetDisplay()->GetVisual();
+ maDrawable = pGraphics->maGraphicsData.GetDrawable();
+}
+
+// ------------------------------------------------------------------------
+
+SalOpenGL::~SalOpenGL()
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::Create()
+{
+ if( OGL_STATE_UNLOADED == mnOGLState )
+ {
+ BOOL bHasGLX = FALSE;
+ char **ppExtensions;
+ int nExtensions;
+
+ if( *DisplayString( mpDisplay ) == ':' ||
+ ! strncmp( DisplayString( mpDisplay ), "localhost:", 10 )
+ )
+ {
+ // GLX only on local displays due to strange problems
+ // with remote GLX
+ ppExtensions = XListExtensions( mpDisplay, &nExtensions );
+ for( int i=0; i < nExtensions; i++ )
+ {
+ if( ! strncmp( "GLX", ppExtensions[ i ], 3 ) )
+ {
+ bHasGLX = TRUE;
+ break;
+ }
+ }
+ XFreeExtensionList( ppExtensions );
+#ifdef DEBUG
+ if( ! bHasGLX )
+ fprintf( stderr, "XServer does not support GLX extension\n" );
+#endif
+ }
+ if( bHasGLX && mpVisualInfo->c_class == TrueColor && ImplInit() )
+ {
+ int nDoubleBuffer = 0;
+ int nHaveGL = 0;
+ pGetConfig( mpDisplay, mpVisualInfo,
+ GLX_USE_GL, &nHaveGL );
+ pGetConfig( mpDisplay, mpVisualInfo,
+ GLX_DOUBLEBUFFER, &nDoubleBuffer );
+ if( nHaveGL && ! nDoubleBuffer )
+ {
+ SalDisplay* pSalDisplay = GetSalData()->GetDefDisp();
+ BOOL bPreviousState =
+ pSalDisplay->GetXLib()->GetIgnoreXErrors();
+ pSalDisplay->GetXLib()->SetIgnoreXErrors( TRUE );
+ mbHaveGLVisual = TRUE;
+
+ maGLXContext = pCreateContext( mpDisplay, mpVisualInfo, 0, True );
+ if( pSalDisplay->GetXLib()->WasXError() )
+ mbHaveGLVisual = FALSE;
+ else
+ pMakeCurrent( mpDisplay, maDrawable, maGLXContext );
+ if( pSalDisplay->GetXLib()->WasXError() )
+ mbHaveGLVisual = FALSE;
+ pSalDisplay->GetXLib()->SetIgnoreXErrors( bPreviousState );
+
+ if( mbHaveGLVisual )
+ mnOGLState = OGL_STATE_VALID;
+ else
+ maGLXContext = None;
+ }
+ }
+ if( mnOGLState != OGL_STATE_VALID )
+ {
+ ImplFreeLib();
+ mnOGLState = OGL_STATE_INVALID;
+ }
+#if defined DEBUG
+ if( mnOGLState == OGL_STATE_VALID )
+ fprintf( stderr, "Using GLX on visual id %x.\n", mpVisualInfo->visualid );
+ else
+ fprintf( stderr, "Not using GLX.\n" );
+#endif
+ }
+
+ return mnOGLState == OGL_STATE_VALID ? TRUE : FALSE;
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::Release()
+{
+ ImplFreeLib();
+}
+
+// ------------------------------------------------------------------------
+
+void* SalOpenGL::GetOGLFnc( const String& rFncName )
+{
+ if( mpGLLib )
+ {
+ return dlsym( mpGLLib, ByteString( rFncName, RTL_TEXTENCODING_ASCII_US ).GetBuffer() );
+ }
+ return NULL;
+}
+
+void* SalOpenGL::GetOGLFnc( char *pFncName )
+{
+ if( mpGLLib )
+ {
+ return dlsym( mpGLLib, pFncName );
+ }
+ return NULL;
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::OGLEntry( SalGraphics* pGraphics )
+{
+ GLXDrawable aDrawable = pGraphics->maGraphicsData.GetDrawable();
+ if( aDrawable != maDrawable )
+ {
+ maDrawable = aDrawable;
+ pMakeCurrent( mpDisplay, maDrawable, maGLXContext );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::OGLExit( SalGraphics* pGraphics )
+{
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::ImplFreeLib()
+{
+ if( mpGLLib )
+ {
+ if( maGLXContext && pDestroyContext )
+ pDestroyContext( mpDisplay, maGLXContext );
+ dlclose( mpGLLib );
+
+ mpGLLib = 0;
+ pCreateContext = 0;
+ pDestroyContext = 0;
+ pGetCurrentContext = 0;
+ pMakeCurrent = 0;
+ pSwapBuffers = 0;
+ pGetConfig = 0;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::ImplInit()
+{
+ if( ! mpGLLib )
+ {
+ ByteString sNoGL( getenv( "SAL_NOOPENGL" ) );
+ if( sNoGL.ToLowerAscii() == "true" ) return FALSE;
+ mpGLLib = dlopen( OGL_LIBNAME, DLOPEN_MODE );
+ }
+ if( ! mpGLLib )
+ {
+#ifdef DEBUG
+ fprintf( stderr, OGL_LIBNAME "could not be opened: %s\n", dlerror() );
+#endif
+ return FALSE;
+ }
+
+ // Internal use
+ pCreateContext = (GLXContext(*)(Display*,XVisualInfo*,GLXContext,Bool ))
+ GetOGLFnc( "glXCreateContext" );
+ pDestroyContext = (void(*)(Display*,GLXContext))
+ GetOGLFnc( "glXDestroyContext" );
+ pGetCurrentContext = (GLXContext(*)())
+ GetOGLFnc( "glXGetCurrentContext" );
+ pMakeCurrent = (Bool(*)(Display*,GLXDrawable,GLXContext))
+ GetOGLFnc( "glXMakeCurrent" );
+ pSwapBuffers=(void(*)(Display*, GLXDrawable))
+ GetOGLFnc( "glXSwapBuffers" );
+ pGetConfig = (int(*)(Display*, XVisualInfo*, int, int* ))
+ GetOGLFnc( "glXGetConfig" );
+ pFlush = (void(*)())
+ GetOGLFnc( "glFlush" );
+
+ BOOL bRet = pCreateContext && pDestroyContext && pGetCurrentContext && pMakeCurrent && pSwapBuffers && pGetConfig ? TRUE : FALSE;
+
+#ifdef DEBUG
+ if( ! bRet )
+ fprintf( stderr, "could not find all needed symbols in " OGL_LIBNAME "\n" );
+#endif
+
+ return bRet;
+}
+
+void SalOpenGL::StartScene( SalGraphics* pGraphics )
+{
+ // flush pending operations which otherwise might be drawn
+ // at the wrong time
+ XSync( mpDisplay, False );
+}
+
+void SalOpenGL::StopScene()
+{
+ if( maDrawable )
+ {
+ pSwapBuffers( mpDisplay, maDrawable );
+ pFlush();
+ }
+}
+
+void SalOpenGL::MakeVisualWeights( Display* pDisplay,
+ XVisualInfo* pInfos,
+ int *pWeights,
+ int nVisuals )
+{
+ BOOL bHasGLX = FALSE;
+ char **ppExtensions;
+ int nExtensions,i ;
+
+ // GLX only on local displays due to strange problems
+ // with remote GLX
+ if( ! ( *DisplayString( pDisplay ) == ':' ||
+ !strncmp( DisplayString( pDisplay ), "localhost:", 10 )
+ ) )
+ return;
+
+ ppExtensions = XListExtensions( pDisplay, &nExtensions );
+ for( i=0; i < nExtensions; i++ )
+ {
+ if( ! strncmp( "GLX", ppExtensions[ i ], 3 ) )
+ {
+ bHasGLX = TRUE;
+ break;
+ }
+ }
+ XFreeExtensionList( ppExtensions );
+ if( ! bHasGLX )
+ return;
+
+ if( ! ImplInit() )
+ {
+ ImplFreeLib();
+ return;
+ }
+
+ for( i = 0; i < nVisuals; i++ )
+ {
+ int nDoubleBuffer = 0;
+ int nHaveGL = 0;
+ if( pInfos[i].c_class == TrueColor )
+ {
+ pGetConfig( pDisplay, &pInfos[ i ], GLX_USE_GL, &nHaveGL );
+ pGetConfig( pDisplay, &pInfos[ i ], GLX_DOUBLEBUFFER, &nDoubleBuffer );
+ if( nHaveGL && ! nDoubleBuffer )
+ {
+ mbHaveGLVisual = TRUE;
+ pWeights[ i ] += 65536;
+ }
+ }
+ }
+}
diff --git a/vcl/unx/source/gdi/salvd.cxx b/vcl/unx/source/gdi/salvd.cxx
new file mode 100644
index 000000000000..6c11ea419bcd
--- /dev/null
+++ b/vcl/unx/source/gdi/salvd.cxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * $RCSfile: salvd.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALVD_CXX
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <salunx.h>
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+
+// -=-= SalInstance =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+SalVirtualDevice* SalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ USHORT nBitCount )
+{
+ SalVirtualDevice *pVDev = new SalVirtualDevice();
+ if( !nBitCount && pGraphics )
+ nBitCount = pGraphics->GetBitCount();
+ if( !pVDev->maVirDevData.Init( pGraphics->maGraphicsData.GetDisplay(),
+ nDX, nDY, nBitCount ) )
+ {
+ delete pVDev;
+ return NULL;
+ }
+
+ pVDev->maVirDevData.InitGraphics( pVDev, pGraphics );
+ return pVDev;
+}
+
+final void SalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
+{ delete pDevice; }
+
+// -=-= SalGraphicsData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final void SalGraphicsData::Init( SalVirtualDevice *pDevice,
+ SalGraphics *pGraphics )
+{
+ SalDisplay *pDisplay = pDevice->maVirDevData.GetDisplay();
+
+ int nVisualDepth = pDisplay->GetColormap().GetVisual()->GetDepth();
+ int nDeviceDepth = pDevice->maVirDevData.GetDepth();
+
+ if( nDeviceDepth == nVisualDepth )
+ xColormap_ = &pDisplay->GetColormap();
+ else
+ if( nDeviceDepth == 1 )
+ xColormap_ = new SalColormap();
+
+ hDrawable_ = pDevice->maVirDevData.GetDrawable();
+
+ bWindow_ = pDisplay->IsDisplay();
+ bVirDev_ = TRUE;
+
+ nPenPixel_ = GetPixel( nPenColor_ );
+ nTextPixel_ = GetPixel( nTextColor_ );
+ nBrushPixel_ = GetPixel( nBrushColor_ );
+}
+
+// -=-= SalVirDevData / SalVirtualDevice -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final BOOL SalVirDevData::Init( SalDisplay *pDisplay,
+ long nDX, long nDY,
+ USHORT nBitCount )
+{
+ pDisplay_ = pDisplay;
+ pGraphics_ = new SalGraphics();
+ nDX_ = nDX;
+ nDY_ = nDY;
+ nDepth_ = nBitCount;
+
+ hDrawable_ = XCreatePixmap( GetXDisplay(),
+ pDisplay_->GetDrawable(),
+ nDX_, nDY_,
+ GetDepth() );
+
+ return hDrawable_ != None ? TRUE : FALSE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final inline SalVirDevData::SalVirDevData()
+{
+ pDisplay_ = (SalDisplay*)ILLEGAL_POINTER;
+ pGraphics_ = NULL;
+ hDrawable_ = None;
+ nDX_ = 0;
+ nDY_ = 0;
+ nDepth_ = 0;
+ bGraphics_ = FALSE;
+}
+
+final SalVirtualDevice::SalVirtualDevice() {}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+beta inline SalVirDevData::~SalVirDevData()
+{
+ if( pGraphics_ )
+ {
+ pGraphics_->maGraphicsData.DeInit();
+ delete pGraphics_;
+ }
+
+ if( GetDrawable() )
+ XFreePixmap( GetXDisplay(), GetDrawable() );
+}
+
+final SalVirtualDevice::~SalVirtualDevice()
+{}
+
+// -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#define _GetDrawable() maVirDevData.GetDrawable()
+#define _GetDisplay() maVirDevData.GetDisplay()
+#define _GetXDisplay() maVirDevData.GetXDisplay()
+#define _GetDepth() maVirDevData.nDepth_
+
+// -=-= SalVirtualDevice -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+final SalGraphics* SalVirtualDevice::GetGraphics()
+{
+ if( maVirDevData.bGraphics_ )
+ return NULL;
+
+ if( maVirDevData.pGraphics_ )
+ maVirDevData.bGraphics_ = TRUE;
+
+ return maVirDevData.pGraphics_;
+}
+
+final void SalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{ maVirDevData.bGraphics_ = FALSE; }
+
+final BOOL SalVirtualDevice::SetSize( long nDX, long nDY )
+{
+ if( !nDX ) nDX = 1;
+ if( !nDY ) nDY = 1;
+
+ Pixmap h = XCreatePixmap( _GetXDisplay(),
+ maVirDevData.pDisplay_->GetDrawable(),
+ nDX, nDY, _GetDepth() );
+
+ if( !h )
+ {
+ if( !_GetDrawable() )
+ {
+ maVirDevData.hDrawable_ = XCreatePixmap( _GetXDisplay(),
+ maVirDevData.pDisplay_->GetDrawable(),
+ 1, 1, _GetDepth() );
+ maVirDevData.nDX_ = 1;
+ maVirDevData.nDY_ = 1;
+ }
+ return FALSE;
+ }
+
+ if( _GetDrawable() )
+ XFreePixmap( _GetXDisplay(), _GetDrawable() );
+ maVirDevData.hDrawable_ = h;
+
+ maVirDevData.nDX_ = nDX;
+ maVirDevData.nDY_ = nDY;
+
+ if( maVirDevData.pGraphics_ )
+ maVirDevData.InitGraphics( this, maVirDevData.pGraphics_ );
+
+ return TRUE;
+}
+
diff --git a/vcl/unx/source/gdi/xfont.cxx b/vcl/unx/source/gdi/xfont.cxx
new file mode 100644
index 000000000000..edf1f02f4cfc
--- /dev/null
+++ b/vcl/unx/source/gdi/xfont.cxx
@@ -0,0 +1,559 @@
+/*************************************************************************
+ *
+ * $RCSfile: xfont.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <salunx.h>
+
+#ifndef EXTENDED_FONTSTRUCT_HXX
+#include "xfont.hxx"
+#endif
+#ifndef XLFD_EXTENDED_HXX
+#include "xlfd_extd.hxx"
+#endif
+#ifndef SAL_CONVERTER_CACHE_HXX_
+#include "salcvt.hxx"
+#endif
+#ifndef _STRING_HXX
+#include <tools/string.hxx>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+ExtendedFontStruct::ExtendedFontStruct( Display* pDisplay,
+ unsigned short nPixelSize, ExtendedXlfd* pXlfd,
+ SalConverterCache* pCvt ) :
+ mpDisplay( pDisplay ),
+ mnPixelSize( nPixelSize ),
+ mpXlfd( pXlfd )
+{
+ // member functions rely on zero initialized pointer for checking of
+ // already loaded fonts
+ mpXFontStruct = (XFontStruct**)calloc( mpXlfd->NumEncodings(),
+ sizeof(XFontStruct*) );
+ mnDefaultWidth = GetDefaultWidth( pCvt );
+}
+
+ExtendedFontStruct::~ExtendedFontStruct()
+{
+ for ( int nIdx = 0; nIdx < mpXlfd->NumEncodings(); nIdx++ )
+ {
+ if ( mpXFontStruct[nIdx] != NULL )
+ XFreeFont( mpDisplay, mpXFontStruct[nIdx] );
+ }
+}
+
+rtl_TextEncoding
+ExtendedFontStruct::GetAsciiEncoding( int *pAsciiRange ) const
+{
+ return mpXlfd->GetAsciiEncoding( pAsciiRange );
+}
+
+int
+ExtendedFontStruct::LoadEncoding( rtl_TextEncoding nEncoding )
+{
+ int nIdx = mpXlfd->GetEncodingIdx( nEncoding );
+ if ( (nIdx < 0) || (mpXFontStruct[ nIdx ] != NULL) )
+ return nIdx;
+
+ ByteString aFontName;
+ mpXlfd->ToString( aFontName, mnPixelSize, nEncoding );
+
+ mpXFontStruct[ nIdx ] = XLoadQueryFont( mpDisplay, aFontName.GetBuffer() );
+ if ( (mpXFontStruct[nIdx] != NULL) && (mpXFontStruct[nIdx]->fid == 0) )
+ mpXFontStruct[nIdx]->fid = XLoadFont(mpDisplay, aFontName.GetBuffer());
+ return nIdx;
+}
+
+XFontStruct*
+ExtendedFontStruct::GetFontStruct( rtl_TextEncoding nEncoding )
+{
+ int nIdx = LoadEncoding( nEncoding );
+ return nIdx < 0 ? NULL : mpXFontStruct[nIdx] ;
+}
+
+Bool
+ExtendedFontStruct::GetFontBoundingBox( XCharStruct *pCharStruct,
+ int *pAscent, int *pDescent )
+{
+ pCharStruct->lbearing = 0;
+ pCharStruct->rbearing = 0;
+ pCharStruct->width = 0;
+ pCharStruct->ascent = 0;
+ pCharStruct->descent = 0;
+
+ *pAscent = 0;
+ *pDescent = 0;
+
+ int nIdx;
+
+ // check whether there is at least one encoding allready loaded
+ Bool bEmpty = True;
+ for ( nIdx = 0; nIdx < mpXlfd->NumEncodings(); nIdx++ )
+ bEmpty = bEmpty && (mpXFontStruct[nIdx] == NULL);
+ if ( bEmpty )
+ LoadEncoding( mpXlfd->GetAsciiEncoding() );
+
+ // get the max bounding box from all font structs
+ for ( nIdx = 0; nIdx < mpXlfd->NumEncodings(); nIdx++ )
+ if ( mpXFontStruct[ nIdx ] != NULL )
+ {
+ *pAscent = max( mpXFontStruct[nIdx]->ascent, *pAscent );
+ *pDescent = max( mpXFontStruct[nIdx]->descent, *pDescent );
+
+ XCharStruct* pMaxBounds = &(mpXFontStruct[nIdx]->max_bounds);
+
+ pCharStruct->lbearing = max( pMaxBounds->lbearing,
+ pCharStruct->lbearing );
+ pCharStruct->rbearing = max( pMaxBounds->rbearing,
+ pCharStruct->rbearing );
+ pCharStruct->width = max( pMaxBounds->width,
+ pCharStruct->width );
+ pCharStruct->ascent = max( pMaxBounds->ascent,
+ pCharStruct->ascent );
+ pCharStruct->descent = max( pMaxBounds->descent,
+ pCharStruct->descent );
+ }
+
+ return (pCharStruct->width > 0);
+}
+
+Bool
+ExtendedFontStruct::ToImplFontMetricData(ImplFontMetricData *pFontMetric)
+{
+ pFontMetric->mnOrientation = 0;
+ pFontMetric->mnSlant = 0;
+ pFontMetric->mbDevice = TRUE;
+
+ pFontMetric->meCharSet = mpXlfd->GetEncoding( );
+ pFontMetric->meFamily = mpXlfd->GetFamily();
+ pFontMetric->meWeight = mpXlfd->GetWeight();
+ pFontMetric->mePitch = mpXlfd->GetSpacing();
+ pFontMetric->meItalic = mpXlfd->GetItalic();
+ pFontMetric->meType = mpXlfd->GetFontType();
+
+ int nAscent, nDescent;
+ XCharStruct aBoundingBox;
+ if ( GetFontBoundingBox(&aBoundingBox, &nAscent, &nDescent) )
+ {
+ pFontMetric->mnWidth = aBoundingBox.width;
+ pFontMetric->mnAscent = aBoundingBox.ascent;
+ pFontMetric->mnDescent = aBoundingBox.descent;
+ pFontMetric->mnLeading = max(0, aBoundingBox.ascent - nAscent
+ + aBoundingBox.descent - nDescent );
+ // XXX Fix me
+ pFontMetric->mnFirstChar = 0;
+ pFontMetric->mnLastChar = 255;
+
+ return True;
+ }
+ else
+ {
+ return False;
+ }
+}
+
+Bool
+ExtendedFontStruct::Match( const ExtendedXlfd *pXlfd, int nPixelSize ) const
+{
+ if( mpXlfd != pXlfd )
+ return FALSE;
+
+ return mnPixelSize == nPixelSize;
+}
+
+// Get an appropriate x-font that contains a glyph for the given unicode
+// code point.
+// This routine is designed to be called for each character in a text.
+// It first checks the given encoding to optimize for the fact that two
+// adjacent characters in a text most probably have the same encoding
+// In the first call initialize pEncodingInOut to dontknow, this causes
+// EncodingHasChar() to fail and thus bootstraps the encoding, otherwise
+// make sure that the initial value of pFontInOut matches the encoding and
+// that the encoding is valid for the font.
+Bool
+ExtendedFontStruct::GetFontStruct( sal_Unicode nChar,
+ rtl_TextEncoding *pEncodingInOut, XFontStruct **pFontInOut,
+ SalConverterCache *pCvt )
+{
+ if ( pCvt->EncodingHasChar(*pEncodingInOut, nChar) )
+ {
+ return True;
+ }
+ else
+ {
+ for ( int nIdx = 0; nIdx < mpXlfd->NumEncodings(); nIdx++ )
+ {
+ rtl_TextEncoding nEnc = mpXlfd->GetEncoding(nIdx);
+ if ( (nEnc != *pEncodingInOut)
+ && pCvt->EncodingHasChar(nEnc, nChar) )
+ {
+ *pEncodingInOut = nEnc;
+ *pFontInOut = GetFontStruct( nEnc );
+ return True;
+ }
+ }
+ }
+
+ return False;
+}
+
+
+// ---------------------------------------------------------------------------
+// utility functions to handle xfontstruct information, this is all to
+// calculate charwidth information
+// ---------------------------------------------------------------------------
+
+static Bool
+CharExists( const XCharStruct* pChar )
+{
+ if ( pChar == NULL )
+ return False;
+
+ return pChar->width
+ || pChar->ascent || pChar->descent
+ || pChar->lbearing || pChar->rbearing;
+}
+
+// this relies on non-null per_char information in the fontstruct
+static XCharStruct*
+GetCharinfo( const XFontStruct *pXFontStruct, sal_MultiByte nChar )
+{
+ unsigned int nRow = nChar >> 8;
+ unsigned int nCol = nChar & 0xFF;
+
+ int nMinRow = pXFontStruct->min_byte1;
+ int nMaxRow = pXFontStruct->max_byte1;
+ int nMinCol = pXFontStruct->min_char_or_byte2;
+ int nMaxCol = pXFontStruct->max_char_or_byte2;
+
+ if ( nRow >= nMinRow && nRow <= nMaxRow
+ && nCol >= nMinCol && nCol <= nMaxCol )
+ {
+ return &pXFontStruct->per_char[
+ (nRow-nMinRow) * (nMaxCol-nMinCol+1) + (nCol-nMinCol) ];
+ }
+
+ return NULL;
+}
+
+static sal_Size
+QueryCharWidth16( Display* pDisplay, XLIB_Font nFontID, sal_MultiByte nChar,
+ sal_Size nDefaultWidth )
+{
+ int nDirection, nFontAscent, nFontDescent;
+ XCharStruct aBoundingBox;
+
+ XQueryTextExtents16( pDisplay, nFontID, (XChar2b*)&nChar, 1,
+ &nDirection, &nFontAscent, &nFontDescent, &aBoundingBox );
+
+ return CharExists( &aBoundingBox ) ? aBoundingBox.width : nDefaultWidth;
+}
+
+static sal_Size
+QueryCharWidth8( XFontStruct* pXFontStruct, sal_Char nChar,
+ sal_Size nDefaultWidth )
+{
+ int nDirection, nFontAscent, nFontDescent;
+ XCharStruct aBoundingBox;
+
+ XTextExtents( pXFontStruct, &nChar, 1,
+ &nDirection, &nFontAscent, &nFontDescent, &aBoundingBox );
+
+ return CharExists( &aBoundingBox ) ? aBoundingBox.width : nDefaultWidth;
+}
+
+// the default width is the width of the question mark since this is the
+// character which is displayed for unconvertable unicode chars
+sal_Size
+ExtendedFontStruct::GetDefaultWidth( SalConverterCache* pCvt )
+{
+ rtl_TextEncoding nEncoding = mpXlfd->GetAsciiEncoding();
+ XFontStruct* pXFontStruct = GetFontStruct( nEncoding );
+
+ if ( pXFontStruct != NULL )
+ {
+ sal_Unicode nQuestionMark = 0x3f;
+ sal_MultiByte nChar;
+ sal_Char pBuffer[8];
+
+ sal_Size nSize = ConvertStringUTF16( &nQuestionMark, 1, pBuffer,
+ sizeof(pBuffer), pCvt->GetU2TConverter(nEncoding) );
+ if ( nSize == 2 )
+ {
+ nChar = ((sal_MultiByte)pBuffer[0] << 8)
+ + (sal_MultiByte)pBuffer[1];
+ return QueryCharWidth16( mpDisplay, pXFontStruct->fid, nChar, 0 );
+ }
+ else
+ if ( nSize == 1 )
+ {
+ return QueryCharWidth8( pXFontStruct, pBuffer[0], 0 );
+ }
+ else
+ {
+ return QueryCharWidth8( pXFontStruct, nQuestionMark, 0 );
+ }
+ }
+
+ return 0;
+}
+
+// Handle single byte fonts which do not require conversion, this exploits
+// the fact that unicode equals latin1 or ansi1252 in the range [0..0xff] and
+// is compatible with iso8859-X at least in the range to 0x7f
+sal_Size
+ExtendedFontStruct::GetCharWidth8( sal_Unicode nFrom, sal_Unicode nTo,
+ long *pWidthArray, rtl_TextEncoding nEncoding )
+{
+ if ( !(nFrom <= nTo) )
+ return 0;
+
+ XFontStruct* pXFontStruct = GetFontStruct( nEncoding );
+ if ( pXFontStruct == NULL )
+ return 0;
+
+ // query the font metrics
+ if ( (pXFontStruct->max_bounds.width == pXFontStruct->min_bounds.width)
+ || (pXFontStruct->per_char == NULL) )
+ {
+ // fixed width font
+ for ( int nIdx = nFrom; nIdx <= nTo; nIdx++, pWidthArray++ )
+ *pWidthArray = mnDefaultWidth;
+ }
+ else
+ {
+ // variable width font
+ int nMinChar = pXFontStruct->min_char_or_byte2;
+ int nMaxChar = pXFontStruct->max_char_or_byte2;
+
+ int nIdx = nFrom;
+
+ for ( ; nIdx < min(nTo, nMinChar); nIdx++, pWidthArray++ )
+ *pWidthArray = mnDefaultWidth;
+ for ( ; nIdx <= min(nTo, nMaxChar); nIdx++, pWidthArray++ )
+ {
+ XCharStruct* pChar = &(pXFontStruct->per_char[nIdx - nMinChar]);
+ *pWidthArray = CharExists(pChar) ? pChar->width : mnDefaultWidth;
+ }
+ for ( ; nIdx <= nTo; nIdx++, pWidthArray++ )
+ *pWidthArray = mnDefaultWidth;
+ }
+
+ // return amount of handled chars
+ return nTo - nFrom + 1;
+}
+
+// Handle utf16 encoded fonts, which do not require conversion
+sal_Size
+ExtendedFontStruct::GetCharWidthUTF16( sal_Unicode nFrom, sal_Unicode nTo,
+ long *pWidthArray )
+{
+ if ( !(nFrom <= nTo) )
+ return 0;
+
+ XFontStruct* pXFontStruct = GetFontStruct( RTL_TEXTENCODING_UNICODE );
+ FontPitch nSpacing = mpXlfd->GetSpacing( RTL_TEXTENCODING_UNICODE );
+
+ if ( pXFontStruct == NULL )
+ return 0;
+
+ // query the font metrics
+ if ( nSpacing == PITCH_VARIABLE
+ && pXFontStruct->per_char == NULL)
+ {
+ // get per_char information from the server
+ for ( sal_Unicode nIdx = nFrom; nIdx <= nTo; nIdx++, pWidthArray++ )
+ *pWidthArray = QueryCharWidth16( mpDisplay, pXFontStruct->fid,
+ nIdx, mnDefaultWidth );
+ }
+ else
+ if ( (pXFontStruct->max_bounds.width == pXFontStruct->min_bounds.width)
+ || (pXFontStruct->per_char == NULL) )
+ {
+ // really a fixed width font
+ for ( sal_Unicode nIdx = nFrom; nIdx <= nTo; nIdx++, pWidthArray++ )
+ *pWidthArray = mnDefaultWidth;
+ }
+ else
+ {
+ // get per_char information from the xfontstruct
+ for ( sal_Unicode nIdx = nFrom; nIdx <= nTo; nIdx++, pWidthArray++ )
+ {
+ XCharStruct* pChar = GetCharinfo( pXFontStruct, nIdx );
+ *pWidthArray = CharExists(pChar) ? pChar->width : mnDefaultWidth;
+ }
+ }
+
+ // return amount of handled chars
+ return nTo - nFrom + 1;
+}
+
+// handle non unicode fonts that are converted into encoding mathing the
+// font in fontstruct, 8 and 16 bit fonts are handled the same way
+sal_Size
+ExtendedFontStruct::GetCharWidth16( SalConverterCache *pCvt,
+ sal_Unicode nFrom, sal_Unicode nTo, long *pWidthArray )
+{
+ if ( !(nFrom <= nTo) )
+ return 0;
+
+ rtl_TextEncoding nEncoding = mpXlfd->GetAsciiEncoding();
+ XFontStruct *pXFontStruct = GetFontStruct( nEncoding );
+
+ if ( pXFontStruct == NULL )
+ return 0;
+
+ unsigned char pBuffer[16];
+ sal_MultiByte nChar;
+
+ for ( sal_Unicode nIdx = nFrom ; nIdx <= nTo ; nIdx++, pWidthArray++ )
+ {
+ Bool bValid;
+ FontPitch nSpacing;
+ sal_Size nSize;
+
+ // get a matching fontstruct
+ if ( bValid = GetFontStruct( nIdx, &nEncoding, &pXFontStruct, pCvt ) )
+ {
+ nSpacing = mpXlfd->GetSpacing( nEncoding );
+ nSize = ConvertStringUTF16( &nIdx, 1,
+ (sal_Char*)pBuffer, sizeof(pBuffer),
+ pCvt->GetU2TConverter(nEncoding) );
+ }
+
+ // query font metrics
+ if ( bValid && (nSize == 1 || nSize == 2) )
+ {
+ nChar = nSize == 1 ? (sal_MultiByte)pBuffer[0] :
+ ((sal_MultiByte)pBuffer[0] << 8) + (sal_MultiByte)pBuffer[1];
+
+ if ( nSpacing == PITCH_VARIABLE
+ && pXFontStruct->per_char == NULL)
+ {
+ // get per_char information from the x-server
+ *pWidthArray = QueryCharWidth16( mpDisplay, pXFontStruct->fid,
+ nChar, mnDefaultWidth );
+ }
+ else
+ if ( ( pXFontStruct->max_bounds.width
+ == pXFontStruct->min_bounds.width)
+ || (pXFontStruct->per_char == NULL) )
+ {
+ // fixed width font
+ *pWidthArray = pXFontStruct->min_bounds.width;
+ }
+ else
+ {
+ // get per_char information from the xfontstruct
+ XCharStruct* pChar = GetCharinfo( pXFontStruct, nChar );
+ *pWidthArray = CharExists(pChar) ? pChar->width : mnDefaultWidth;
+ }
+ }
+ else
+ {
+ // conversion error
+ *pWidthArray = mnDefaultWidth;
+ }
+ }
+
+ // return amount of handled chars
+ return nTo - nFrom + 1;
+}
+
+sal_Size
+ExtendedFontStruct::GetCharWidth( SalConverterCache *pCvt,
+ sal_Unicode nFrom, sal_Unicode nTo, long *pWidthArray )
+{
+ int nAsciiRange;
+ sal_Size nConverted = 0;
+
+ rtl_TextEncoding nEncoding = mpXlfd->GetAsciiEncoding(&nAsciiRange);
+
+ // dispatch querying of metrics to most promising encoding candidate
+ if ( nEncoding == RTL_TEXTENCODING_UNICODE )
+ {
+ // if we have a unicode encoded system font than we get the charwidth
+ // straight forward
+ nConverted = GetCharWidthUTF16( nFrom, nTo, pWidthArray );
+ }
+ else
+ {
+ if ( nFrom < nAsciiRange )
+ {
+ // optimize the most frequent case, requesting only the latin1
+ // chars which are mappable to a single encoding
+ nConverted = GetCharWidth8( nFrom, min(nAsciiRange, nTo),
+ pWidthArray, nEncoding );
+ }
+
+ // if further requests are pending, then the according unicode
+ // codepoint has to be dispatched to one of the system fonts and
+ // converted to this fonts encoding
+ nConverted += GetCharWidth16( pCvt, nFrom + nConverted, nTo,
+ pWidthArray + nConverted );
+ }
+
+ return nConverted;
+}
diff --git a/vcl/unx/source/gdi/xlfd_attr.cxx b/vcl/unx/source/gdi/xlfd_attr.cxx
new file mode 100644
index 000000000000..a5571d43311a
--- /dev/null
+++ b/vcl/unx/source/gdi/xlfd_attr.cxx
@@ -0,0 +1,655 @@
+/*************************************************************************
+ *
+ * $RCSfile: xlfd_attr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <alloca.h>
+
+#ifndef XLFD_ATTRIBUTE_HXX
+#include "xlfd_attr.hxx"
+#endif
+#ifndef _RTL_TENCINFO_H
+#include <rtl/tencinfo.h>
+#endif
+#ifndef _VCL_VCLENUM_HXX
+#include <vclenum.hxx>
+#endif
+
+// ---------------------------------------------------------------------------
+//
+//
+// Attribute is a container for simple name value pairs
+// eg. ( "times", FAMILY_ROMAN ) or ( "demi bold", WEIGHT_SEMIBOLD )
+// enriched with an annotation which is a pretty-printed version of the
+// string, i.e. "itc avant garde" would get an annotation of "Itc Avant Garde"
+//
+//
+// ---------------------------------------------------------------------------
+
+// release the stored string
+void
+Attribute::Release()
+{
+ if ( mpAnnotation != NULL )
+ delete mpAnnotation;
+ if ( mpName != NULL )
+ free( (void*)mpName );
+}
+
+// get a private copy of the given argument
+void
+Attribute::SetName( const char *p, int nLen )
+{
+ mpName = (char*)malloc( nLen + 1 );
+ mnLength = nLen;
+ memcpy( (void*)mpName, p, mnLength );
+ ((char*)mpName)[ mnLength ] = '\0';
+}
+
+// Compare whether two strings a equal for the first nLen bytes
+// i.e. arial == arialnarrow
+int
+Attribute::Compare( const char *p, int nLen )
+{
+ return strncmp( mpName, p, nLen );
+}
+
+// Compare two strings, they have to be equal for nLen bytes, after nLen
+// bytes both strings have to be terminated either by '\0' or by '-'
+// this is for comparing a string being a substring in a Xlfd with a
+// zeroterminated string
+Bool
+Attribute::ExactMatch( const char *p, int nLen )
+{
+ Bool bMatch;
+ if ( nLen > 0 )
+ bMatch = Compare( p, nLen ) == 0;
+ else
+ bMatch = True;
+ if ( bMatch )
+ {
+ char c1 = p[ nLen ];
+ char c2 = mpName[ nLen ];
+ bMatch = (c1 == '-' || c1 == '\0') && (c2 == '-' || c2 == '\0');
+ }
+
+ return bMatch;
+}
+
+void
+Attribute::TagFeature( unsigned short nFeature )
+{
+ if ( (nFeature & XLFD_FEATURE_NARROW)
+ && (strstr(mpName, "narrow") != NULL) )
+ {
+ mnFeature |= XLFD_FEATURE_NARROW;
+ }
+ if ( (nFeature & XLFD_FEATURE_OL_CURSOR)
+ && (strcmp(mpName, "open look cursor") == 0) )
+ {
+ mnFeature |= XLFD_FEATURE_OL_CURSOR;
+ }
+ if ( (nFeature & XLFD_FEATURE_OL_GLYPH)
+ && (strcmp(mpName, "open look glyph") == 0) )
+ {
+ mnFeature |= XLFD_FEATURE_OL_GLYPH;
+ }
+
+ if ( nFeature & XLFD_FEATURE_REDUNDANTSTYLE )
+ {
+ switch ( mpName[0] )
+ {
+ case '\0':
+ mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
+ break;
+
+ case 'b':
+ if ( (strcmp(mpName, "bold") == 0)
+ || (strcmp(mpName, "bold italic") == 0)
+ || (strcmp(mpName, "bold sans") == 0) )
+ mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
+ break;
+
+ case 'd':
+ if ( (strcmp(mpName, "demi") == 0)
+ || (strcmp(mpName, "demi italic") == 0) )
+ mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
+ break;
+
+ case 'i':
+ if ( strcmp(mpName, "italic") == 0 )
+ mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
+ break;
+
+ case 's':
+ if ( (strcmp(mpName, "sans") == 0)
+ || (strcmp(mpName, "serif") == 0) )
+ mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
+ break;
+ }
+ }
+}
+
+// given Attribute classifications, strings have to be in alphabetical
+// order, since they are treated by binary search algorithm
+
+#define InitializeAttributeWith( p, a ) p, sizeof(p) - 1, a, 0, NULL
+#define MembersOf( p ) (sizeof(p) / sizeof(p[0]) )
+
+const Attribute pFamilyAttribute[] = {
+ { InitializeAttributeWith( "arial", FAMILY_SWISS ) },
+ { InitializeAttributeWith( "arioso", FAMILY_SCRIPT ) },
+ { InitializeAttributeWith( "avant garde", FAMILY_SWISS ) },
+ { InitializeAttributeWith( "avantgarde", FAMILY_SWISS ) },
+ { InitializeAttributeWith( "bembo", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "bookman", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "conga", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "courier", FAMILY_MODERN ) },
+ { InitializeAttributeWith( "curl", FAMILY_SCRIPT ) },
+ { InitializeAttributeWith( "fixed", FAMILY_MODERN ) },
+ { InitializeAttributeWith( "gill", FAMILY_SWISS ) },
+ { InitializeAttributeWith( "helmet", FAMILY_MODERN ) },
+ { InitializeAttributeWith( "helvetica", FAMILY_SWISS ) },
+ { InitializeAttributeWith( "international", FAMILY_MODERN ) },
+ { InitializeAttributeWith( "lucida", FAMILY_SWISS ) },
+ { InitializeAttributeWith( "new century schoolbook", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "palatino", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "roman", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "sans serif", FAMILY_SWISS ) },
+ { InitializeAttributeWith( "sansserif", FAMILY_SWISS ) },
+ { InitializeAttributeWith( "serf", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "serif", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "times", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "utopia", FAMILY_ROMAN ) },
+ { InitializeAttributeWith( "zapf chancery", FAMILY_SCRIPT ) },
+ { InitializeAttributeWith( "zapfchancery", FAMILY_SCRIPT ) }
+};
+
+const Attribute pWeightAttribute[] = {
+ { InitializeAttributeWith( "black", WEIGHT_BLACK ) },
+ { InitializeAttributeWith( "bold", WEIGHT_BOLD ) },
+ { InitializeAttributeWith( "book", WEIGHT_LIGHT ) },
+ { InitializeAttributeWith( "demi", WEIGHT_SEMIBOLD ) },
+ { InitializeAttributeWith( "demi bold", WEIGHT_SEMIBOLD ) },
+ { InitializeAttributeWith( "demibold", WEIGHT_SEMIBOLD ) },
+ { InitializeAttributeWith( "light", WEIGHT_LIGHT ) },
+ { InitializeAttributeWith( "medium", WEIGHT_MEDIUM ) },
+ { InitializeAttributeWith( "normal", WEIGHT_NORMAL ) },
+ { InitializeAttributeWith( "regular", WEIGHT_NORMAL ) },
+ { InitializeAttributeWith( "roman", WEIGHT_NORMAL ) },
+ { InitializeAttributeWith( "semicondensed", WEIGHT_LIGHT ) },
+ { InitializeAttributeWith( "ultrabold", WEIGHT_ULTRABOLD ) }
+};
+
+const Attribute pSlantAttribute[] = {
+ { InitializeAttributeWith( "i", ITALIC_NORMAL ) },
+ { InitializeAttributeWith( "o", ITALIC_OBLIQUE ) },
+ { InitializeAttributeWith( "r", ITALIC_NONE ) }
+};
+
+const Attribute pSetwidthAttribute[] = {
+ { InitializeAttributeWith( "bold", WIDTH_SEMI_EXPANDED ) },
+ { InitializeAttributeWith( "condensed", WIDTH_CONDENSED ) },
+ { InitializeAttributeWith( "double wide", WIDTH_ULTRA_EXPANDED ) },
+ { InitializeAttributeWith( "expanded", WIDTH_EXPANDED ) },
+ { InitializeAttributeWith( "extracondensed", WIDTH_EXTRA_CONDENSED ) },
+ { InitializeAttributeWith( "extraexpanded", WIDTH_EXTRA_EXPANDED ) },
+ { InitializeAttributeWith( "medium", WIDTH_NORMAL ) },
+ { InitializeAttributeWith( "narrow", WIDTH_CONDENSED ) },
+ { InitializeAttributeWith( "normal", WIDTH_NORMAL ) },
+ { InitializeAttributeWith( "semicondensed", WIDTH_SEMI_CONDENSED ) },
+ { InitializeAttributeWith( "semiexpanded", WIDTH_SEMI_EXPANDED ) },
+ { InitializeAttributeWith( "ultracondensed", WIDTH_ULTRA_CONDENSED ) },
+ { InitializeAttributeWith( "ultraexpanded", WIDTH_ULTRA_EXPANDED ) },
+ { InitializeAttributeWith( "wide", WIDTH_EXPANDED ) }
+};
+
+const Attribute pEnhancedCharsetAttribute[] = {
+ { InitializeAttributeWith( "iso8859-1", RTL_TEXTENCODING_MS_1252 ) },
+ { InitializeAttributeWith( "iso8859_1", RTL_TEXTENCODING_MS_1252 ) }
+};
+
+// -------------------------------------------------------------------------
+//
+// String handling utility functions
+//
+// -------------------------------------------------------------------------
+
+
+void
+AppendAttribute( Attribute *pAttribute, ByteString &rString )
+{
+ if ( pAttribute == NULL )
+ return ;
+
+ int nLength = pAttribute->GetLength();
+ char *pBuffer = (char*)alloca( nLength + 1);
+
+ pBuffer[ 0 ] = '-';
+ memcpy( pBuffer + 1, pAttribute->GetName(), nLength );
+ rString.Append( pBuffer, nLength + 1);
+}
+
+//
+// Prettify the font name: make each leading character of a fontname
+// uppercase. For example
+// times new roman -> Times New Roman
+//
+
+static void
+ToUpper( char *pCharacter )
+{
+ // replace [a,z] with [A,Z]
+ if ( (*pCharacter >= 97) && (*pCharacter <= 122) )
+ *pCharacter -= 32;
+}
+
+static String*
+Capitalize( const char *pStr, int nLength )
+{
+ char *pCopy = (char*)alloca( nLength + 1 );
+ char *pPtr = pCopy;
+ memcpy( pPtr, pStr, nLength + 1 );
+
+ // loop over string data and uppercase first char and all chars
+ // following a space (other white space would be unexpected here)
+ char nPreviousChar = ' ';
+ while ( *pPtr )
+ {
+ if ( nPreviousChar == ' ' )
+ ToUpper( pPtr );
+ nPreviousChar = *pPtr++;
+ }
+
+ return new String( pCopy, RTL_TEXTENCODING_ISO_8859_1 );
+}
+
+String*
+AnnotateString( const Attribute& rAttribute )
+{
+ return Capitalize(rAttribute.GetName(), rAttribute.GetLength());
+}
+
+String*
+AnnotateSlant( const Attribute& rAttribute )
+{
+ const char* pStr = rAttribute.GetName();
+ int nLen = rAttribute.GetLength();
+
+ static const struct {
+ const char *pFrom; const char *pTo;
+ } pTranslation[] = {
+ { "r", "Roman" },
+ { "o", "Oblique" },
+ { "i", "Italic" },
+ { "ri", "Reverse Italic" },
+ { "ro", "Reverse Oblique" },
+ { "ot", "Other" }
+ };
+
+ for ( int i = 0; i < MembersOf(pTranslation); i++ )
+ if ( strcmp(pStr, pTranslation[i].pFrom) == 0 )
+ {
+ return new String( pTranslation[i].pTo,
+ RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ return Capitalize(pStr, nLen);
+}
+
+String*
+AnnotateNone( const Attribute& rAttribute )
+{
+ return new String();
+}
+
+// ---------------------------------------------------------------------------
+//
+//
+// manage global lists of Attributes
+// since XListFonts does never list more than 64K fonts this storage does
+// handle array size and indices with unsigned short values for low
+// memory consumption
+//
+//
+// ---------------------------------------------------------------------------
+
+AttributeStorage::AttributeStorage( unsigned short nDefaultValue ) :
+ mpList( NULL ),
+ mnSize( 0 ),
+ mnCount( 0 ),
+ mnLastmatch( 0 ),
+ mnDefaultValue( nDefaultValue )
+{
+}
+
+AttributeStorage::~AttributeStorage()
+{
+ if ( mpList != NULL )
+ {
+ for ( int i = 0; i < mnCount; i++ )
+ mpList[i].Release();
+ free( mpList );
+ }
+}
+
+#ifdef DEBUG
+void
+AttributeStorage::Dump()
+{
+ fprintf(stderr, "AttributeStorage: size=%i, used=%i\n", mnSize, mnCount);
+ for ( int i = 0; i < mnCount; i++ )
+ {
+ ByteString aAnnotation = ByteString(
+ mpList[i].GetAnnotation(),
+ RTL_TEXTENCODING_ISO_8859_1 );
+ fprintf(stderr, "\t%4i: <%s><len=%i><val=%i><%s>\n", i, mpList[i].GetName(),
+ mpList[i].GetLength(), mpList[i].GetValue(),
+ aAnnotation.GetBuffer() );
+ }
+ fprintf(stderr, "\n");
+}
+#endif
+
+Attribute*
+AttributeStorage::Retrieve( unsigned short nIndex ) const
+{
+ return nIndex < mnCount ? &mpList[ nIndex ] : (Attribute*)NULL ;
+}
+
+// pClassification contains a list of name-value pairs. If names in
+// the AttributeStorage match those in the pClassification then
+// the according value is copied. Matching means match for the length
+// of the string in pClassification (i.e. arial matches arialnarrow)
+// the strings in pClassification must be in alphabetical order, all
+// strings Lowercase
+void
+AttributeStorage::AddClassification( Attribute *pClassification,
+ unsigned short nNum )
+{
+ for ( int i = 0; i < mnCount; i++ )
+ {
+ unsigned int nLower = 0;
+ unsigned int nUpper = nNum;
+ unsigned int nCurrent;
+ int nComparison;
+ Attribute *pHaystack, *pNeedle;
+
+ pNeedle = &mpList[ i ];
+
+ // binary search
+ while ( nLower < nUpper )
+ {
+ nCurrent = (nLower + nUpper) / 2;
+ pHaystack = &pClassification[ nCurrent ];
+ nComparison = pNeedle->Compare( pHaystack->GetName(),
+ pHaystack->GetLength() );
+ if (nComparison < 0)
+ nUpper = nCurrent;
+ else
+ if (nComparison > 0)
+ nLower = nCurrent + 1;
+ else
+ break;
+ }
+
+ // if there's a match store the according classification in the
+ // Attribute storage, otherwise do nothing since defaults are
+ // already provided in AttributeStorage::Insert()
+ if ( nComparison == 0 )
+ pNeedle->SetValue( pHaystack->GetValue() );
+ }
+}
+
+void
+AttributeStorage::AddClassification( AttributeClassifierT Classify )
+{
+ for ( int i = 0; i < mnCount; i++ )
+ {
+ Attribute& rCurrent = mpList[i] ;
+ int nValue = Classify( rCurrent.GetName() );
+ rCurrent.SetValue( nValue );
+ }
+}
+
+void
+AttributeStorage::AddAnnotation( AttributeAnnotatorT Annotate )
+{
+ for ( int i = 0; i < mnCount; i++ )
+ {
+ String* pAnnotation = Annotate( mpList[i] );
+ mpList[i].SetAnnotation( pAnnotation );
+ }
+}
+
+void
+AttributeStorage::TagFeature( unsigned short nFeature )
+{
+ for ( int i = 0; i < mnCount; i++ )
+ mpList[i].TagFeature( nFeature );
+}
+
+// Enlarge the list of Attributes
+void
+AttributeStorage::Enlarge()
+{
+ if ( mnSize == 0 )
+ {
+ mnSize = 8;
+ mpList = (Attribute*) malloc( mnSize * sizeof(Attribute) );
+ }
+ else
+ {
+ mnSize = mnSize < 32768 ? (mnSize * 2) : 65535;
+ mpList = (Attribute*) realloc( mpList, mnSize * sizeof(Attribute) );
+ }
+}
+
+// nLength is the length as it would be reported by strlen(3)
+// for an null-terminated string. if a string is part of a Xlfd
+// the field separator '-' is taken as '\0'
+// the AttributeStorage itself is NOT sorted to make sure that the
+// leased keys are still valid
+unsigned short
+AttributeStorage::Insert( const char *pString, int nLength )
+{
+ // check whether the last match is still equal to the current
+ // string since XListFonts lists fonts in sets of similar fontnames
+ if ( mnLastmatch < mnCount )
+ {
+ if ( mpList[mnLastmatch].ExactMatch(pString, nLength) )
+ return mnLastmatch;
+ }
+
+ // otherwise search in list
+ for ( int i = 0; i < mnCount; i++ )
+ {
+ if ( mpList[i].ExactMatch(pString, nLength) )
+ return mnLastmatch = i;
+ }
+
+ // if still not found we have to Insert the new string
+ if ( mnSize == mnCount )
+ Enlarge();
+ mpList[mnCount].SetName( pString, nLength );
+ mpList[mnCount].SetValue( mnDefaultValue );
+ mpList[mnCount].SetAnnotation( NULL );
+ mpList[mnCount].SetFeature( XLFD_FEATURE_NONE );
+ mnLastmatch = mnCount;
+ mnCount = mnCount < 65535 ? mnCount + 1 : mnCount;
+
+ return mnLastmatch;
+}
+
+
+// ---------------------------------------------------------------------------
+//
+//
+// Attribute provider is a frame for a set of AttributeStorages.
+//
+//
+// ---------------------------------------------------------------------------
+
+AttributeProvider::AttributeProvider( eDeviceT eOutputDevice ) :
+ meOutputDevice( eOutputDevice )
+{
+ mpField[eXLFDFoundry ] = new AttributeStorage(0);
+ mpField[eXLFDFamilyName ] = new AttributeStorage(FAMILY_DONTKNOW);
+ mpField[eXLFDWeightName ] = new AttributeStorage(WEIGHT_NORMAL);
+ mpField[eXLFDSlant ] = new AttributeStorage(ITALIC_NONE);
+ mpField[eXLFDSetwidthName] = new AttributeStorage(WIDTH_NORMAL);
+ mpField[eXLFDAddstyleName] = new AttributeStorage(RTL_TEXTENCODING_DONTKNOW);
+ mpField[eXLFDCharset ] = new AttributeStorage(RTL_TEXTENCODING_DONTKNOW);
+}
+
+AttributeProvider::~AttributeProvider()
+{
+ for ( int i = 0; i < eXLFDMaxEntry; i++ )
+ delete mpField[ i ];
+}
+
+#ifdef DEBUG
+void
+AttributeProvider::Dump()
+{
+ for ( int i = 0; i < eXLFDMaxEntry; i++ )
+ mpField[ i ]->Dump();
+}
+#endif
+
+extern "C" rtl_TextEncoding
+GetTextEncodingFromAddStylename( const sal_Char *pAddStylename )
+{
+ int nBufferLength = strlen( pAddStylename ) + 1;
+ sal_Char *pBuffer = (sal_Char*)alloca( nBufferLength );
+ for ( int i = 0; i < nBufferLength; i++ )
+ pBuffer[i] = pAddStylename[i] == '_' ? '-' : pAddStylename[i] ;
+
+ return rtl_getTextEncodingFromUnixCharset( pBuffer );
+}
+
+
+// classification information is needed before sorting because of course the
+// classification is the sort criteria
+void
+AttributeProvider::AddClassification()
+{
+ /* mpField[ eXLFDFoundry ] doesn't need classification */
+ mpField[ eXLFDFamilyName ]->AddClassification(
+ (Attribute*)pFamilyAttribute,
+ MembersOf(pFamilyAttribute) );
+ mpField[ eXLFDWeightName ]->AddClassification(
+ (Attribute*)pWeightAttribute,
+ MembersOf(pWeightAttribute) );
+ mpField[ eXLFDSlant ]->AddClassification(
+ (Attribute*)pSlantAttribute,
+ MembersOf(pSlantAttribute) );
+ mpField[ eXLFDSetwidthName ]->AddClassification(
+ (Attribute*)pSetwidthAttribute,
+ MembersOf(pSetwidthAttribute) );
+ mpField[ eXLFDAddstyleName ]->AddClassification(
+ GetTextEncodingFromAddStylename );
+ mpField[ eXLFDCharset ]->AddClassification(
+ rtl_getTextEncodingFromUnixCharset );
+
+ // Postscript Fonts usually have usefull glyphs in the area 128 - 160 these
+ // are not accessible through the latin1 encoding but through the
+ // ansi1252 encoding
+ if ( meOutputDevice == eDevicePrinter )
+ {
+ mpField[ eXLFDAddstyleName ]->AddClassification(
+ (Attribute*)pEnhancedCharsetAttribute,
+ MembersOf(pEnhancedCharsetAttribute) );
+ mpField[ eXLFDCharset ]->AddClassification(
+ (Attribute*)pEnhancedCharsetAttribute,
+ MembersOf(pEnhancedCharsetAttribute) );
+ }
+}
+
+// add some pretty print description
+void
+AttributeProvider::AddAnnotation()
+{
+ mpField[ eXLFDFoundry ]->AddAnnotation( AnnotateNone );
+ mpField[ eXLFDFamilyName ]->AddAnnotation( AnnotateString );
+ mpField[ eXLFDWeightName ]->AddAnnotation( AnnotateString );
+ mpField[ eXLFDSlant ]->AddAnnotation( AnnotateSlant );
+ mpField[ eXLFDSetwidthName ]->AddAnnotation( AnnotateString );
+ mpField[ eXLFDAddstyleName ]->AddAnnotation( AnnotateNone );
+ mpField[ eXLFDCharset ]->AddAnnotation( AnnotateNone );
+}
+
+// this is the misc or any section: dirty hacks for dirty xlfd usage
+void
+AttributeProvider::TagFeature()
+{
+ mpField[ eXLFDFamilyName ]->TagFeature(
+ XLFD_FEATURE_OL_GLYPH
+ | XLFD_FEATURE_OL_CURSOR
+ | XLFD_FEATURE_NARROW );
+
+ mpField[ eXLFDSetwidthName ]->TagFeature(
+ XLFD_FEATURE_NARROW );
+
+ mpField[ eXLFDAddstyleName ]->TagFeature(
+ XLFD_FEATURE_REDUNDANTSTYLE );
+}
+
diff --git a/vcl/unx/source/gdi/xlfd_attr.hxx b/vcl/unx/source/gdi/xlfd_attr.hxx
new file mode 100644
index 000000000000..a48da64c0c39
--- /dev/null
+++ b/vcl/unx/source/gdi/xlfd_attr.hxx
@@ -0,0 +1,266 @@
+/*************************************************************************
+ *
+ * $RCSfile: xlfd_attr.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef XLFD_ATTRIBUTE_HXX
+#define XLFD_ATTRIBUTE_HXX
+
+#ifndef _SALUNX_H
+#include <salunx.h>
+#endif
+#ifndef _STRING_HXX
+#include <tools/string.hxx>
+#endif
+
+
+struct Attribute {
+
+ const char* mpName;
+ unsigned short mnLength;
+ unsigned short mnValue;
+ unsigned short mnFeature;
+ String* mpAnnotation;
+
+ const char* GetName() const
+ { return mpName; }
+ unsigned short GetValue() const
+ { return mnValue; }
+ unsigned short GetLength() const
+ { return mnLength; }
+ Bool HasFeature( unsigned short nFeature ) const
+ { return ((mnFeature & nFeature) != 0); }
+ const String &GetAnnotation() const
+ { return *mpAnnotation; }
+
+ void SetName( const char *p, int nLen );
+ void SetValue( unsigned short nIn )
+ { mnValue = nIn; }
+ void SetAnnotation( String *pString )
+ { mpAnnotation = pString; }
+ void SetFeature( unsigned short nFeature )
+ { mnFeature = nFeature; }
+ void TagFeature( unsigned short nFeature );
+
+ int Compare( const char *p, int nLen );
+ Bool ExactMatch( const char *p, int nLen );
+ void Release();
+};
+
+
+void
+AppendAttribute( Attribute *pAttribute, ByteString &rString );
+
+
+typedef String*(*AttributeAnnotatorT)(const Attribute &rAttribute);
+extern "C" {
+typedef rtl_TextEncoding(*AttributeClassifierT)(const char* pStr);
+}
+
+#define XLFD_FEATURE_NONE 0x00
+#define XLFD_FEATURE_NARROW 0x01
+#define XLFD_FEATURE_OL_GLYPH 0x02
+#define XLFD_FEATURE_OL_CURSOR 0x04
+#define XLFD_FEATURE_REDUNDANTSTYLE 0x08
+
+// ---------------------------------------------------------------------------
+//
+//
+// manage global lists of Attributes
+// since XListFonts does never list more than 64K fonts this storage does
+// handle array size and indices with unsigned short values for low
+// memory consumption
+//
+//
+// ---------------------------------------------------------------------------
+
+class AttributeStorage {
+
+ private:
+
+ Attribute* mpList;
+ unsigned short mnSize;
+ unsigned short mnCount;
+ unsigned short mnLastmatch;
+ unsigned short mnDefaultValue;
+
+ void Enlarge();
+ AttributeStorage();
+
+ public:
+
+ AttributeStorage( unsigned short nDefaultValue );
+ ~AttributeStorage();
+ unsigned short Insert( const char *pString, int nLength );
+ Attribute* Retrieve( unsigned short nIndex ) const ;
+ void AddClassification( Attribute *pClassification,
+ unsigned short nNum );
+ void AddClassification( AttributeClassifierT Classify );
+ void TagFeature( unsigned short nFeature );
+ void AddAnnotation( AttributeAnnotatorT Annotate );
+ #ifdef DEBUG
+ void Dump();
+ #endif
+};
+
+
+// ---------------------------------------------------------------------------
+//
+//
+// Attribute provider is a frame for a set of AttributeStorages. For XLFD
+// interpretation and efficient storage, AttributeStorages for foundry,
+// family_name, weight_name, slant, setwidth_name, add_style_name and combined
+// charset_registry and charset_encoding are used. pixel_size, point_size,
+// resolution_x and resolution_y are stored as numbers. please note that this
+// does not allow storage of matrix-enhanced fonts. spacing is stored as
+// a char, since only the 'm', 'c' and 'p' types are defined.
+//
+//
+// ---------------------------------------------------------------------------
+
+typedef enum eXLFDAttributeT {
+ eXLFDFoundry = 0,
+ eXLFDFamilyName,
+ eXLFDWeightName,
+ eXLFDSlant,
+ eXLFDSetwidthName,
+ eXLFDAddstyleName,
+ eXLFDCharset,
+ eXLFDMaxEntry
+};
+
+typedef enum eDeviceT {
+ eDeviceDontKnow = 0,
+ eDevicePrinter,
+ eDeviceDisplay
+};
+
+class AttributeProvider {
+
+ private:
+
+ AttributeStorage* mpField[ eXLFDMaxEntry ];
+
+ AttributeStorage* GetField( eXLFDAttributeT eXLFDField )
+ { return mpField[ eXLFDField]; }
+ eDeviceT meOutputDevice;
+ public:
+
+ AttributeProvider( eDeviceT eOutputDevice );
+ ~AttributeProvider();
+
+ void AddClassification();
+ void AddAnnotation();
+ void TagFeature();
+ #ifdef DEBUG
+ void Dump();
+ #endif
+
+ eDeviceT GetDevice() const
+ { return meOutputDevice; }
+
+ // these are just shortcuts or proxies for the most common used
+ // AttributeStorage functionality
+ AttributeStorage* GetFoundry()
+ { return GetField(eXLFDFoundry); }
+ AttributeStorage* GetFamily()
+ { return GetField(eXLFDFamilyName); }
+ AttributeStorage* GetWeight()
+ { return GetField(eXLFDWeightName); }
+ AttributeStorage* GetSlant()
+ { return GetField(eXLFDSlant); }
+ AttributeStorage* GetSetwidth()
+ { return GetField(eXLFDSetwidthName); }
+ AttributeStorage* GetAddstyle()
+ { return GetField(eXLFDAddstyleName); }
+ AttributeStorage* GetCharset()
+ { return GetField(eXLFDCharset); }
+
+ Attribute* RetrieveFoundry( unsigned short nIndex )
+ { return GetFoundry()->Retrieve(nIndex); }
+ Attribute* RetrieveFamily( unsigned short nIndex )
+ { return GetFamily()->Retrieve(nIndex); }
+ Attribute* RetrieveWeight( unsigned short nIndex )
+ { return GetWeight()->Retrieve(nIndex); }
+ Attribute* RetrieveSlant( unsigned short nIndex )
+ { return GetSlant()->Retrieve(nIndex); }
+ Attribute* RetrieveSetwidth( unsigned short nIndex )
+ { return GetSetwidth()->Retrieve(nIndex); }
+ Attribute* RetrieveAddstyle( unsigned short nIndex )
+ { return GetAddstyle()->Retrieve(nIndex); }
+ Attribute* RetrieveCharset( unsigned short nIndex )
+ { return GetCharset()->Retrieve(nIndex); }
+
+ unsigned short InsertFoundry( const char *pString, int nLength )
+ { return GetFoundry()->Insert(pString, nLength); }
+ unsigned short InsertFamily( const char *pString, int nLength )
+ { return GetFamily()->Insert(pString, nLength); }
+ unsigned short InsertWeight( const char *pString, int nLength )
+ { return GetWeight()->Insert(pString, nLength); }
+ unsigned short InsertSlant( const char *pString, int nLength )
+ { return GetSlant()->Insert(pString, nLength); }
+ unsigned short InsertSetwidth( const char *pString, int nLength )
+ { return GetSetwidth()->Insert(pString, nLength);}
+ unsigned short InsertAddstyle( const char *pString, int nLength )
+ { return GetAddstyle()->Insert(pString, nLength);}
+ unsigned short InsertCharset( const char *pString, int nLength )
+ { return GetCharset()->Insert(pString, nLength); }
+};
+
+#endif /* XLFD_ATTRIBUTE_HXX */
+
diff --git a/vcl/unx/source/gdi/xlfd_extd.cxx b/vcl/unx/source/gdi/xlfd_extd.cxx
new file mode 100644
index 000000000000..2a8a65ccce53
--- /dev/null
+++ b/vcl/unx/source/gdi/xlfd_extd.cxx
@@ -0,0 +1,699 @@
+/*************************************************************************
+ *
+ * $RCSfile: xlfd_extd.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef XLFD_ATTRIBUTE_HXX
+#include "xlfd_attr.hxx"
+#endif
+#ifndef XLFD_SIMPLE_HXX
+#include "xlfd_smpl.hxx"
+#endif
+#ifndef XLFD_EXTENDED_HXX
+#include "xlfd_extd.hxx"
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+
+// --------------------------------------------------------------------------
+//
+// classes for Xlfd handling that contain more than a single encoding.
+// Members that may vary through different encodings are stored in
+// a mpEncodingInfo member. There are three different classes:
+// true scalable fonts (truetype and type1) scalable bitmap fonts
+// (the ugly ones) and bitmap fonts. The ExtendedXlfd stores all the members
+// that are specific to a font outline
+// ( e.g. adobe-times-roman-medium-r-normal- X -p- X )
+// and specifies the interface.
+//
+// --------------------------------------------------------------------------
+
+ExtendedXlfd::EncodingInfo&
+ExtendedXlfd::EncodingInfo::operator= ( const Xlfd *pXlfd )
+{
+ mcSpacing = pXlfd->mcSpacing;
+ mnResolutionX = pXlfd->mnResolutionX;
+ mnResolutionY = pXlfd->mnResolutionY;
+ mnAddstyle = pXlfd->mnAddstyle;
+ mnCharset = pXlfd->mnCharset;
+
+ mnEncoding = pXlfd->GetEncoding();
+
+ return *this;
+}
+
+// ------ base class --------------------------------------------------------
+
+ExtendedXlfd::ExtendedXlfd()
+{
+ mpEncodingInfo = NULL;
+ mnEncodings = 0;
+}
+
+ExtendedXlfd::~ExtendedXlfd()
+{
+ if ( mnEncodings != 0 )
+ free( mpEncodingInfo );
+}
+
+inline void*
+Realloc( void *pPtr, sal_Size nSize )
+{
+ return pPtr == NULL ? malloc( nSize ) : realloc( pPtr, nSize );
+}
+
+int
+ExtendedXlfd::GetEncodingIdx( rtl_TextEncoding nEncoding ) const
+{
+ for ( int i = 0; i < mnEncodings; i++ )
+ if ( nEncoding == mpEncodingInfo[i].mnEncoding )
+ return i;
+ return -1;
+}
+
+Bool
+ExtendedXlfd::HasEncoding( rtl_TextEncoding nEncoding ) const
+{
+ return !(GetEncodingIdx( nEncoding ) < 0) ;
+}
+
+rtl_TextEncoding
+ExtendedXlfd::GetEncoding( int i ) const
+{
+ if ( i < mnEncodings && i >= 0 )
+ return mpEncodingInfo[i].mnEncoding;
+
+ return RTL_TEXTENCODING_DONTKNOW;
+}
+
+rtl_TextEncoding
+ExtendedXlfd::GetEncoding() const
+{
+ return mnEncodings == 1 ? mpEncodingInfo[0].mnEncoding : RTL_TEXTENCODING_DONTKNOW;
+}
+
+// query the most unicode / Ascii compatible font: either one of the fonts
+// is utf16 encoded or there's a single byte font which is unicode
+// compatible for the first 256 chars (latin1) or for at least 128
+// chars (most latin-X encodings, cyrillic encodings)
+rtl_TextEncoding
+ExtendedXlfd::GetAsciiEncoding( int *pAsciiRange ) const
+{
+ rtl_TextEncoding nBestEncoding = RTL_TEXTENCODING_DONTKNOW;
+ int nLargestRange = 0x0000;
+
+ for ( int i = 0; i < mnEncodings && nLargestRange < 0xffff; i++ )
+ {
+ rtl_TextEncoding nCurEncoding = mpEncodingInfo[i].mnEncoding;
+ switch ( nCurEncoding )
+ {
+ case RTL_TEXTENCODING_UNICODE:
+ nLargestRange = 0xffff;
+ nBestEncoding = nCurEncoding;
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_1:
+ case RTL_TEXTENCODING_MS_1252:
+ nLargestRange = 0x00ff;
+ nBestEncoding = nCurEncoding;
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_2:
+ case RTL_TEXTENCODING_ISO_8859_4:
+ case RTL_TEXTENCODING_ISO_8859_5:
+ case RTL_TEXTENCODING_ISO_8859_6:
+ case RTL_TEXTENCODING_ISO_8859_7:
+ case RTL_TEXTENCODING_ISO_8859_8:
+ case RTL_TEXTENCODING_ISO_8859_9:
+ case RTL_TEXTENCODING_ISO_8859_13:
+ case RTL_TEXTENCODING_ISO_8859_15:
+ case RTL_TEXTENCODING_MS_1251:
+ case RTL_TEXTENCODING_KOI8_R:
+ case RTL_TEXTENCODING_JIS_X_0201:
+ if ( nLargestRange < 0x0080 )
+ {
+ nLargestRange = 0x0080;
+ nBestEncoding = nCurEncoding;
+ }
+ break;
+
+ default:
+ if ( nLargestRange == 0x0000 )
+ {
+ nBestEncoding = nCurEncoding;
+ }
+ break;
+ }
+ }
+
+ if ( pAsciiRange != NULL )
+ *pAsciiRange = nLargestRange;
+
+ return nBestEncoding;
+}
+
+Bool
+ExtendedXlfd::AddEncoding( const Xlfd *pXlfd )
+{
+ rtl_TextEncoding nEncoding = pXlfd->GetEncoding();
+
+ if ( HasEncoding(nEncoding) )
+ return False;
+
+ if ( mnEncodings == 0 )
+ {
+ // bootstrap
+ mnFoundry = pXlfd->mnFoundry;
+ mnFamily = pXlfd->mnFamily;
+ mnWeight = pXlfd->mnWeight;
+ mnSlant = pXlfd->mnSlant;
+ mnSetwidth = pXlfd->mnSetwidth;
+ mpFactory = pXlfd->mpFactory;
+ }
+
+ mpEncodingInfo = (EncodingInfo*)Realloc( mpEncodingInfo,
+ (mnEncodings + 1) * sizeof(EncodingInfo) );
+ mpEncodingInfo[ mnEncodings ] = pXlfd;
+ mnEncodings += 1;
+
+ return True;
+}
+
+void
+ExtendedXlfd::ToString( ByteString &rString,
+ unsigned short nPixelSize, rtl_TextEncoding nEncoding ) const
+{
+ AppendAttribute( mpFactory->RetrieveFoundry(mnFoundry), rString );
+ AppendAttribute( mpFactory->RetrieveFamily(mnFamily), rString );
+ AppendAttribute( mpFactory->RetrieveWeight(mnWeight), rString );
+ AppendAttribute( mpFactory->RetrieveSlant(mnSlant), rString );
+ AppendAttribute( mpFactory->RetrieveSetwidth(mnSetwidth), rString );
+}
+
+// interface to the independent vcl class implfontdata
+// this must not be called if mnEncodings is zero
+void
+ExtendedXlfd::ToImplFontData( ImplFontData *pFontData ) const
+{
+ pFontData->mpSysData = (void*)this;
+
+ Attribute *pFamilyAttr = mpFactory->RetrieveFamily( mnFamily );
+ Attribute *pWeightAttr = mpFactory->RetrieveWeight( mnWeight );
+ Attribute *pWidthAttr = mpFactory->RetrieveSetwidth( mnSetwidth );
+ Attribute *pSlantAttr = mpFactory->RetrieveSlant( mnSlant );
+
+ pFontData->meFamily = GetFamily();
+ pFontData->meWeight = GetWeight();
+ pFontData->meItalic = GetItalic();
+ pFontData->meWidthType = GetWidth();
+
+ // family name
+ pFontData->maName = pFamilyAttr->GetAnnotation();
+
+ // the helvetica narrow hack
+ if ( ! pFamilyAttr->HasFeature(XLFD_FEATURE_NARROW)
+ && pWidthAttr->HasFeature(XLFD_FEATURE_NARROW) )
+ {
+ static const String aNarrow( RTL_CONSTASCII_USTRINGPARAM(" Narrow") );
+ pFontData->maName += aNarrow;
+ }
+
+ // stylename = weight + slant + width
+ // XXX Fix me: there may be a space missing between them
+ String aStyleName;
+ if ( pFontData->meWeight != WEIGHT_NORMAL )
+ aStyleName += pWeightAttr->GetAnnotation();
+ if ( pFontData->meItalic != ITALIC_NONE )
+ aStyleName += pSlantAttr->GetAnnotation();
+ if ( ( pFontData->meWidthType != WIDTH_NORMAL)
+ && (! pWidthAttr->HasFeature(XLFD_FEATURE_NARROW)) )
+ aStyleName += pWidthAttr->GetAnnotation();
+ pFontData->maStyleName = aStyleName;
+
+ pFontData->meCharSet = GetEncoding();
+ pFontData->mbOrientation = TRUE;
+
+ // printer resident font / downloadable
+ pFontData->mbDevice = TRUE;
+
+ // spacing
+ pFontData->mePitch = GetSpacing();
+
+}
+
+static FontPitch
+GetPitch( const char cSpacing )
+{
+ switch ( cSpacing )
+ {
+ case 'c':
+ case 'm': return PITCH_FIXED;
+ case 'p': return PITCH_VARIABLE;
+ default: return PITCH_DONTKNOW;
+ }
+}
+
+// you must not call any of the ExtendedXlfd::GetXXX() functions if the
+// ExtendedXlfd is really empty (i.e. mnEncodings is zero)
+
+FontPitch
+ExtendedXlfd::GetSpacing() const
+{
+ if ( mnEncodings > 0 )
+ return PITCH_VARIABLE;
+ if ( mnEncodings == 1 )
+ return GetPitch( mpEncodingInfo[0].mcSpacing );
+
+ return PITCH_DONTKNOW;
+}
+
+FontPitch
+ExtendedXlfd::GetSpacing( rtl_TextEncoding nEncoding ) const
+{
+ for ( int nIdx = 0; nIdx < mnEncodings; nIdx++ )
+ {
+ if ( mpEncodingInfo[nIdx].mnEncoding == nEncoding )
+ return GetPitch( mpEncodingInfo[nIdx].mcSpacing );
+ }
+ return PITCH_DONTKNOW;
+}
+
+FontFamily
+ExtendedXlfd::GetFamily() const
+{
+ Attribute *pFamilyAttr= mpFactory->RetrieveFamily(mnFamily);
+ return (FontFamily)pFamilyAttr->GetValue();
+}
+
+FontWeight
+ExtendedXlfd::GetWeight() const
+{
+ Attribute *pWeightAttr = mpFactory->RetrieveWeight(mnWeight);
+ return (FontWeight)pWeightAttr->GetValue();
+}
+
+FontItalic
+ExtendedXlfd::GetItalic() const
+{
+ Attribute *pSlantAttr = mpFactory->RetrieveSlant(mnSlant);
+ return (FontItalic)pSlantAttr->GetValue();
+}
+
+FontWidth
+ExtendedXlfd::GetWidth() const
+{
+ Attribute *pWidthAttr = mpFactory->RetrieveSetwidth(mnSetwidth);
+ return (FontWidth)pWidthAttr->GetValue();
+}
+
+#ifdef DEBUG
+void
+ExtendedXlfd::Dump() const
+{
+ for ( int i = 0; i < mnEncodings; i++ )
+ {
+ ByteString aString;
+ ToString( aString, 0, mpEncodingInfo[i].mnEncoding );
+ fprintf( stderr, "%s\n", aString.GetBuffer() );
+ }
+}
+#endif
+
+// ------ class to handle scalable bitmap fonts ------------------------------
+
+ScalableBitmapXlfd::ScalableBitmapXlfd()
+{
+}
+
+ScalableBitmapXlfd::~ScalableBitmapXlfd()
+{
+}
+
+void
+ScalableBitmapXlfd::ToString( ByteString &rString,
+ unsigned short nPixelSize, rtl_TextEncoding nEncoding ) const
+{
+ int nIdx = GetEncodingIdx( nEncoding );
+ if ( nIdx < 0 )
+ return;
+
+ ExtendedXlfd::ToString( rString, nPixelSize, nEncoding );
+ EncodingInfo& rInfo = mpEncodingInfo[ nIdx ];
+
+ AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString );
+
+ rString += '-';
+ rString += ByteString::CreateFromInt32( nPixelSize );
+ rString += "-0-";
+ rString += ByteString::CreateFromInt32( rInfo.mnResolutionX );
+ rString += '-';
+ rString += ByteString::CreateFromInt32( rInfo.mnResolutionY );
+ rString += '-';
+ rString += rInfo.mcSpacing;
+ rString += "-0";
+
+ AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString );
+}
+
+void
+ScalableBitmapXlfd::ToImplFontData( ImplFontData *pFontData ) const
+{
+ ExtendedXlfd::ToImplFontData( pFontData );
+
+ pFontData->meType = TYPE_SCALABLE;
+ pFontData->mnWidth = 0;
+ pFontData->mnHeight = 0;
+ pFontData->mnQuality= 0;
+}
+
+// ------ class to handle true bitmap fonts ----------------------------------
+
+BitmapXlfd::BitmapXlfd( )
+{
+}
+
+BitmapXlfd::~BitmapXlfd( )
+{
+}
+
+Bool
+BitmapXlfd::AddEncoding( const Xlfd *pXlfd )
+{
+ if ( mnEncodings == 0 )
+ {
+ mnPixelSize = pXlfd->mnPixelSize;
+ mnPointSize = pXlfd->mnPointSize;
+ mnAverageWidth = pXlfd->mnAverageWidth;
+ }
+
+ return ExtendedXlfd::AddEncoding( pXlfd );
+}
+
+void
+BitmapXlfd::ToString( ByteString &rString,
+ unsigned short nPixelSize, rtl_TextEncoding nEncoding ) const
+{
+ int nIdx = GetEncodingIdx( nEncoding );
+ if ( nIdx < 0 )
+ return;
+
+ ExtendedXlfd::ToString( rString, nPixelSize, nEncoding );
+ EncodingInfo& rInfo = mpEncodingInfo[ nIdx ];
+
+ AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString );
+
+ rString += '-';
+ rString += ByteString::CreateFromInt32( mnPixelSize );
+ rString += "-";
+ rString += ByteString::CreateFromInt32( mnPointSize );
+ rString += "-";
+ rString += ByteString::CreateFromInt32( rInfo.mnResolutionX );
+ rString += '-';
+ rString += ByteString::CreateFromInt32( rInfo.mnResolutionY );
+ rString += '-';
+ rString += rInfo.mcSpacing;
+ rString += '-';
+ rString += ByteString::CreateFromInt32( mnAverageWidth );
+
+ AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString );
+}
+
+void
+BitmapXlfd::ToImplFontData( ImplFontData *pFontData ) const
+{
+ ExtendedXlfd::ToImplFontData( pFontData );
+
+ pFontData->meType = TYPE_RASTER;
+ pFontData->mnWidth = 0;
+ pFontData->mnHeight = mnPixelSize;
+ pFontData->mnQuality= 256;
+}
+
+
+// ------ class to handle true scalable fonts --------------------------------
+
+ScalableXlfd::ScalableXlfd()
+{
+}
+
+ScalableXlfd::~ScalableXlfd()
+{
+}
+
+void
+ScalableXlfd::ToString( ByteString &rString,
+ unsigned short nPixelSize, rtl_TextEncoding nEncoding ) const
+{
+ int nIdx = GetEncodingIdx( nEncoding );
+ if ( nIdx < 0 )
+ return;
+
+ ExtendedXlfd::ToString( rString, nPixelSize, nEncoding);
+
+ EncodingInfo& rInfo = mpEncodingInfo[ nIdx ];
+ AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString );
+
+ rString += '-';
+ rString += ByteString::CreateFromInt32( nPixelSize );
+ rString += "-0-0-0-";
+ rString += rInfo.mcSpacing;
+ rString += "-0";
+
+ AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString );
+}
+
+void
+ScalableXlfd::ToImplFontData( ImplFontData *pFontData ) const
+{
+ ExtendedXlfd::ToImplFontData( pFontData );
+
+ pFontData->meType = TYPE_SCALABLE;
+ pFontData->mnWidth = 0;
+ pFontData->mnHeight = 0;
+ pFontData->mnQuality= 1024;
+}
+
+// ------ printer fonts ---------------------------------------------------
+
+PrinterFontXlfd::PrinterFontXlfd( )
+{
+}
+
+PrinterFontXlfd::~PrinterFontXlfd( )
+{
+}
+
+Bool
+PrinterFontXlfd::AddEncoding( const Xlfd *pXlfd )
+{
+ rtl_TextEncoding nEncoding = pXlfd->GetEncoding();
+ int nEncodingIdx = GetEncodingIdx( nEncoding );
+
+ if ( nEncodingIdx == -1 )
+ {
+ // the encoding is new, so add it anyway
+ return ExtendedXlfd::AddEncoding( pXlfd );
+ }
+ else
+ {
+ // we already have this encoding, check if we can replace
+ // a soft font with a builtin font
+ EncodingInfo& rInfo = mpEncodingInfo[ nEncodingIdx ];
+ XlfdFonttype nNewType, nOldType;
+
+ nOldType = rInfo.mnResolutionX == 0 && rInfo.mnResolutionY == 0 ?
+ eTypePrinterDownload : eTypePrinterBuiltIn;
+ nNewType = pXlfd->Fonttype();
+
+ if ( nOldType == eTypePrinterDownload
+ && nNewType == eTypePrinterBuiltIn )
+ {
+ mpEncodingInfo[ nEncodingIdx ] = pXlfd;
+ }
+ return True;
+ }
+
+ return False;
+}
+
+// ------ font list -------------------------------------------------------
+
+void
+XlfdStorage::Dispose()
+{
+ for ( int i = 0; i < mnCount; i++ )
+ delete mpList[i];
+ if ( mnSize != 0 )
+ delete mpList;
+
+ mnCount = 0;
+ mnSize = 0;
+ mpList = NULL;
+}
+
+void
+XlfdStorage::Reset()
+{
+ mnCount = 0;
+}
+
+XlfdStorage::~XlfdStorage()
+{
+ if ( mnSize != 0 )
+ delete mpList;
+}
+
+XlfdStorage::XlfdStorage() :
+ mnCount( 0 ),
+ mnSize( 0 ),
+ mpList( NULL )
+{
+}
+
+void
+XlfdStorage::Enlarge()
+{
+ if ( mnSize == 0 )
+ mnSize = 8;
+ else
+ mnSize = mnSize < 32768 ? (mnSize * 2) : 65535;
+
+ mpList = (const ExtendedXlfd**)Realloc(mpList, mnSize * sizeof(ExtendedXlfd*));
+}
+
+void
+XlfdStorage::Add( const ExtendedXlfd* pXlfd )
+{
+ if ( pXlfd == NULL )
+ return;
+
+ if ( mnCount >= mnSize )
+ Enlarge();
+ mpList[ mnCount++ ] = pXlfd;
+}
+
+void
+XlfdStorage::Add( const XlfdStorage* pXlfd )
+{
+ if ( pXlfd == NULL )
+ return;
+
+ if ( pXlfd->mnCount != 0 )
+ {
+ unsigned short nNeeded = mnCount + pXlfd->mnCount;
+ if ( mnSize <= nNeeded )
+ {
+ if ( mnSize == 0 )
+ mnSize = pXlfd->mnSize;
+ while ( mnSize <= nNeeded )
+ mnSize = mnSize < 32768 ? (mnSize * 2) : 65535;
+ mpList = (const ExtendedXlfd**)Realloc( mpList,
+ mnSize * sizeof(ExtendedXlfd*) );
+ }
+ memcpy( mpList + mnCount, pXlfd->mpList,
+ pXlfd->mnCount * sizeof(ExtendedXlfd*) );
+ mnCount += pXlfd->mnCount;
+ }
+}
+
+#ifdef DEBUG
+void
+XlfdStorage::Dump() const
+{
+ for ( int i = 0; i < mnCount; i++ )
+ {
+ mpList[i]->Dump();
+ fprintf(stderr, "\n" );
+ }
+}
+#endif
+
+const ExtendedXlfd*
+XlfdStorage::Get( int nIdx ) const
+{
+ return nIdx >= 0 && nIdx < mnCount ? mpList[nIdx] : NULL ;
+}
+
+// ------ bitmap font list --------------------------------------------------
+
+void
+BitmapXlfdStorage::AddBitmapFont( const Xlfd *pXlfd )
+{
+ if ( pXlfd == NULL )
+ return;
+
+ unsigned short nSize = pXlfd->mnPixelSize;
+
+ for ( int i = 0; i < mnCount; i++ )
+ if ( nSize == ((BitmapXlfd*)mpList[i])->GetPixelSize() )
+ {
+ const_cast<ExtendedXlfd*>(mpList[i])->AddEncoding( pXlfd );
+ return;
+ }
+ if ( mnCount >= mnSize )
+ Enlarge();
+ mpList[ mnCount ] = new BitmapXlfd();
+ const_cast<ExtendedXlfd*>(mpList[ mnCount ])->AddEncoding( pXlfd );
+ ++mnCount;
+}
+
diff --git a/vcl/unx/source/gdi/xlfd_extd.hxx b/vcl/unx/source/gdi/xlfd_extd.hxx
new file mode 100644
index 000000000000..96197177eb33
--- /dev/null
+++ b/vcl/unx/source/gdi/xlfd_extd.hxx
@@ -0,0 +1,251 @@
+/*************************************************************************
+ *
+ * $RCSfile: xlfd_extd.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef XLFD_EXTENDED_HXX
+#define XLFD_EXTENDED_HXX
+
+#ifndef _SALUNX_H
+#include <salunx.h>
+#endif
+#ifndef _VCL_VCLENUM_HXX
+#include <enum.hxx>
+#endif
+
+class Xlfd;
+class AttributeProvider;
+class ImplFontData;
+class ByteString;
+
+// --------------------------------------------------------------------------
+//
+// classes for Xlfd handling that contain more than a single encoding.
+// Members that may vary through different encodings are stored in
+// a mpEncodingInfo member. There are three different classes:
+// true scalable fonts (truetype and type1) scalable bitmap fonts
+// (the ugly ones) and bitmap fonts. The ExtendedXlfd stores all the members
+// that are specific to a font outline
+// ( e.g. adobe-times-roman-medium-r-normal- * -p- * )
+// and specifies the interface.
+//
+// --------------------------------------------------------------------------
+
+// base class
+
+class ExtendedXlfd {
+
+ public:
+ ExtendedXlfd();
+ virtual ~ExtendedXlfd();
+ virtual Bool AddEncoding( const Xlfd *pXlfd );
+ Bool HasEncoding( rtl_TextEncoding nEncoding ) const;
+ int GetEncodingIdx( rtl_TextEncoding nEncoding ) const;
+ unsigned short NumEncodings() const
+ { return mnEncodings; }
+ virtual void ToString( ByteString &rString,
+ unsigned short nPixelSize,
+ rtl_TextEncoding nEncoding ) const ;
+ virtual void ToImplFontData( ImplFontData *pFontData ) const ;
+ virtual FontType GetFontType() const
+ { return TYPE_DONTKNOW; }
+ FontFamily GetFamily() const;
+ FontWeight GetWeight() const;
+ FontItalic GetItalic() const;
+ FontWidth GetWidth() const;
+ virtual FontPitch GetSpacing() const;
+ virtual FontPitch GetSpacing( rtl_TextEncoding nEnc ) const;
+ rtl_TextEncoding GetAsciiEncoding( int *pAsciiRange = NULL ) const;
+ rtl_TextEncoding GetEncoding() const;
+ rtl_TextEncoding GetEncoding( int i ) const;
+
+ #ifdef DEBUG
+ void Dump() const;
+ #endif
+
+ protected:
+
+ AttributeProvider* mpFactory;
+
+ unsigned short mnFoundry;
+ unsigned short mnFamily;
+ unsigned short mnWeight;
+ unsigned short mnSlant;
+ unsigned short mnSetwidth;
+
+ unsigned short mnEncodings;
+ struct EncodingInfo {
+ unsigned char mcSpacing;
+ unsigned short mnResolutionX;
+ unsigned short mnResolutionY;
+ unsigned short mnAddstyle;
+ unsigned short mnCharset;
+
+ rtl_TextEncoding mnEncoding;
+
+ EncodingInfo& operator= ( const Xlfd *pXlfd );
+ } *mpEncodingInfo;
+};
+
+// class to handle scalable bitmap fonts
+
+class ScalableBitmapXlfd : public ExtendedXlfd {
+
+ public:
+ ScalableBitmapXlfd();
+ virtual ~ScalableBitmapXlfd();
+ virtual void ToString( ByteString &rString,
+ unsigned short nPixelSize,
+ rtl_TextEncoding nEncoding ) const;
+ virtual void ToImplFontData( ImplFontData *pFontData ) const;
+ virtual FontType GetFontType() const
+ { return TYPE_SCALABLE; }
+};
+
+// class to handle true bitmap fonts
+
+class BitmapXlfd : public ExtendedXlfd {
+
+ public:
+ BitmapXlfd();
+ ~BitmapXlfd();
+ Bool AddEncoding( const Xlfd *pXlfd );
+ unsigned short GetPixelSize() const
+ { return mnPixelSize; }
+ virtual void ToString( ByteString &rString,
+ unsigned short nPixelSize,
+ rtl_TextEncoding nEncoding ) const;
+ virtual void ToImplFontData( ImplFontData *pFontData ) const ;
+ virtual FontType GetFontType() const
+ { return TYPE_RASTER; }
+ protected:
+
+ unsigned short mnPixelSize;
+ unsigned short mnPointSize;
+ unsigned short mnAverageWidth;
+};
+
+// class to handle true scalable fonts
+
+class ScalableXlfd : public ExtendedXlfd {
+
+ public:
+ ScalableXlfd();
+ virtual ~ScalableXlfd();
+ virtual void ToString( ByteString &rString,
+ unsigned short nPixelSize,
+ rtl_TextEncoding nEncoding ) const;
+
+ virtual void ToImplFontData( ImplFontData *pFontData ) const ;
+ virtual FontType GetFontType() const
+ { return TYPE_SCALABLE; }
+};
+
+// class to handle printer resident and printer downloadable fonts
+// printer font xlfd look like scalable bitmap fonts but behave a
+// little bit different
+
+class PrinterFontXlfd : public ScalableBitmapXlfd {
+
+ public:
+ PrinterFontXlfd();
+ virtual ~PrinterFontXlfd();
+ virtual Bool AddEncoding( const Xlfd *pXlfd );
+};
+
+// class to maintain a list of fonts ( bitmap and scalable )
+
+class XlfdStorage {
+
+ public:
+ XlfdStorage();
+ ~XlfdStorage();
+
+ void Dispose();
+ void Reset();
+
+ void Add( const ExtendedXlfd *pXlfd );
+ void Add( const XlfdStorage *pXlfd );
+ unsigned short GetCount() const
+ { return mnCount; }
+ const ExtendedXlfd* Get(int nIdx) const;
+ #ifdef DEBUG
+ void Dump() const ;
+ #endif
+
+ protected:
+
+ void Enlarge();
+
+ unsigned short mnCount;
+ unsigned short mnSize;
+ const ExtendedXlfd**
+ mpList;
+};
+
+// list of fonts specific for bitmap fonts
+
+class BitmapXlfdStorage : public XlfdStorage {
+
+ public:
+
+ void AddBitmapFont( const Xlfd *pXlfd );
+};
+
+#endif /* XLFD_EXTENDED_HXX */
+
diff --git a/vcl/unx/source/gdi/xlfd_smpl.cxx b/vcl/unx/source/gdi/xlfd_smpl.cxx
new file mode 100644
index 000000000000..e2ef73f59747
--- /dev/null
+++ b/vcl/unx/source/gdi/xlfd_smpl.cxx
@@ -0,0 +1,285 @@
+/*************************************************************************
+ *
+ * $RCSfile: xlfd_smpl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifndef XLFD_ATTRIBUTE_HXX
+#include "xlfd_attr.hxx"
+#endif
+#ifndef XLFD_SIMPLE_HXX
+#include "xlfd_smpl.hxx"
+#endif
+
+// --------------------------------------------------------------------------
+//
+//
+// broken down structure equivalent to a Xlfd string
+//
+//
+// --------------------------------------------------------------------------
+
+Xlfd::Xlfd()
+{
+}
+
+// XlfdCompare abi has to be qsort(3) compatible, the sorting result must
+// guarantee that fonts with SameFontoutline() are successive
+// XlfdCompare relies on vFrom->mpFactory eq vTo->mpFactory. Since comparing
+// Xlfd's is done by comparing attributes there is no way around this.
+extern "C" int
+XlfdCompare( const void *vFrom, const void *vTo )
+{
+ const Xlfd *pFrom = (Xlfd*)vFrom;
+ const Xlfd *pTo = (Xlfd*)vTo;
+
+ // Compare outline description
+ if ( pFrom->mnFoundry != pTo->mnFoundry )
+ return (int)pFrom->mnFoundry - (int)pTo->mnFoundry;
+ if ( pFrom->mnFamily != pTo->mnFamily )
+ return (int)pFrom->mnFamily - (int)pTo->mnFamily;
+ if ( pFrom->mnWeight != pTo->mnWeight )
+ return (int)pFrom->mnWeight - (int)pTo->mnWeight;
+ if ( pFrom->mnSlant != pTo->mnSlant )
+ return (int)pFrom->mnSlant - (int)pTo->mnSlant;
+ if ( pFrom->mnSetwidth != pTo->mnSetwidth )
+ return (int)pFrom->mnSetwidth - (int)pTo->mnSetwidth;
+
+ // Addstyle name is futile tricky. it may contain encoding information
+ // (like "ansi_1251") which Compares equal, or it may contain style
+ // information (like "serif") which Compares unequal
+ if ( pFrom->mnAddstyle == pTo->mnAddstyle )
+ return 0;
+
+ AttributeProvider *pFactory = pFrom->mpFactory;
+ Attribute *pFromAttr = pFactory->RetrieveAddstyle( pFrom->mnAddstyle );
+ Attribute *pToAttr = pFactory->RetrieveAddstyle( pTo->mnAddstyle );
+
+ // if both addstyles denote encodings or if one denotes an
+ // encoding and the other denotes a style which really
+ // duplicates weight and slant information
+
+ int nFromCompare = (pFromAttr->GetValue() != RTL_TEXTENCODING_DONTKNOW)
+ || (pFromAttr->HasFeature(XLFD_FEATURE_REDUNDANTSTYLE)) ?
+ -1 : pFrom->mnAddstyle;
+ int nToCompare = (pToAttr->GetValue() != RTL_TEXTENCODING_DONTKNOW)
+ || (pToAttr->HasFeature(XLFD_FEATURE_REDUNDANTSTYLE)) ?
+ -1 : pTo->mnAddstyle;
+
+ return nFromCompare - nToCompare;
+}
+
+// check whether two fonts are identical as appearance is concerned
+// this does not Compare the actual scaling of two fonts
+Bool
+Xlfd::SameFontoutline( const Xlfd* pComparedTo ) const
+{
+ void* pThis = (void*)this;
+ return XlfdCompare( (void*)pThis, (void*)pComparedTo ) == 0 ;
+}
+
+unsigned short
+Xlfd::GetEncoding() const
+{
+ Attribute *pAddstyle = mpFactory->RetrieveAddstyle( mnAddstyle );
+ if ( pAddstyle->GetValue() != RTL_TEXTENCODING_DONTKNOW )
+ return pAddstyle->GetValue();
+
+ Attribute *pEncoding = mpFactory->RetrieveCharset( mnCharset );
+ return pEncoding->GetValue();
+}
+
+XlfdFonttype
+Xlfd::Fonttype() const
+{
+ if ( (mnAverageWidth == 0) && (mnPixelSize == 0) && (mnPointSize == 0) )
+ {
+ if ( (mnResolutionX == 0) && (mnResolutionY == 0) )
+ return mpFactory->GetDevice() == eDevicePrinter ?
+ eTypePrinterDownload : eTypeScalable;
+ else
+ return mpFactory->GetDevice() == eDevicePrinter ?
+ eTypePrinterBuiltIn : eTypeScalableBitmap;
+ }
+
+ return mpFactory->GetDevice() == eDevicePrinter ?
+ eTypeUnknown : eTypeBitmap;
+}
+
+void
+Advance( const char** pFrom, const char** pTo )
+{
+ const char *pTmp = *pTo;
+
+ for( ; (*pTmp != '\0') && (*pTmp++ != '-'); )
+ {}
+ *pFrom = *pTo;
+ *pTo = pTmp;
+}
+
+// this is the real workhorse function. Since this is called for every font
+// in the fontpath it has to be as fast a possible
+Bool
+Xlfd::FromString( const char* pXlfdstring, AttributeProvider *pFactory )
+{
+ mpFactory = pFactory;
+
+ const char* pTo;
+ const char* pFrom;
+
+ pFrom = pXlfdstring;
+ // first char must be '-'
+ if(*pFrom++ != '-')
+ return False;
+
+ pTo = pFrom;
+
+ Advance( &pFrom, &pTo ); //-foundry-*
+ mnFoundry = mpFactory->InsertFoundry( pFrom, pTo - pFrom - 1 );
+
+ Advance( &pFrom, &pTo ); // -*-family-*
+ mnFamily = mpFactory->InsertFamily( pFrom, pTo - pFrom - 1 );
+
+ Advance( &pFrom, &pTo ); // -*-*-weight-*
+ mnWeight = mpFactory->InsertWeight( pFrom, pTo - pFrom - 1 );
+
+ Advance( &pFrom, &pTo ); //-*-*-*-slant-*
+ mnSlant = mpFactory->InsertSlant( pFrom, pTo - pFrom - 1 );
+
+ Advance( &pFrom, &pTo ); //-*-*-*-*-setwidth-*
+ mnSetwidth = mpFactory->InsertSetwidth( pFrom, pTo - pFrom - 1 );
+
+ Advance( &pFrom, &pTo ); //-*-*-*-*-*-Addstyle-*
+ mnAddstyle = mpFactory->InsertAddstyle( pFrom, pTo - pFrom - 1 );
+
+ Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-height-*
+ mnPixelSize = atoi( pFrom );
+
+ Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-pt height-*
+ mnPointSize = atoi( pFrom );
+
+ Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-x resolution-*
+ mnResolutionX = atoi( pFrom );
+
+ Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-y resolution-*
+ mnResolutionY = atoi( pFrom );
+
+ Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-spacing-*
+ mcSpacing = pFrom == pTo ? '\0' : *pFrom;
+
+ Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-*-average-*
+ mnAverageWidth = atoi( pFrom );
+
+ Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-*-*-registry-encoding
+ const char* pTmp = pFrom;
+ Advance( &pTmp, &pTo );
+ mnCharset = mpFactory->InsertCharset( pFrom, pTo - pFrom );
+
+ // sanity check whether we have really found a valid XLFD, if not
+ // throw away the whole font, since we have no idea what parts of
+ // the XLFD contains the error.
+ if ( !(pTo > pFrom) )
+ return False;
+
+ // a non-empty family name is essential, since otherwise the font
+ // would match the "default font" #52299#
+ Attribute* pFamily = mpFactory->RetrieveFamily( mnFamily );
+ const char* pFamilyName = pFamily->GetName();
+ if ( pFamilyName[0] == '\0' )
+ return False;
+
+ // well done
+ return True;
+}
+
+#ifdef DEBUG
+// pure debug for now: this is only to inspect/pretty print a Xlfd struct
+const char*
+Xlfd::ToString( ByteString &rString ) const
+{
+ AppendAttribute( mpFactory->RetrieveFoundry(mnFoundry), rString );
+ AppendAttribute( mpFactory->RetrieveFamily(mnFamily), rString );
+ AppendAttribute( mpFactory->RetrieveWeight(mnWeight), rString );
+ AppendAttribute( mpFactory->RetrieveSlant(mnSlant), rString );
+ AppendAttribute( mpFactory->RetrieveSetwidth(mnSetwidth), rString );
+ AppendAttribute( mpFactory->RetrieveAddstyle(mnAddstyle), rString );
+
+ rString += '-'; rString += ByteString::CreateFromInt32( mnPixelSize );
+ rString += '-'; rString += ByteString::CreateFromInt32( mnPointSize );
+ rString += '-'; rString += ByteString::CreateFromInt32( mnResolutionX );
+ rString += '-'; rString += ByteString::CreateFromInt32( mnResolutionY );
+ rString += '-'; rString += mcSpacing;
+ rString += '-'; rString += ByteString::CreateFromInt32( mnAverageWidth );
+
+ AppendAttribute( mpFactory->RetrieveCharset(mnCharset), rString );
+
+ return rString.GetBuffer() ;
+}
+
+void
+Xlfd::Dump() const
+{
+ ByteString aString;
+ fprintf(stderr, "Xlfd: %s\n", ToString(aString) );
+}
+#endif
+
diff --git a/vcl/unx/source/gdi/xlfd_smpl.hxx b/vcl/unx/source/gdi/xlfd_smpl.hxx
new file mode 100644
index 000000000000..923f542d3d15
--- /dev/null
+++ b/vcl/unx/source/gdi/xlfd_smpl.hxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * $RCSfile: xlfd_smpl.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef XLFD_SIMPLE_HXX
+#define XLFD_SIMPLE_HXX
+
+#ifndef _SALUNX_H
+#include <salunx.h>
+#endif
+#ifndef _VCL_VCLENUM_HXX
+#include <vclenum.hxx>
+#endif
+#ifndef _STRING_HXX
+#include <tools/string.hxx>
+#endif
+
+class AttributeProvider;
+
+// --------------------------------------------------------------------------
+//
+//
+// broken down structure equivalent to a Xlfd string
+//
+//
+// --------------------------------------------------------------------------
+
+enum XlfdFonttype {
+ eTypeUnknown = TYPE_DONTKNOW,
+ eTypeBitmap = TYPE_RASTER,
+ eTypeScalableBitmap = TYPE_VECTOR,
+ eTypeScalable = TYPE_SCALABLE,
+ eTypePrinterBuiltIn,
+ eTypePrinterDownload
+};
+
+class Xlfd {
+
+ public:
+
+ unsigned short mnFoundry;
+ unsigned short mnFamily;
+ unsigned short mnWeight;
+ unsigned short mnSlant;
+ unsigned short mnSetwidth;
+ unsigned short mnAddstyle;
+ unsigned short mnPixelSize;
+ unsigned short mnPointSize;
+ unsigned short mnResolutionX;
+ unsigned short mnResolutionY;
+ unsigned char mcSpacing;
+ unsigned short mnAverageWidth;
+ unsigned short mnCharset;
+
+ // all foundry, family, weight ... information referres
+ // to this factory
+ AttributeProvider *mpFactory;
+
+ public:
+ Xlfd();
+ Bool FromString( const char* pXlfdstring,
+ AttributeProvider *pFactory );
+ Bool SameFontoutline( const Xlfd *pComparedTo ) const ;
+ XlfdFonttype Fonttype() const ;
+ unsigned short GetEncoding() const ;
+ #ifdef DEBUG
+ const char* ToString( ByteString &rString ) const ;
+ void Dump() const;
+ #endif
+};
+
+extern "C" int
+XlfdCompare( const void *vFrom, const void *vTo );
+
+#endif /* XLFD_SIMPLE_HXX */
+
diff --git a/vcl/unx/source/inc/airbrush_curs.h b/vcl/unx/source/inc/airbrush_curs.h
new file mode 100644
index 000000000000..0cee6ff80441
--- /dev/null
+++ b/vcl/unx/source/inc/airbrush_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: airbrush_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define airbrush_curs_width 32
+#define airbrush_curs_height 32
+#define airbrush_curs_x_hot 5
+#define airbrush_curs_y_hot 22
+static char airbrush_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
+ 0x7c,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x1f,0x00,0x00,0x98,0x0f,0x00,0x00,
+ 0xcc,0x07,0x00,0x00,0xb4,0x03,0x00,0x00,0x10,0x01,0x00,0x00,0x88,0x00,0x00,
+ 0x00,0x44,0x00,0x00,0x00,0x62,0x60,0x00,0x00,0x91,0x10,0x00,0x80,0x88,0x10,
+ 0x00,0x40,0x04,0x09,0x00,0x40,0x02,0x06,0x00,0xa0,0x01,0x00,0x00,0x60,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};
diff --git a/vcl/unx/source/inc/airbrush_mask.h b/vcl/unx/source/inc/airbrush_mask.h
new file mode 100644
index 000000000000..3192d0ec2a74
--- /dev/null
+++ b/vcl/unx/source/inc/airbrush_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: airbrush_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define airbrush_mask_width 32
+#define airbrush_mask_height 32
+#define airbrush_mask_x_hot 5
+#define airbrush_mask_y_hot 22
+static char airbrush_mask_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
+ 0x7c,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x1f,0x00,0x00,0x98,0x0f,0x00,0x00,
+ 0xcc,0x07,0x00,0x00,0xf4,0x03,0x00,0x00,0xf0,0x01,0x00,0x00,0xf8,0x00,0x00,
+ 0x00,0x7c,0x00,0x00,0x00,0x7e,0x60,0x00,0x00,0x9f,0x10,0x00,0x80,0x8f,0x10,
+ 0x00,0xc0,0x07,0x09,0x00,0xc0,0x03,0x06,0x00,0xe0,0x01,0x00,0x00,0x60,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};
diff --git a/vcl/unx/source/inc/ase_curs.h b/vcl/unx/source/inc/ase_curs.h
new file mode 100644
index 000000000000..71387399b3c2
--- /dev/null
+++ b/vcl/unx/source/inc/ase_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: ase_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define ase_curs_width 32
+#define ase_curs_height 32
+#define ase_curs_x_hot 19
+#define ase_curs_y_hot 16
+static char ase_curs_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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x1c,0x0e,
+ 0x00,0x00,0x3e,0x1e,0x00,0x00,0x3e,0x7e,0x00,0x00,0x3e,0x1e,0x00,0x00,0x1c,
+ 0x0e,0x00,0x00,0x00,0x03,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};
diff --git a/vcl/unx/source/inc/ase_mask.h b/vcl/unx/source/inc/ase_mask.h
new file mode 100644
index 000000000000..bdd084127371
--- /dev/null
+++ b/vcl/unx/source/inc/ase_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: ase_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define ase_mask_width 32
+#define ase_mask_height 32
+#define ase_mask_x_hot 19
+#define ase_mask_y_hot 16
+static char ase_mask_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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x9c,0x0f,0x00,0x00,0x3e,0x1f,
+ 0x00,0x00,0x7f,0x7f,0x00,0x00,0x7f,0xff,0x00,0x00,0x7f,0x7f,0x00,0x00,0x3e,
+ 0x1f,0x00,0x00,0x9c,0x0f,0x00,0x00,0x00,0x03,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};
diff --git a/vcl/unx/source/inc/asn_curs.h b/vcl/unx/source/inc/asn_curs.h
new file mode 100644
index 000000000000..c81b50f0bbee
--- /dev/null
+++ b/vcl/unx/source/inc/asn_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asn_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asn_curs_width 32
+#define asn_curs_height 32
+#define asn_curs_x_hot 16
+#define asn_curs_y_hot 12
+static char asn_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x03,
+ 0x00,0x00,0xc0,0x07,0x00,0x00,0xc0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0x20,
+ 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,
+ 0xc0,0x07,0x00,0x00,0xc0,0x07,0x00,0x00,0xc0,0x07,0x00,0x00,0x80,0x03,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/asn_mask.h b/vcl/unx/source/inc/asn_mask.h
new file mode 100644
index 000000000000..a711a43aced6
--- /dev/null
+++ b/vcl/unx/source/inc/asn_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asn_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asn_mask_width 32
+#define asn_mask_height 32
+#define asn_mask_x_hot 16
+#define asn_mask_y_hot 12
+static char asn_mask_bits[] = {
+ 0x00,0x00,0x01,0x00,0x00,0x80,0x03,0x00,0x00,0x80,0x03,0x00,0x00,0xc0,0x07,
+ 0x00,0x00,0xe0,0x0f,0x00,0x00,0xe0,0x0f,0x00,0x00,0xf0,0x1f,0x00,0x00,0xf0,
+ 0x1f,0x00,0x00,0x20,0x08,0x00,0x00,0x80,0x03,0x00,0x00,0xc0,0x07,0x00,0x00,
+ 0xe0,0x0f,0x00,0x00,0xe0,0x0f,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x07,0x00,
+ 0x00,0x80,0x03,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,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/asne_curs.h b/vcl/unx/source/inc/asne_curs.h
new file mode 100644
index 000000000000..2463803a8fb7
--- /dev/null
+++ b/vcl/unx/source/inc/asne_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asne_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asne_curs_width 32
+#define asne_curs_height 32
+#define asne_curs_x_hot 21
+#define asne_curs_y_hot 10
+static char asne_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x80,
+ 0x3f,0x00,0x00,0xc0,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x1c,0x00,0x00,
+ 0x00,0x1c,0x00,0x00,0x70,0x18,0x00,0x00,0xf8,0x08,0x00,0x00,0xf8,0x00,0x00,
+ 0x00,0xf8,0x00,0x00,0x00,0x70,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,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/asne_mask.h b/vcl/unx/source/inc/asne_mask.h
new file mode 100644
index 000000000000..1d59c3009dec
--- /dev/null
+++ b/vcl/unx/source/inc/asne_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asne_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asne_mask_width 32
+#define asne_mask_height 32
+#define asne_mask_x_hot 21
+#define asne_mask_y_hot 10
+static char asne_mask_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,0x80,0x7f,0x00,0x00,0xc0,
+ 0x7f,0x00,0x00,0xe0,0x7f,0x00,0x00,0xc0,0x7f,0x00,0x00,0x00,0x3f,0x00,0x00,
+ 0x70,0x3e,0x00,0x00,0xf8,0x3c,0x00,0x00,0xfc,0x1d,0x00,0x00,0xfc,0x09,0x00,
+ 0x00,0xfc,0x01,0x00,0x00,0xf8,0x00,0x00,0x00,0x70,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/asns_curs.h b/vcl/unx/source/inc/asns_curs.h
new file mode 100644
index 000000000000..9b459efc1dee
--- /dev/null
+++ b/vcl/unx/source/inc/asns_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asns_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asns_curs_width 32
+#define asns_curs_height 32
+#define asns_curs_x_hot 15
+#define asns_curs_y_hot 15
+static char asns_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0xc0,0x01,0x00,0x00,0xe0,
+ 0x03,0x00,0x00,0xe0,0x03,0x00,0x00,0xf0,0x07,0x00,0x00,0x10,0x04,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0x00,0x00,0xe0,0x03,0x00,
+ 0x00,0xe0,0x03,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0xf0,0x07,0x00,0x00,0xe0,
+ 0x03,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,0x00,0x00,0x80,0x00,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};
diff --git a/vcl/unx/source/inc/asns_mask.h b/vcl/unx/source/inc/asns_mask.h
new file mode 100644
index 000000000000..377687fdf2b2
--- /dev/null
+++ b/vcl/unx/source/inc/asns_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asns_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asns_mask_width 32
+#define asns_mask_height 32
+#define asns_mask_x_hot 15
+#define asns_mask_y_hot 15
+static char asns_mask_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,
+ 0x00,0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,0xe0,0x03,0x00,0x00,0xf0,
+ 0x07,0x00,0x00,0xf0,0x07,0x00,0x00,0xf8,0x0f,0x00,0x00,0xf8,0x0f,0x00,0x00,
+ 0x10,0x04,0x00,0x00,0xc0,0x01,0x00,0x00,0xe0,0x03,0x00,0x00,0xf0,0x07,0x00,
+ 0x00,0xf0,0x07,0x00,0x00,0xf0,0x07,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,
+ 0x00,0x00,0x10,0x04,0x00,0x00,0xf8,0x0f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xf0,
+ 0x07,0x00,0x00,0xf0,0x07,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,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};
diff --git a/vcl/unx/source/inc/asnswe_curs.h b/vcl/unx/source/inc/asnswe_curs.h
new file mode 100644
index 000000000000..e6c871fed4e5
--- /dev/null
+++ b/vcl/unx/source/inc/asnswe_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asnswe_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asnswe_curs_width 32
+#define asnswe_curs_height 32
+#define asnswe_curs_x_hot 15
+#define asnswe_curs_y_hot 15
+static char asnswe_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0xc0,0x01,0x00,0x00,0xe0,
+ 0x03,0x00,0x00,0xe0,0x03,0x00,0x00,0xf0,0x07,0x00,0x00,0x10,0x04,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x80,0xc3,0xe1,0x00,0xc0,0xe3,0xe3,0x01,
+ 0xf0,0xe3,0xe3,0x07,0xc0,0xe3,0xe3,0x01,0x80,0xc3,0xe1,0x00,0x00,0x06,0x30,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0xf0,0x07,0x00,0x00,0xe0,
+ 0x03,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,0x00,0x00,0x80,0x00,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};
diff --git a/vcl/unx/source/inc/asnswe_mask.h b/vcl/unx/source/inc/asnswe_mask.h
new file mode 100644
index 000000000000..22c910a1a9a7
--- /dev/null
+++ b/vcl/unx/source/inc/asnswe_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asnswe_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asnswe_mask_width 32
+#define asnswe_mask_height 32
+#define asnswe_mask_x_hot 15
+#define asnswe_mask_y_hot 15
+static char asnswe_mask_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,
+ 0x00,0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,0xe0,0x03,0x00,0x00,0xf0,
+ 0x07,0x00,0x00,0xf0,0x07,0x00,0x00,0xf8,0x0f,0x00,0x00,0xf8,0x0f,0x00,0x00,
+ 0x16,0x34,0x00,0x80,0xcf,0xf9,0x00,0xc0,0xe7,0xf3,0x01,0xf0,0xf7,0xf7,0x07,
+ 0xf8,0xf7,0xf7,0x0f,0xf0,0xf7,0xf7,0x07,0xc0,0xe7,0xf3,0x01,0x80,0xcf,0xf9,
+ 0x00,0x00,0x16,0x34,0x00,0x00,0xf8,0x0f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xf0,
+ 0x07,0x00,0x00,0xf0,0x07,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,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};
diff --git a/vcl/unx/source/inc/asnw_curs.h b/vcl/unx/source/inc/asnw_curs.h
new file mode 100644
index 000000000000..9961547d6378
--- /dev/null
+++ b/vcl/unx/source/inc/asnw_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asnw_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asnw_curs_width 32
+#define asnw_curs_height 32
+#define asnw_curs_x_hot 10
+#define asnw_curs_y_hot 10
+static char asnw_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0xfc,0x01,0x00,
+ 0x00,0xfc,0x03,0x00,0x00,0xfc,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x38,0x00,
+ 0x00,0x00,0x18,0x0e,0x00,0x00,0x10,0x1f,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
+ 0x1f,0x00,0x00,0x00,0x0e,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,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/asnw_mask.h b/vcl/unx/source/inc/asnw_mask.h
new file mode 100644
index 000000000000..b824f9287e58
--- /dev/null
+++ b/vcl/unx/source/inc/asnw_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asnw_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asnw_mask_width 32
+#define asnw_mask_height 32
+#define asnw_mask_x_hot 10
+#define asnw_mask_y_hot 10
+static char asnw_mask_bits[] = {
+ 0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0xfe,0x01,0x00,0x00,0xfe,0x03,0x00,
+ 0x00,0xfe,0x07,0x00,0x00,0xfe,0x03,0x00,0x00,0xfc,0x00,0x00,0x00,0x7c,0x0e,
+ 0x00,0x00,0x3c,0x1f,0x00,0x00,0xb8,0x3f,0x00,0x00,0x90,0x3f,0x00,0x00,0x80,
+ 0x3f,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x0e,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/ass_curs.h b/vcl/unx/source/inc/ass_curs.h
new file mode 100644
index 000000000000..47da8c925589
--- /dev/null
+++ b/vcl/unx/source/inc/ass_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: ass_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define ass_curs_width 32
+#define ass_curs_height 32
+#define ass_curs_x_hot 15
+#define ass_curs_y_hot 19
+static char ass_curs_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,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,0xc0,0x01,0x00,0x00,0xe0,0x03,
+ 0x00,0x00,0xe0,0x03,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0xf0,0x07,0x00,0x00,
+ 0xe0,0x03,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,0x00,0x00,0x80,0x00,0x00,
+ 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/ass_mask.h b/vcl/unx/source/inc/ass_mask.h
new file mode 100644
index 000000000000..951e8dd72c88
--- /dev/null
+++ b/vcl/unx/source/inc/ass_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: ass_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define ass_mask_width 32
+#define ass_mask_height 32
+#define ass_mask_x_hot 15
+#define ass_mask_y_hot 19
+static char ass_mask_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,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,0xc0,0x01,0x00,0x00,0xe0,0x03,0x00,0x00,0xf0,0x07,
+ 0x00,0x00,0xf0,0x07,0x00,0x00,0xf0,0x07,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,
+ 0x01,0x00,0x00,0x10,0x04,0x00,0x00,0xf8,0x0f,0x00,0x00,0xf8,0x0f,0x00,0x00,
+ 0xf0,0x07,0x00,0x00,0xf0,0x07,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,0x00,
+ 0x00,0xc0,0x01,0x00,0x00,0x80,0x00,0x00};
diff --git a/vcl/unx/source/inc/asse_curs.h b/vcl/unx/source/inc/asse_curs.h
new file mode 100644
index 000000000000..763756e8c833
--- /dev/null
+++ b/vcl/unx/source/inc/asse_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asse_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asse_curs_width 32
+#define asse_curs_height 32
+#define asse_curs_x_hot 21
+#define asse_curs_y_hot 21
+static char asse_curs_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,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,0x70,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,
+ 0xf8,0x08,0x00,0x00,0x70,0x18,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x1c,0x00,
+ 0x00,0x00,0x3f,0x00,0x00,0xc0,0x3f,0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x3c,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/asse_mask.h b/vcl/unx/source/inc/asse_mask.h
new file mode 100644
index 000000000000..3e80ed64250c
--- /dev/null
+++ b/vcl/unx/source/inc/asse_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asse_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asse_mask_width 32
+#define asse_mask_height 32
+#define asse_mask_x_hot 21
+#define asse_mask_y_hot 21
+static char asse_mask_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,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,0x70,
+ 0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0xfc,0x01,0x00,0x00,0xfc,0x09,0x00,0x00,
+ 0xfc,0x1d,0x00,0x00,0xf8,0x3c,0x00,0x00,0x70,0x3e,0x00,0x00,0x00,0x3f,0x00,
+ 0x00,0xc0,0x7f,0x00,0x00,0xe0,0x7f,0x00,0x00,0xc0,0x7f,0x00,0x00,0x80,0x7f,
+ 0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/assw_curs.h b/vcl/unx/source/inc/assw_curs.h
new file mode 100644
index 000000000000..7ee6d3bf02e3
--- /dev/null
+++ b/vcl/unx/source/inc/assw_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: assw_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define assw_curs_width 32
+#define assw_curs_height 32
+#define assw_curs_x_hot 21
+#define assw_curs_y_hot 21
+static char assw_curs_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,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,0x0e,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x1f,0x00,0x00,0x10,0x1f,
+ 0x00,0x00,0x18,0x0e,0x00,0x00,0x38,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xfc,
+ 0x00,0x00,0x00,0xfc,0x03,0x00,0x00,0xfc,0x01,0x00,0x00,0x3c,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/assw_mask.h b/vcl/unx/source/inc/assw_mask.h
new file mode 100644
index 000000000000..4f184f717cd1
--- /dev/null
+++ b/vcl/unx/source/inc/assw_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: assw_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define assw_mask_width 32
+#define assw_mask_height 32
+#define assw_mask_x_hot 21
+#define assw_mask_y_hot 21
+static char assw_mask_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,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,0x0e,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x1f,0x00,0x00,0x10,0x1f,
+ 0x00,0x00,0x18,0x0e,0x00,0x00,0x38,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xfc,
+ 0x00,0x00,0x00,0xfc,0x03,0x00,0x00,0xfc,0x01,0x00,0x00,0x3c,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/asw_curs.h b/vcl/unx/source/inc/asw_curs.h
new file mode 100644
index 000000000000..33c77e76fb6e
--- /dev/null
+++ b/vcl/unx/source/inc/asw_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asw_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asw_curs_width 32
+#define asw_curs_height 32
+#define asw_curs_x_hot 12
+#define asw_curs_y_hot 15
+static char asw_curs_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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x70,0x38,0x00,0x00,0x78,0x7c,0x00,0x00,
+ 0x7e,0x7c,0x00,0x00,0x78,0x7c,0x00,0x00,0x70,0x38,0x00,0x00,0xc0,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,0x00};
diff --git a/vcl/unx/source/inc/asw_mask.h b/vcl/unx/source/inc/asw_mask.h
new file mode 100644
index 000000000000..11a227508627
--- /dev/null
+++ b/vcl/unx/source/inc/asw_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: asw_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define asw_mask_width 32
+#define asw_mask_height 32
+#define asw_mask_x_hot 12
+#define asw_mask_y_hot 15
+static char asw_mask_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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
+ 0x00,0x00,0x00,0xf0,0x39,0x00,0x00,0xf8,0x7c,0x00,0x00,0xfe,0xfe,0x00,0x00,
+ 0xff,0xfe,0x00,0x00,0xfe,0xfe,0x00,0x00,0xf8,0x7c,0x00,0x00,0xf0,0x39,0x00,
+ 0x00,0xc0,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};
diff --git a/vcl/unx/source/inc/aswe_curs.h b/vcl/unx/source/inc/aswe_curs.h
new file mode 100644
index 000000000000..76bf92ed9e9e
--- /dev/null
+++ b/vcl/unx/source/inc/aswe_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: aswe_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define aswe_curs_width 32
+#define aswe_curs_height 32
+#define aswe_curs_x_hot 15
+#define aswe_curs_y_hot 15
+static char aswe_curs_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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x80,0xc3,0xe1,0x00,0xc0,0xe3,0xe3,0x01,
+ 0xf0,0xe3,0xe3,0x07,0xc0,0xe3,0xe3,0x01,0x80,0xc3,0xe1,0x00,0x00,0x06,0x30,
+ 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};
diff --git a/vcl/unx/source/inc/aswe_mask.h b/vcl/unx/source/inc/aswe_mask.h
new file mode 100644
index 000000000000..ef2f2043e30a
--- /dev/null
+++ b/vcl/unx/source/inc/aswe_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: aswe_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define aswe_mask_width 32
+#define aswe_mask_height 32
+#define aswe_mask_x_hot 15
+#define aswe_mask_y_hot 15
+static char aswe_mask_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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x06,0x30,0x00,0x80,0xcf,0xf9,0x00,0xc0,0xe7,0xf3,0x01,0xf0,0xf7,0xf7,0x07,
+ 0xf8,0xf7,0xf7,0x0f,0xf0,0xf7,0xf7,0x07,0xc0,0xe7,0xf3,0x01,0x80,0xcf,0xf9,
+ 0x00,0x00,0x06,0x30,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};
diff --git a/vcl/unx/source/inc/chain_curs.h b/vcl/unx/source/inc/chain_curs.h
new file mode 100644
index 000000000000..6ec19fc917f6
--- /dev/null
+++ b/vcl/unx/source/inc/chain_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: chain_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define chain_curs_width 32
+#define chain_curs_height 32
+#define chain_curs_x_hot 0
+#define chain_curs_y_hot 2
+static char chain_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x00,0x81,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x01,
+ 0x02,0x00,0x00,0x01,0x04,0x00,0x00,0x81,0x0f,0x00,0x00,0x91,0x00,0x00,0x00,
+ 0x99,0x00,0x00,0x00,0x25,0x01,0x00,0x00,0x23,0x01,0x00,0x00,0x41,0x3e,0xbf,
+ 0x0f,0x40,0x82,0x40,0x10,0x80,0x5c,0xae,0x23,0x80,0x24,0x91,0x24,0x00,0x23,
+ 0x91,0x28,0x80,0x24,0x91,0x28,0x80,0x24,0x91,0x24,0x80,0x98,0x4f,0x23,0x00,
+ 0x41,0x20,0x10,0x00,0x3e,0xde,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/chain_mask.h b/vcl/unx/source/inc/chain_mask.h
new file mode 100644
index 000000000000..f03eaf6a611c
--- /dev/null
+++ b/vcl/unx/source/inc/chain_mask.h
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * $RCSfile: chain_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define chain_mask_width 32
+#define chain_mask_height 32
+static char chain_mask_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x01,0x00,0x00,0xff,
+ 0x03,0x00,0x00,0xff,0x07,0x00,0x00,0xff,0x0f,0x00,0x00,0xff,0x00,0x00,0x00,
+ 0xff,0x00,0x00,0x00,0xe7,0x01,0x00,0x00,0xe3,0x01,0x00,0x00,0xc1,0x3f,0xbf,
+ 0x0f,0xc0,0xbf,0xff,0x1f,0x80,0xdf,0xff,0x3f,0x80,0xe7,0xf1,0x3c,0x00,0xe3,
+ 0xf1,0x38,0x80,0xe7,0xf1,0x38,0x80,0xe7,0xf1,0x3c,0x80,0xff,0xff,0x3f,0x00,
+ 0x7f,0xff,0x1f,0x00,0x3e,0xde,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/chainnot_curs.h b/vcl/unx/source/inc/chainnot_curs.h
new file mode 100644
index 000000000000..1d98fbd89aef
--- /dev/null
+++ b/vcl/unx/source/inc/chainnot_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: chainnot_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define chainnot_curs_width 32
+#define chainnot_curs_height 32
+#define chainnot_curs_x_hot 2
+#define chainnot_curs_y_hot 2
+static char chainnot_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x80,0x1f,0x00,0x00,0xe0,0x7f,0x00,0x00,0xf0,0xf0,0x00,
+ 0x00,0x38,0xc0,0x01,0x00,0x7c,0x80,0x03,0x00,0xec,0x00,0x03,0x00,0xce,0x01,
+ 0x07,0x00,0x86,0x03,0x06,0x00,0x06,0x07,0x06,0x00,0x06,0x0e,0x06,0x00,0x06,
+ 0x1c,0x06,0x00,0x0e,0x38,0x07,0x00,0x0c,0x70,0x03,0x00,0x1c,0xe0,0x03,0x00,
+ 0x38,0xc0,0x01,0x00,0xf0,0xe0,0x00,0x00,0xe0,0x7f,0x00,0x00,0x80,0x9f,0xfc,
+ 0x3e,0x00,0x00,0x02,0x41,0x00,0x72,0xb9,0x8e,0x00,0x92,0x44,0x92,0x00,0x8c,
+ 0x44,0xa2,0x00,0x92,0x44,0xa2,0x00,0x92,0x44,0x92,0x00,0x62,0x3e,0x8d,0x00,
+ 0x04,0x81,0x40,0x00,0xf8,0x78,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/chainnot_mask.h b/vcl/unx/source/inc/chainnot_mask.h
new file mode 100644
index 000000000000..38764c143944
--- /dev/null
+++ b/vcl/unx/source/inc/chainnot_mask.h
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * $RCSfile: chainnot_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define chainnot_mask_width 32
+#define chainnot_mask_height 32
+static char chainnot_mask_bits[] = {
+ 0x80,0x1f,0x00,0x00,0xe0,0x7f,0x00,0x00,0xf0,0xff,0x00,0x00,0xf8,0xff,0x01,
+ 0x00,0xfc,0xf0,0x03,0x00,0xfe,0xc0,0x07,0x00,0xfe,0x81,0x07,0x00,0xff,0x83,
+ 0x0f,0x00,0xcf,0x07,0x0f,0x00,0x8f,0x0f,0x0f,0x00,0x0f,0x1f,0x0f,0x00,0x0f,
+ 0x3e,0x0f,0x00,0x1f,0xfc,0x0f,0x00,0x1e,0xf8,0x07,0x00,0x3e,0xf0,0x07,0x00,
+ 0xfc,0xe0,0x03,0x00,0xf8,0xff,0x01,0x00,0xf0,0xff,0x00,0x00,0xe0,0xff,0xfc,
+ 0x3e,0x80,0xff,0xfe,0x7f,0x00,0x7e,0xff,0xff,0x00,0x9e,0xc7,0xf3,0x00,0x8c,
+ 0xc7,0xe3,0x00,0x9e,0xc7,0xe3,0x00,0x9e,0xc7,0xf3,0x00,0xfe,0xff,0xff,0x00,
+ 0xfc,0xfd,0x7f,0x00,0xf8,0x78,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/chart_curs.h b/vcl/unx/source/inc/chart_curs.h
new file mode 100644
index 000000000000..7aa676c96cf3
--- /dev/null
+++ b/vcl/unx/source/inc/chart_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: chart_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define chart_curs_width 32
+#define chart_curs_height 32
+#define chart_curs_x_hot 15
+#define chart_curs_y_hot 16
+static char chart_curs_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,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xbf,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,
+ 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,
+ 0x10,0x00,0x00,0x80,0x00,0x06,0x00,0x00,0x10,0x06,0x00,0x00,0x00,0x06,0x00,
+ 0x00,0x10,0x36,0x00,0x00,0xc0,0x36,0x00,0x00,0xd0,0x36,0x00,0x00,0xc0,0x36,
+ 0x00,0x00,0xf0,0x7f,0x00,0x00,0x00,0x00};
diff --git a/vcl/unx/source/inc/chart_mask.h b/vcl/unx/source/inc/chart_mask.h
new file mode 100644
index 000000000000..0f0b6b37bb3f
--- /dev/null
+++ b/vcl/unx/source/inc/chart_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: chart_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define chart_mask_width 32
+#define chart_mask_height 32
+#define chart_mask_x_hot 15
+#define chart_mask_y_hot 16
+static char chart_mask_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,0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,
+ 0xc0,0x01,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,0x00,0xc0,0x01,
+ 0x00,0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,0xc0,0x39,0x00,0x00,0xc0,
+ 0x39,0x0f,0x00,0xc0,0x39,0x0f,0x00,0xc0,0x39,0x0f,0x00,0x00,0x38,0x7f,0x00,
+ 0x00,0xf8,0x7f,0x00,0x00,0xf8,0x7f,0x00,0x00,0xf8,0x7f,0x00,0x00,0xf8,0xff,
+ 0x00,0x00,0xf8,0xff,0x00,0x00,0xf8,0xff};
diff --git a/vcl/unx/source/inc/copydata_curs.h b/vcl/unx/source/inc/copydata_curs.h
new file mode 100644
index 000000000000..e60620a7c777
--- /dev/null
+++ b/vcl/unx/source/inc/copydata_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copydata_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copydata_curs_width 32
+#define copydata_curs_height 32
+#define copydata_curs_x_hot 1
+#define copydata_curs_y_hot 1
+static char copydata_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
+ 0x7e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00,
+ 0xfe, 0x03, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
+ 0x66, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x10, 0x53, 0x00, 0x00,
+ 0x28, 0xa3, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x10, 0xf0, 0x1f, 0x00, 0x08, 0xf0, 0x1f, 0x00, 0x10, 0xf0, 0x1e, 0x00,
+ 0xa8, 0xf2, 0x1e, 0x00, 0x50, 0x35, 0x18, 0x00, 0x00, 0xf0, 0x1e, 0x00,
+ 0x00, 0xf0, 0x1e, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/copydata_mask.h b/vcl/unx/source/inc/copydata_mask.h
new file mode 100644
index 000000000000..7b3b86c15030
--- /dev/null
+++ b/vcl/unx/source/inc/copydata_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copydata_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copydata_mask_width 32
+#define copydata_mask_height 32
+#define copydata_mask_x_hot 1
+#define copydata_mask_y_hot 1
+static char copydata_mask_bits[] = {
+ 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xe7, 0x03, 0x00, 0x00,
+ 0xe0, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00,
+ 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x3c, 0xf8, 0x3f, 0x00,
+ 0x3c, 0xf8, 0x3f, 0x00, 0x3c, 0xf8, 0x3f, 0x00, 0xfc, 0xff, 0x3f, 0x00,
+ 0xfc, 0xff, 0x3f, 0x00, 0xfc, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f, 0x00,
+ 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00,
+ 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/copydlnk_curs.h b/vcl/unx/source/inc/copydlnk_curs.h
new file mode 100644
index 000000000000..3e8b1633efc8
--- /dev/null
+++ b/vcl/unx/source/inc/copydlnk_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copydlnk_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copydlnk_curs_width 32
+#define copydlnk_curs_height 32
+#define copydlnk_curs_x_hot 1
+#define copydlnk_curs_y_hot 1
+static char copydlnk_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
+ 0x7e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00,
+ 0xfe, 0x03, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
+ 0x66, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x10, 0x53, 0x00, 0x00,
+ 0x28, 0xa3, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
+ 0x30, 0xf1, 0x1f, 0x00, 0x10, 0xf1, 0x1f, 0x00, 0xd0, 0xf1, 0x1e, 0x00,
+ 0xf0, 0xf1, 0x1e, 0x00, 0x00, 0x34, 0x18, 0x00, 0x00, 0xf0, 0x1e, 0x00,
+ 0x00, 0xf0, 0x1e, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/copydlnk_mask.h b/vcl/unx/source/inc/copydlnk_mask.h
new file mode 100644
index 000000000000..bd9900fdfe67
--- /dev/null
+++ b/vcl/unx/source/inc/copydlnk_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copydlnk_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copydlnk_mask_width 32
+#define copydlnk_mask_height 32
+#define copydlnk_mask_x_hot 1
+#define copydlnk_mask_y_hot 1
+static char copydlnk_mask_bits[] = {
+ 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xe7, 0x03, 0x00, 0x00,
+ 0xe0, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00,
+ 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x3f, 0x00,
+ 0xf8, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f, 0x00,
+ 0xf8, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0xfe, 0x3f, 0x00,
+ 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00,
+ 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/copyfile_curs.h b/vcl/unx/source/inc/copyfile_curs.h
new file mode 100644
index 000000000000..f92161e0ec06
--- /dev/null
+++ b/vcl/unx/source/inc/copyfile_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copyfile_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copyfile_curs_width 32
+#define copyfile_curs_height 32
+#define copyfile_curs_x_hot 9
+#define copyfile_curs_y_hot 9
+static char copyfile_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x00, 0x00,
+ 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
+ 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x00,
+ 0xfe, 0x02, 0x00, 0x00, 0xfe, 0x06, 0x00, 0x00, 0xfe, 0x0e, 0x00, 0x00,
+ 0xfe, 0x1e, 0x00, 0x00, 0xfe, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+ 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x03, 0x00,
+ 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00,
+ 0x00, 0xc2, 0xe0, 0x3f, 0x00, 0xc0, 0xe0, 0x3f, 0x00, 0x80, 0xe1, 0x3d,
+ 0x00, 0x80, 0xe1, 0x3d, 0x00, 0x00, 0x63, 0x30, 0x00, 0x00, 0xe3, 0x3d,
+ 0x00, 0x00, 0xe0, 0x3d, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/copyfile_mask.h b/vcl/unx/source/inc/copyfile_mask.h
new file mode 100644
index 000000000000..af844d3218b2
--- /dev/null
+++ b/vcl/unx/source/inc/copyfile_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copyfile_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copyfile_mask_width 32
+#define copyfile_mask_height 32
+#define copyfile_mask_x_hot 9
+#define copyfile_mask_y_hot 9
+static char copyfile_mask_bits[] = {
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00,
+ 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00,
+ 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xf1, 0x7f,
+ 0x00, 0xff, 0xf1, 0x7f, 0x00, 0xe7, 0xf3, 0x7f, 0x00, 0xe0, 0xf3, 0x7f,
+ 0x00, 0xc0, 0xf7, 0x7f, 0x00, 0xc0, 0xf7, 0x7f, 0x00, 0x80, 0xf7, 0x7f,
+ 0x00, 0x80, 0xf7, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f,
+ 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/copyfiles_curs.h b/vcl/unx/source/inc/copyfiles_curs.h
new file mode 100644
index 000000000000..4acfaf38b0db
--- /dev/null
+++ b/vcl/unx/source/inc/copyfiles_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copyfiles_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copyfiles_curs_width 32
+#define copyfiles_curs_height 32
+#define copyfiles_curs_x_hot 8
+#define copyfiles_curs_y_hot 9
+static char copyfiles_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xe0, 0x2f, 0x00, 0x00,
+ 0xe8, 0x0f, 0x00, 0x00, 0xe8, 0x7f, 0x00, 0x00, 0xea, 0x7f, 0x00, 0x00,
+ 0xea, 0x7f, 0x00, 0x00, 0xea, 0x7f, 0x00, 0x00, 0x6a, 0x7e, 0x00, 0x00,
+ 0x6a, 0x7d, 0x00, 0x00, 0x6a, 0x7b, 0x00, 0x00, 0x6a, 0x77, 0x00, 0x00,
+ 0x6a, 0x6f, 0x00, 0x00, 0x6a, 0x5f, 0x00, 0x00, 0x0a, 0x3f, 0x00, 0x00,
+ 0x7a, 0x7f, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x7e, 0xff, 0x01, 0x00,
+ 0x00, 0x3f, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00,
+ 0x00, 0x61, 0xe0, 0x3f, 0x00, 0x60, 0xe0, 0x3f, 0x00, 0xc0, 0xe0, 0x3d,
+ 0x00, 0xc0, 0xe0, 0x3d, 0x00, 0x80, 0x61, 0x30, 0x00, 0x80, 0xe1, 0x3d,
+ 0x00, 0x00, 0xe0, 0x3d, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/copyfiles_mask.h b/vcl/unx/source/inc/copyfiles_mask.h
new file mode 100644
index 000000000000..cec000477d40
--- /dev/null
+++ b/vcl/unx/source/inc/copyfiles_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copyfiles_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copyfiles_mask_width 32
+#define copyfiles_mask_height 32
+#define copyfiles_mask_x_hot 8
+#define copyfiles_mask_y_hot 9
+static char copyfiles_mask_bits[] = {
+ 0xf0, 0x1f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00,
+ 0xfc, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00,
+ 0xff, 0xff, 0x03, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x80, 0xff, 0xf0, 0x7f,
+ 0x80, 0xff, 0xf0, 0x7f, 0x80, 0xf3, 0xf1, 0x7f, 0x00, 0xf0, 0xf1, 0x7f,
+ 0x00, 0xe0, 0xf3, 0x7f, 0x00, 0xe0, 0xf3, 0x7f, 0x00, 0xc0, 0xf3, 0x7f,
+ 0x00, 0xc0, 0xf3, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f,
+ 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/copyflnk_curs.h b/vcl/unx/source/inc/copyflnk_curs.h
new file mode 100644
index 000000000000..c61d5fbfe564
--- /dev/null
+++ b/vcl/unx/source/inc/copyflnk_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copyflnk_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copyflnk_curs_width 32
+#define copyflnk_curs_height 32
+#define copyflnk_curs_x_hot 9
+#define copyflnk_curs_y_hot 9
+static char copyflnk_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x00, 0x00,
+ 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
+ 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00,
+ 0xbe, 0x02, 0x00, 0x00, 0xa6, 0x06, 0x00, 0x00, 0xa2, 0x0e, 0x00, 0x00,
+ 0xba, 0x1e, 0x00, 0x00, 0xbe, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+ 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x03, 0x00,
+ 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00,
+ 0x00, 0xc2, 0xe0, 0x3f, 0x00, 0xc0, 0xe0, 0x3f, 0x00, 0x80, 0xe1, 0x3d,
+ 0x00, 0x80, 0xe1, 0x3d, 0x00, 0x00, 0x63, 0x30, 0x00, 0x00, 0xe3, 0x3d,
+ 0x00, 0x00, 0xe0, 0x3d, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/copyflnk_mask.h b/vcl/unx/source/inc/copyflnk_mask.h
new file mode 100644
index 000000000000..110c0cc42991
--- /dev/null
+++ b/vcl/unx/source/inc/copyflnk_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: copyflnk_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define copyflnk_mask_width 32
+#define copyflnk_mask_height 32
+#define copyflnk_mask_x_hot 9
+#define copyflnk_mask_y_hot 9
+static char copyflnk_mask_bits[] = {
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00,
+ 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00,
+ 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xf1, 0x7f,
+ 0x00, 0xff, 0xf1, 0x7f, 0x00, 0xe7, 0xf3, 0x7f, 0x00, 0xe0, 0xf3, 0x7f,
+ 0x00, 0xc0, 0xf7, 0x7f, 0x00, 0xc0, 0xf7, 0x7f, 0x00, 0x80, 0xf7, 0x7f,
+ 0x00, 0x80, 0xf7, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f,
+ 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/crook_curs.h b/vcl/unx/source/inc/crook_curs.h
new file mode 100644
index 000000000000..877730c2c115
--- /dev/null
+++ b/vcl/unx/source/inc/crook_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: crook_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define crook_curs_width 32
+#define crook_curs_height 32
+#define crook_curs_x_hot 15
+#define crook_curs_y_hot 14
+static char crook_curs_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0x3e, 0xff, 0x7f, 0xbb, 0xdd, 0xfe,
+ 0x7f, 0xbb, 0xdd, 0xfe, 0xf3, 0xb6, 0x6d, 0xcf, 0xed, 0xb6, 0x6d, 0xb7,
+ 0xdd, 0x75, 0xae, 0xbb, 0xbb, 0x0b, 0xd0, 0xdd, 0xb7, 0xf1, 0x8f, 0xed,
+ 0x4f, 0x0e, 0x70, 0xf2, 0xbf, 0xf1, 0x8f, 0xfd, 0x5f, 0xfe, 0x7f, 0xfa,
+ 0xaf, 0xff, 0xff, 0xf5, 0xd7, 0xff, 0xff, 0xeb, 0xef, 0xff, 0xff, 0xf7,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/vcl/unx/source/inc/crook_mask.h b/vcl/unx/source/inc/crook_mask.h
new file mode 100644
index 000000000000..3e7b2929304f
--- /dev/null
+++ b/vcl/unx/source/inc/crook_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: crook_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define crook_mask_width 32
+#define crook_mask_height 32
+static char crook_mask_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, 0x83, 0xc1, 0x00, 0x80, 0xc7, 0xe3, 0x01, 0xc0, 0xef, 0xf7, 0x03,
+ 0xcc, 0xef, 0xf7, 0x33, 0x9e, 0xff, 0xff, 0x79, 0xbf, 0xff, 0xff, 0xfd,
+ 0x77, 0xff, 0xff, 0xee, 0xee, 0xf6, 0x6f, 0x77, 0xfc, 0xff, 0xff, 0x3f,
+ 0xb8, 0xff, 0xff, 0x1d, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
+ 0xf8, 0x01, 0x80, 0x1f, 0x7c, 0x00, 0x00, 0x3e, 0x38, 0x00, 0x00, 0x1c,
+ 0x10, 0x00, 0x00, 0x08, 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};
diff --git a/vcl/unx/source/inc/crop_curs.h b/vcl/unx/source/inc/crop_curs.h
new file mode 100644
index 000000000000..a67818a30f7b
--- /dev/null
+++ b/vcl/unx/source/inc/crop_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: crop_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define crop_curs_width 32
+#define crop_curs_height 32
+#define crop_curs_x_hot 9
+#define crop_curs_y_hot 9
+static char crop_curs_bits[] = {
+ 0xff, 0x0f, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff,
+ 0x07, 0x60, 0xf8, 0xff, 0xf7, 0x6f, 0xfb, 0xff, 0xf7, 0x6f, 0xfb, 0xff,
+ 0x37, 0x60, 0xf8, 0xff, 0xb7, 0x6f, 0xff, 0xff, 0xb7, 0x6f, 0xff, 0xff,
+ 0xb7, 0x6f, 0xff, 0xff, 0xb7, 0x6f, 0xff, 0xff, 0xb7, 0x6f, 0xff, 0xff,
+ 0x30, 0x60, 0xff, 0xff, 0xb6, 0x7f, 0xff, 0xff, 0xb6, 0x7f, 0xff, 0xff,
+ 0x30, 0x00, 0xff, 0xff, 0xb7, 0xff, 0xff, 0xff, 0xb7, 0xff, 0xff, 0xff,
+ 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/vcl/unx/source/inc/crop_mask.h b/vcl/unx/source/inc/crop_mask.h
new file mode 100644
index 000000000000..5731265dee6f
--- /dev/null
+++ b/vcl/unx/source/inc/crop_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: crop_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define crop_mask_width 32
+#define crop_mask_height 32
+static char crop_mask_bits[] = {
+ 0x00, 0xf8, 0x01, 0x00, 0x00, 0xf8, 0x01, 0x00, 0xfc, 0xff, 0x0f, 0x00,
+ 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00,
+ 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xf8, 0x01, 0x00,
+ 0xfc, 0xf8, 0x01, 0x00, 0xfc, 0xf8, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfc, 0x00, 0x00, 0x00,
+ 0xfc, 0x00, 0x00, 0x00, 0xfc, 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};
diff --git a/vcl/unx/source/inc/detective_curs.h b/vcl/unx/source/inc/detective_curs.h
new file mode 100644
index 000000000000..30cf7cb1fc02
--- /dev/null
+++ b/vcl/unx/source/inc/detective_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: detective_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define detective_curs_width 32
+#define detective_curs_height 32
+#define detective_curs_x_hot 12
+#define detective_curs_y_hot 13
+static char detective_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x38,0x00,
+ 0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,
+ 0x00,0x00,0x00,0x83,0x01,0x00,0x80,0x00,0x02,0x00,0x80,0x10,0x02,0x00,0x40,
+ 0x38,0x04,0x00,0x40,0x7c,0x04,0x00,0x40,0xfe,0x04,0x00,0x40,0x38,0x04,0x00,
+ 0x40,0x38,0x04,0x00,0x80,0x38,0x02,0x00,0x80,0x00,0x02,0x00,0x00,0x83,0x07,
+ 0x00,0x00,0x7c,0x0e,0x00,0x00,0x00,0x1c,0x00,0x00,0x10,0x38,0x00,0x00,0x38,
+ 0x70,0x00,0x00,0x10,0x60,0x00,0x00,0x10,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};
diff --git a/vcl/unx/source/inc/detective_mask.h b/vcl/unx/source/inc/detective_mask.h
new file mode 100644
index 000000000000..11ad00d35a1e
--- /dev/null
+++ b/vcl/unx/source/inc/detective_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: detective_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define detective_mask_width 32
+#define detective_mask_height 32
+#define detective_mask_x_hot 12
+#define detective_mask_y_hot 13
+static char detective_mask_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x38,0x00,
+ 0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,
+ 0x00,0x00,0x00,0xff,0x01,0x00,0x80,0xff,0x03,0x00,0x80,0xff,0x03,0x00,0xc0,
+ 0xff,0x07,0x00,0xc0,0xff,0x07,0x00,0xc0,0xff,0x07,0x00,0xc0,0xff,0x07,0x00,
+ 0xc0,0xff,0x07,0x00,0x80,0xff,0x03,0x00,0x80,0xff,0x03,0x00,0x00,0xff,0x07,
+ 0x00,0x00,0x7c,0x0e,0x00,0x00,0x00,0x1c,0x00,0x00,0x10,0x38,0x00,0x00,0x38,
+ 0x70,0x00,0x00,0x10,0x60,0x00,0x00,0x10,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};
diff --git a/vcl/unx/source/inc/drawarc_curs.h b/vcl/unx/source/inc/drawarc_curs.h
new file mode 100644
index 000000000000..7d7455e5606d
--- /dev/null
+++ b/vcl/unx/source/inc/drawarc_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawarc_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawarc_curs_width 32
+#define drawarc_curs_height 32
+#define drawarc_curs_x_hot 7
+#define drawarc_curs_y_hot 7
+static char drawarc_curs_bits[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x42, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 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};
diff --git a/vcl/unx/source/inc/drawarc_mask.h b/vcl/unx/source/inc/drawarc_mask.h
new file mode 100644
index 000000000000..68a532fef334
--- /dev/null
+++ b/vcl/unx/source/inc/drawarc_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawarc_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawarc_mask_width 32
+#define drawarc_mask_height 32
+static char drawarc_mask_bits[] = {
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x3f, 0x7e, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x3f, 0x7e, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0x80, 0xe7, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00,
+ 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 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};
diff --git a/vcl/unx/source/inc/drawbezier_curs.h b/vcl/unx/source/inc/drawbezier_curs.h
new file mode 100644
index 000000000000..61099e42a8da
--- /dev/null
+++ b/vcl/unx/source/inc/drawbezier_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawbezier_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawbezier_curs_width 32
+#define drawbezier_curs_height 32
+#define drawbezier_curs_x_hot 7
+#define drawbezier_curs_y_hot 7
+static char drawbezier_curs_bits[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x00, 0x00, 0x88, 0x00,
+ 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00,
+ 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x0e, 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};
diff --git a/vcl/unx/source/inc/drawbezier_mask.h b/vcl/unx/source/inc/drawbezier_mask.h
new file mode 100644
index 000000000000..77c302f5d216
--- /dev/null
+++ b/vcl/unx/source/inc/drawbezier_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawbezier_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawbezier_mask_width 32
+#define drawbezier_mask_height 32
+static char drawbezier_mask_bits[] = {
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x3f, 0x7e, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x3f, 0x7e, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x0f, 0x00, 0x00, 0x8e, 0x0f, 0x00, 0x00, 0xdc, 0x0f,
+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0x00,
+ 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xbf, 0x03, 0x00, 0x00, 0x1f, 0x07,
+ 0x00, 0x00, 0x0f, 0x06, 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};
diff --git a/vcl/unx/source/inc/drawcaption_curs.h b/vcl/unx/source/inc/drawcaption_curs.h
new file mode 100644
index 000000000000..dd2b97d39747
--- /dev/null
+++ b/vcl/unx/source/inc/drawcaption_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawcaption_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawcaption_curs_width 32
+#define drawcaption_curs_height 32
+#define drawcaption_curs_x_hot 8
+#define drawcaption_curs_y_hot 8
+static char drawcaption_curs_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
+ 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
+ 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x02, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
+ 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xbe, 0xff, 0xff,
+ 0xff, 0x7e, 0x1f, 0xe0, 0xff, 0xff, 0xde, 0xef, 0xff, 0xff, 0xc1, 0xef,
+ 0xff, 0xff, 0xdf, 0xef, 0xff, 0xff, 0x1f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/vcl/unx/source/inc/drawcaption_mask.h b/vcl/unx/source/inc/drawcaption_mask.h
new file mode 100644
index 000000000000..53675e4697e5
--- /dev/null
+++ b/vcl/unx/source/inc/drawcaption_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawcaption_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawcaption_mask_width 32
+#define drawcaption_mask_height 32
+static char drawcaption_mask_bits[] = {
+ 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0xff, 0xff, 0x01, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0x80, 0x43, 0x00, 0x00, 0x80, 0xe3, 0xf0, 0x3f,
+ 0x80, 0xc3, 0xf1, 0x3f, 0x80, 0x83, 0xff, 0x3f, 0x00, 0x00, 0x7f, 0x38,
+ 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xf0, 0x3f,
+ 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};
diff --git a/vcl/unx/source/inc/drawcirclecut_curs.h b/vcl/unx/source/inc/drawcirclecut_curs.h
new file mode 100644
index 000000000000..2f66f6f8ec25
--- /dev/null
+++ b/vcl/unx/source/inc/drawcirclecut_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawcirclecut_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawcirclecut_curs_width 32
+#define drawcirclecut_curs_height 32
+#define drawcirclecut_curs_x_hot 7
+#define drawcirclecut_curs_y_hot 7
+static char drawcirclecut_curs_bits[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00,
+ 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x41, 0x00,
+ 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x3c, 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};
diff --git a/vcl/unx/source/inc/drawcirclecut_mask.h b/vcl/unx/source/inc/drawcirclecut_mask.h
new file mode 100644
index 000000000000..e4bb3fb22b54
--- /dev/null
+++ b/vcl/unx/source/inc/drawcirclecut_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawcirclecut_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawcirclecut_mask_width 32
+#define drawcirclecut_mask_height 32
+static char drawcirclecut_mask_bits[] = {
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x3f, 0x7e, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x3f, 0x7e, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1f, 0x00,
+ 0x00, 0x80, 0x3b, 0x00, 0x00, 0x80, 0x73, 0x00, 0x00, 0x80, 0xe3, 0x00,
+ 0x00, 0x80, 0xc3, 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x7e, 0x00,
+ 0x00, 0x00, 0x3c, 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};
diff --git a/vcl/unx/source/inc/drawconnect_curs.h b/vcl/unx/source/inc/drawconnect_curs.h
new file mode 100644
index 000000000000..9f79bda47d38
--- /dev/null
+++ b/vcl/unx/source/inc/drawconnect_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawconnect_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawconnect_curs_width 32
+#define drawconnect_curs_height 32
+#define drawconnect_curs_x_hot 7
+#define drawconnect_curs_y_hot 7
+static char drawconnect_curs_bits[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x80, 0x5f, 0x00, 0x00, 0x80, 0x70,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0xfd, 0x00,
+ 0x00, 0x00, 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};
diff --git a/vcl/unx/source/inc/drawconnect_mask.h b/vcl/unx/source/inc/drawconnect_mask.h
new file mode 100644
index 000000000000..4b833b83f5c7
--- /dev/null
+++ b/vcl/unx/source/inc/drawconnect_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawconnect_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawconnect_mask_width 32
+#define drawconnect_mask_height 32
+static char drawconnect_mask_bits[] = {
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x3f, 0x7e, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x3f, 0x7e, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xc0, 0xdf, 0x00, 0x00, 0xc0, 0xff,
+ 0x00, 0x80, 0xcf, 0xf9, 0x00, 0x80, 0xff, 0x01, 0x00, 0x80, 0xfd, 0x01,
+ 0x00, 0x80, 0xff, 0x01, 0x00, 0x80, 0x0f, 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};
diff --git a/vcl/unx/source/inc/drawcrook_curs.h b/vcl/unx/source/inc/drawcrook_curs.h
new file mode 100644
index 000000000000..fd8317b7a88e
--- /dev/null
+++ b/vcl/unx/source/inc/drawcrook_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawcrook_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawcrook_curs_width 32
+#define drawcrook_curs_height 32
+#define drawcrook_curs_x_hot 15
+#define drawcrook_curs_y_hot 14
+static char drawcrook_curs_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0x3e, 0xff, 0x7f, 0xbb, 0xdd, 0xfe,
+ 0x7f, 0xbb, 0xdd, 0xfe, 0xf3, 0xb6, 0x6d, 0xcf, 0xed, 0xb6, 0x6d, 0xb7,
+ 0xdd, 0x75, 0xae, 0xbb, 0xbb, 0x0b, 0xd0, 0xdd, 0xb7, 0xf1, 0x8f, 0xed,
+ 0x4f, 0x0e, 0x70, 0xf2, 0xbf, 0xf1, 0x8f, 0xfd, 0x5f, 0xfe, 0x7f, 0xfa,
+ 0xaf, 0xff, 0xff, 0xf5, 0xd7, 0xff, 0xff, 0xeb, 0xef, 0xff, 0xff, 0xf7,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/vcl/unx/source/inc/drawcrook_mask.h b/vcl/unx/source/inc/drawcrook_mask.h
new file mode 100644
index 000000000000..3d1dce8c7f1e
--- /dev/null
+++ b/vcl/unx/source/inc/drawcrook_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawcrook_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawcrook_mask_width 32
+#define drawcrook_mask_height 32
+static char drawcrook_mask_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, 0x83, 0xc1, 0x00, 0x80, 0xc7, 0xe3, 0x01, 0xc0, 0xef, 0xf7, 0x03,
+ 0xcc, 0xef, 0xf7, 0x33, 0x9e, 0xff, 0xff, 0x79, 0xbf, 0xff, 0xff, 0xfd,
+ 0x77, 0xff, 0xff, 0xee, 0xee, 0xf6, 0x6f, 0x77, 0xfc, 0xff, 0xff, 0x3f,
+ 0xb8, 0xff, 0xff, 0x1d, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
+ 0xf8, 0x01, 0x80, 0x1f, 0x7c, 0x00, 0x00, 0x3e, 0x38, 0x00, 0x00, 0x1c,
+ 0x10, 0x00, 0x00, 0x08, 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};
diff --git a/vcl/unx/source/inc/drawcrop_curs.h b/vcl/unx/source/inc/drawcrop_curs.h
new file mode 100644
index 000000000000..aa287f6e502c
--- /dev/null
+++ b/vcl/unx/source/inc/drawcrop_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawcrop_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawcrop_curs_width 32
+#define drawcrop_curs_height 32
+#define drawcrop_curs_x_hot 9
+#define drawcrop_curs_y_hot 9
+static char drawcrop_curs_bits[] = {
+ 0xff, 0x0f, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff,
+ 0x07, 0x60, 0xf8, 0xff, 0xf7, 0x6f, 0xfb, 0xff, 0xf7, 0x6f, 0xfb, 0xff,
+ 0x37, 0x60, 0xf8, 0xff, 0xb7, 0x6f, 0xff, 0xff, 0xb7, 0x6f, 0xff, 0xff,
+ 0xb7, 0x6f, 0xff, 0xff, 0xb7, 0x6f, 0xff, 0xff, 0xb7, 0x6f, 0xff, 0xff,
+ 0x30, 0x60, 0xff, 0xff, 0xb6, 0x7f, 0xff, 0xff, 0xb6, 0x7f, 0xff, 0xff,
+ 0x30, 0x00, 0xff, 0xff, 0xb7, 0xff, 0xff, 0xff, 0xb7, 0xff, 0xff, 0xff,
+ 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/vcl/unx/source/inc/drawcrop_mask.h b/vcl/unx/source/inc/drawcrop_mask.h
new file mode 100644
index 000000000000..c631f8fa4397
--- /dev/null
+++ b/vcl/unx/source/inc/drawcrop_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawcrop_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawcrop_mask_width 32
+#define drawcrop_mask_height 32
+static char drawcrop_mask_bits[] = {
+ 0x00, 0xf8, 0x01, 0x00, 0x00, 0xf8, 0x01, 0x00, 0xfc, 0xff, 0x0f, 0x00,
+ 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00,
+ 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xf8, 0x01, 0x00,
+ 0xfc, 0xf8, 0x01, 0x00, 0xfc, 0xf8, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfc, 0x00, 0x00, 0x00,
+ 0xfc, 0x00, 0x00, 0x00, 0xfc, 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};
diff --git a/vcl/unx/source/inc/drawellipse_curs.h b/vcl/unx/source/inc/drawellipse_curs.h
new file mode 100644
index 000000000000..f1df489167f0
--- /dev/null
+++ b/vcl/unx/source/inc/drawellipse_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawellipse_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawellipse_curs_width 32
+#define drawellipse_curs_height 32
+#define drawellipse_curs_x_hot 7
+#define drawellipse_curs_y_hot 7
+static char drawellipse_curs_bits[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x42, 0x00,
+ 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x81, 0x00,
+ 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x3c, 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};
diff --git a/vcl/unx/source/inc/drawellipse_mask.h b/vcl/unx/source/inc/drawellipse_mask.h
new file mode 100644
index 000000000000..4f4c8a00fd2c
--- /dev/null
+++ b/vcl/unx/source/inc/drawellipse_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawellipse_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawellipse_mask_width 32
+#define drawellipse_mask_height 32
+static char drawellipse_mask_bits[] = {
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x3f, 0x7e, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x3f, 0x7e, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0x80, 0xe7, 0x01, 0x00, 0x80, 0xc3, 0x01, 0x00, 0x80, 0xc3, 0x01,
+ 0x00, 0x80, 0xe7, 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x7e, 0x00,
+ 0x00, 0x00, 0x3c, 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};
diff --git a/vcl/unx/source/inc/drawfreehand_curs.h b/vcl/unx/source/inc/drawfreehand_curs.h
new file mode 100644
index 000000000000..34a54b5124ec
--- /dev/null
+++ b/vcl/unx/source/inc/drawfreehand_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawfreehand_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawfreehand_curs_width 32
+#define drawfreehand_curs_height 32
+#define drawfreehand_curs_x_hot 8
+#define drawfreehand_curs_y_hot 8
+static char drawfreehand_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xfd, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x88, 0x00, 0x02, 0x00, 0x84, 0x00, 0x01, 0x00, 0x84, 0xc0, 0x00,
+ 0x00, 0x04, 0x3f, 0x00, 0x00, 0x04, 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};
diff --git a/vcl/unx/source/inc/drawfreehand_mask.h b/vcl/unx/source/inc/drawfreehand_mask.h
new file mode 100644
index 000000000000..e56aafe3d56c
--- /dev/null
+++ b/vcl/unx/source/inc/drawfreehand_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawfreehand_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawfreehand_mask_width 32
+#define drawfreehand_mask_height 32
+static char drawfreehand_mask_bits[] = {
+ 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0xff, 0xff, 0x01, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x08,
+ 0x80, 0x03, 0x00, 0x1c, 0x80, 0x73, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x07,
+ 0x00, 0xfc, 0x01, 0x07, 0x00, 0xce, 0xc1, 0x03, 0x00, 0xce, 0xff, 0x01,
+ 0x00, 0x8e, 0xff, 0x00, 0x00, 0x0e, 0x3f, 0x00, 0x00, 0x0e, 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};
diff --git a/vcl/unx/source/inc/drawline_curs.h b/vcl/unx/source/inc/drawline_curs.h
new file mode 100644
index 000000000000..830f42966c0b
--- /dev/null
+++ b/vcl/unx/source/inc/drawline_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawline_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawline_curs_width 32
+#define drawline_curs_height 32
+#define drawline_curs_x_hot 7
+#define drawline_curs_y_hot 7
+static char drawline_curs_bits[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00,
+ 0x00, 0x00, 0x03, 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};
diff --git a/vcl/unx/source/inc/drawline_mask.h b/vcl/unx/source/inc/drawline_mask.h
new file mode 100644
index 000000000000..58e436fadcc3
--- /dev/null
+++ b/vcl/unx/source/inc/drawline_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawline_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawline_mask_width 32
+#define drawline_mask_height 32
+static char drawline_mask_bits[] = {
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x3f, 0xfe, 0x00, 0x00, 0xbf, 0xfe, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x70,
+ 0xc0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0xc0, 0x0f,
+ 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00,
+ 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 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};
diff --git a/vcl/unx/source/inc/drawmirror_curs.h b/vcl/unx/source/inc/drawmirror_curs.h
new file mode 100644
index 000000000000..59b604dcec4b
--- /dev/null
+++ b/vcl/unx/source/inc/drawmirror_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawmirror_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawmirror_curs_width 32
+#define drawmirror_curs_height 32
+#define drawmirror_curs_x_hot 14
+#define drawmirror_curs_y_hot 12
+static char drawmirror_curs_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x03, 0xf8, 0xf5, 0xff,
+ 0xfb, 0xfb, 0xee, 0xff, 0x0b, 0xfa, 0xf5, 0xff, 0xeb, 0xfa, 0xfa, 0xff,
+ 0xeb, 0xfa, 0xfa, 0xff, 0xeb, 0x7a, 0xfd, 0xff, 0xeb, 0x7a, 0xfd, 0xff,
+ 0xeb, 0xba, 0x7e, 0xff, 0xeb, 0xba, 0xbe, 0xfe, 0xeb, 0x5a, 0x5f, 0xfd,
+ 0x0b, 0x5a, 0xaf, 0xfa, 0xfb, 0xab, 0xd7, 0xf5, 0x03, 0xa8, 0xeb, 0xeb,
+ 0xff, 0xd7, 0xf5, 0xf5, 0xff, 0xd7, 0xfa, 0xfa, 0xff, 0x6b, 0x7d, 0xfd,
+ 0xff, 0xeb, 0xba, 0xfe, 0xff, 0xf5, 0x55, 0xff, 0xff, 0xf5, 0xab, 0xff,
+ 0xff, 0xfa, 0xd7, 0xff, 0x7f, 0xf7, 0xef, 0xff, 0xff, 0xfa, 0xff, 0xff,
+ 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/vcl/unx/source/inc/drawmirror_mask.h b/vcl/unx/source/inc/drawmirror_mask.h
new file mode 100644
index 000000000000..2858036f5139
--- /dev/null
+++ b/vcl/unx/source/inc/drawmirror_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawmirror_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawmirror_mask_width 32
+#define drawmirror_mask_height 32
+static char drawmirror_mask_bits[] = {
+ 0x00, 0x00, 0x04, 0x00, 0xfe, 0x0f, 0x0e, 0x00, 0xfe, 0x0f, 0x1f, 0x00,
+ 0xfe, 0x8f, 0x3f, 0x00, 0xfe, 0x0f, 0x1f, 0x00, 0xfe, 0x8f, 0x0f, 0x00,
+ 0xbe, 0x8f, 0x0f, 0x00, 0xbe, 0xcf, 0x07, 0x00, 0xbe, 0xcf, 0x87, 0x00,
+ 0xbe, 0xef, 0xc3, 0x01, 0xbe, 0xef, 0xe3, 0x03, 0xfe, 0xff, 0xf1, 0x07,
+ 0xfe, 0xff, 0x79, 0x0f, 0xfe, 0xff, 0x3c, 0x1e, 0xfe, 0xff, 0x1e, 0x3c,
+ 0xfe, 0x7f, 0x0f, 0x1e, 0x00, 0xfc, 0x07, 0x0f, 0x00, 0xfe, 0x83, 0x07,
+ 0x00, 0xbe, 0xc7, 0x03, 0x00, 0x1f, 0xef, 0x01, 0x00, 0x1f, 0xfe, 0x00,
+ 0x80, 0x0f, 0x7c, 0x00, 0xc0, 0x1d, 0x38, 0x00, 0x80, 0x0f, 0x10, 0x00,
+ 0x00, 0x07, 0x00, 0x00, 0x00, 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};
diff --git a/vcl/unx/source/inc/drawpie_curs.h b/vcl/unx/source/inc/drawpie_curs.h
new file mode 100644
index 000000000000..0b289f9dbb2d
--- /dev/null
+++ b/vcl/unx/source/inc/drawpie_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawpie_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawpie_curs_width 32
+#define drawpie_curs_height 32
+#define drawpie_curs_x_hot 7
+#define drawpie_curs_y_hot 7
+static char drawpie_curs_bits[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0a, 0x00,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xf9, 0x00,
+ 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x3c, 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};
diff --git a/vcl/unx/source/inc/drawpie_mask.h b/vcl/unx/source/inc/drawpie_mask.h
new file mode 100644
index 000000000000..e0be2e64d35a
--- /dev/null
+++ b/vcl/unx/source/inc/drawpie_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawpie_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawpie_mask_width 32
+#define drawpie_mask_height 32
+static char drawpie_mask_bits[] = {
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x3f, 0x7e, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x3f, 0x7e, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00,
+ 0x00, 0x80, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x80, 0xff, 0x01,
+ 0x00, 0x80, 0xfb, 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x7e, 0x00,
+ 0x00, 0x00, 0x3c, 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};
diff --git a/vcl/unx/source/inc/drawpolygon_curs.h b/vcl/unx/source/inc/drawpolygon_curs.h
new file mode 100644
index 000000000000..2ac109600373
--- /dev/null
+++ b/vcl/unx/source/inc/drawpolygon_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawpolygon_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawpolygon_curs_width 32
+#define drawpolygon_curs_height 32
+#define drawpolygon_curs_x_hot 7
+#define drawpolygon_curs_y_hot 7
+static char drawpolygon_curs_bits[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x83, 0x00,
+ 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x99, 0x00,
+ 0x00, 0x00, 0x89, 0x03, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/drawpolygon_mask.h b/vcl/unx/source/inc/drawpolygon_mask.h
new file mode 100644
index 000000000000..687d8c098798
--- /dev/null
+++ b/vcl/unx/source/inc/drawpolygon_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawpolygon_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawpolygon_mask_width 32
+#define drawpolygon_mask_height 32
+static char drawpolygon_mask_bits[] = {
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x3f, 0x7e, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x3f, 0x7e, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1e, 0x06,
+ 0x00, 0x00, 0x1e, 0x07, 0x00, 0x00, 0xbe, 0x07, 0x00, 0x00, 0xfe, 0x07,
+ 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x7e, 0x1f, 0x00, 0x00, 0x3e, 0x1f,
+ 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x0e, 0x07, 0x00, 0x00, 0x0e, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/drawrect_curs.h b/vcl/unx/source/inc/drawrect_curs.h
new file mode 100644
index 000000000000..5734700482b8
--- /dev/null
+++ b/vcl/unx/source/inc/drawrect_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawrect_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawrect_curs_width 32
+#define drawrect_curs_height 32
+#define drawrect_curs_x_hot 7
+#define drawrect_curs_y_hot 7
+static char drawrect_curs_bits[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x81, 0x00,
+ 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x81, 0x00,
+ 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/drawrect_mask.h b/vcl/unx/source/inc/drawrect_mask.h
new file mode 100644
index 000000000000..ce97b52d1ff3
--- /dev/null
+++ b/vcl/unx/source/inc/drawrect_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawrect_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawrect_mask_width 32
+#define drawrect_mask_height 32
+static char drawrect_mask_bits[] = {
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x3f, 0x7e, 0x00, 0x00, 0xbf, 0x7e, 0x00, 0x00, 0x3f, 0x7e, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+ 0x00, 0x80, 0xff, 0x01, 0x00, 0x80, 0xff, 0x01, 0x00, 0x80, 0xff, 0x01,
+ 0x00, 0x80, 0xc3, 0x01, 0x00, 0x80, 0xc3, 0x01, 0x00, 0x80, 0xff, 0x01,
+ 0x00, 0x80, 0xff, 0x01, 0x00, 0x80, 0xff, 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};
diff --git a/vcl/unx/source/inc/drawtext_curs.h b/vcl/unx/source/inc/drawtext_curs.h
new file mode 100644
index 000000000000..ec2b30198f41
--- /dev/null
+++ b/vcl/unx/source/inc/drawtext_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawtext_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawtext_curs_width 32
+#define drawtext_curs_height 32
+#define drawtext_curs_x_hot 8
+#define drawtext_curs_y_hot 8
+static char drawtext_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xfd, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x81, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x80, 0x0d, 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};
diff --git a/vcl/unx/source/inc/drawtext_mask.h b/vcl/unx/source/inc/drawtext_mask.h
new file mode 100644
index 000000000000..c045333f0fe4
--- /dev/null
+++ b/vcl/unx/source/inc/drawtext_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawtext_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define drawtext_mask_width 32
+#define drawtext_mask_height 32
+static char drawtext_mask_bits[] = {
+ 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0xff, 0xff, 0x01, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0xc3, 0x1f, 0x00,
+ 0x80, 0xc3, 0x1f, 0x00, 0x80, 0xc3, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00,
+ 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xc0, 0x1f, 0x00,
+ 0x00, 0xc0, 0x1f, 0x00, 0x00, 0xc0, 0x1f, 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};
diff --git a/vcl/unx/source/inc/fill_curs.h b/vcl/unx/source/inc/fill_curs.h
new file mode 100644
index 000000000000..eab6f5d1f9fc
--- /dev/null
+++ b/vcl/unx/source/inc/fill_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: fill_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define fill_curs_width 32
+#define fill_curs_height 32
+#define fill_curs_x_hot 10
+#define fill_curs_y_hot 22
+static char fill_curs_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,0x00,0x00,0x03,0x00,0x00,0x80,0x02,0x00,0x00,0x5c,0x0c,0x00,0x00,
+ 0x2e,0x12,0x00,0x00,0x17,0x38,0x00,0x00,0x0b,0x7c,0x00,0x00,0x5b,0xbe,0x00,
+ 0x00,0x27,0x9f,0x00,0x00,0xa7,0x4f,0x00,0x00,0xc7,0x27,0x00,0x00,0x87,0x13,
+ 0x00,0x00,0x06,0x09,0x00,0x00,0x06,0x06,0x00,0x00,0x04,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};
diff --git a/vcl/unx/source/inc/fill_mask.h b/vcl/unx/source/inc/fill_mask.h
new file mode 100644
index 000000000000..a3d1e935f8a6
--- /dev/null
+++ b/vcl/unx/source/inc/fill_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: fill_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define fill_mask_width 32
+#define fill_mask_height 32
+#define fill_mask_x_hot 10
+#define fill_mask_y_hot 22
+static char fill_mask_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,0x00,0x00,0x03,0x00,0x00,0x80,0x03,0x00,0x00,0xdc,0x0f,0x00,0x00,
+ 0xfe,0x1f,0x00,0x00,0xff,0x3f,0x00,0x00,0xff,0x7f,0x00,0x00,0xff,0xff,0x00,
+ 0x00,0xe7,0xff,0x00,0x00,0xe7,0x7f,0x00,0x00,0xc7,0x3f,0x00,0x00,0x87,0x1f,
+ 0x00,0x00,0x06,0x0f,0x00,0x00,0x06,0x06,0x00,0x00,0x04,0x00,0x00,0x00,0x04,
+ 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};
diff --git a/vcl/unx/source/inc/hshear_curs.h b/vcl/unx/source/inc/hshear_curs.h
new file mode 100644
index 000000000000..f45a162c866e
--- /dev/null
+++ b/vcl/unx/source/inc/hshear_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: hshear_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define hshear_curs_width 32
+#define hshear_curs_height 32
+#define hshear_curs_x_hot 15
+#define hshear_curs_y_hot 15
+static char hshear_curs_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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x3c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0c, 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};
diff --git a/vcl/unx/source/inc/hshear_mask.h b/vcl/unx/source/inc/hshear_mask.h
new file mode 100644
index 000000000000..d43b505cd6de
--- /dev/null
+++ b/vcl/unx/source/inc/hshear_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: hshear_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define hshear_mask_width 32
+#define hshear_mask_height 32
+static char hshear_mask_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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00,
+ 0x80, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01,
+ 0x80, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x3e, 0x00,
+ 0x00, 0x00, 0x0e, 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};
diff --git a/vcl/unx/source/inc/invert50.h b/vcl/unx/source/inc/invert50.h
new file mode 100644
index 000000000000..bd9a48e94833
--- /dev/null
+++ b/vcl/unx/source/inc/invert50.h
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * $RCSfile: invert50.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define invert50_width 32
+#define invert50_height 32
+static char invert50_bits[] = {
+#if 1
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+#else
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+#endif
+};
diff --git a/vcl/unx/source/inc/linkdata_curs.h b/vcl/unx/source/inc/linkdata_curs.h
new file mode 100644
index 000000000000..c6fd5105967c
--- /dev/null
+++ b/vcl/unx/source/inc/linkdata_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: linkdata_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define linkdata_curs_width 32
+#define linkdata_curs_height 32
+#define linkdata_curs_x_hot 1
+#define linkdata_curs_y_hot 1
+static char linkdata_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
+ 0x7e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00,
+ 0xfe, 0x03, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
+ 0x66, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x10, 0x53, 0x00, 0x00,
+ 0x28, 0xa3, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x10, 0xf0, 0x1f, 0x00, 0x08, 0x70, 0x18, 0x00, 0x10, 0xf0, 0x18, 0x00,
+ 0xa8, 0x72, 0x18, 0x00, 0x50, 0x35, 0x1a, 0x00, 0x00, 0x30, 0x1f, 0x00,
+ 0x00, 0xb0, 0x1f, 0x00, 0x00, 0x70, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/linkdata_mask.h b/vcl/unx/source/inc/linkdata_mask.h
new file mode 100644
index 000000000000..93ec3011a8e3
--- /dev/null
+++ b/vcl/unx/source/inc/linkdata_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: linkdata_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define linkdata_mask_width 32
+#define linkdata_mask_height 32
+#define linkdata_mask_x_hot 1
+#define linkdata_mask_y_hot 1
+static char linkdata_mask_bits[] = {
+ 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xe7, 0x03, 0x00, 0x00,
+ 0xe0, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00,
+ 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x3c, 0xf8, 0x3f, 0x00,
+ 0x3c, 0xf8, 0x3f, 0x00, 0x3c, 0xf8, 0x3f, 0x00, 0xfc, 0xff, 0x3f, 0x00,
+ 0xfc, 0xff, 0x3f, 0x00, 0xfc, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f, 0x00,
+ 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00,
+ 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/linkfile_curs.h b/vcl/unx/source/inc/linkfile_curs.h
new file mode 100644
index 000000000000..75f391383e49
--- /dev/null
+++ b/vcl/unx/source/inc/linkfile_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: linkfile_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define linkfile_curs_width 32
+#define linkfile_curs_height 32
+#define linkfile_curs_x_hot 9
+#define linkfile_curs_y_hot 9
+static char linkfile_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x00, 0x00,
+ 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
+ 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x00,
+ 0xfe, 0x02, 0x00, 0x00, 0xfe, 0x06, 0x00, 0x00, 0xfe, 0x0e, 0x00, 0x00,
+ 0xfe, 0x1e, 0x00, 0x00, 0xfe, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+ 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x03, 0x00,
+ 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00,
+ 0x00, 0xc2, 0xe0, 0x3f, 0x00, 0xc0, 0xe0, 0x30, 0x00, 0x80, 0xe1, 0x31,
+ 0x00, 0x80, 0xe1, 0x30, 0x00, 0x00, 0x63, 0x34, 0x00, 0x00, 0x63, 0x3e,
+ 0x00, 0x00, 0x60, 0x3f, 0x00, 0x00, 0xe0, 0x3e, 0x00, 0x00, 0xe0, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/linkfile_mask.h b/vcl/unx/source/inc/linkfile_mask.h
new file mode 100644
index 000000000000..4fb151b8a72f
--- /dev/null
+++ b/vcl/unx/source/inc/linkfile_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: linkfile_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define linkfile_mask_width 32
+#define linkfile_mask_height 32
+#define linkfile_mask_x_hot 9
+#define linkfile_mask_y_hot 9
+static char linkfile_mask_bits[] = {
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00,
+ 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00,
+ 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xf1, 0x7f,
+ 0x00, 0xff, 0xf1, 0x7f, 0x00, 0xe7, 0xf3, 0x7f, 0x00, 0xe0, 0xf3, 0x7f,
+ 0x00, 0xc0, 0xf7, 0x7f, 0x00, 0xc0, 0xf7, 0x7f, 0x00, 0x80, 0xf7, 0x7f,
+ 0x00, 0x80, 0xf7, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f,
+ 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/magnify_curs.h b/vcl/unx/source/inc/magnify_curs.h
new file mode 100644
index 000000000000..79009a88b1b1
--- /dev/null
+++ b/vcl/unx/source/inc/magnify_curs.h
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * $RCSfile: magnify_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define magnify_curs_width 16
+#define magnify_curs_height 16
+#define magnify_curs_x_hot 6
+#define magnify_curs_y_hot 6
+static char magnify_curs_bits[] = {
+ 0x00, 0x00, 0xe0, 0x00, 0x18, 0x03, 0x04, 0x04, 0x14, 0x05, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x14, 0x05, 0x04, 0x04, 0x18, 0x0f, 0xe0, 0x1c,
+ 0x00, 0x38, 0x00, 0x70, 0x00, 0x60, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/magnify_mask.h b/vcl/unx/source/inc/magnify_mask.h
new file mode 100644
index 000000000000..895582f4cda9
--- /dev/null
+++ b/vcl/unx/source/inc/magnify_mask.h
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * $RCSfile: magnify_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define magnify_mask_width 16
+#define magnify_mask_height 16
+static char magnify_mask_bits[] = {
+ 0xe0, 0x00, 0xf8, 0x03, 0xfc, 0x07, 0xfe, 0x0f, 0xfe, 0x0f, 0xff, 0x1f,
+ 0xff, 0x1f, 0xff, 0x1f, 0xfe, 0x0f, 0xfe, 0x0f, 0xfc, 0x1f, 0xf8, 0x3f,
+ 0xe0, 0x7c, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xe0};
diff --git a/vcl/unx/source/inc/mirror_curs.h b/vcl/unx/source/inc/mirror_curs.h
new file mode 100644
index 000000000000..931eb7b47762
--- /dev/null
+++ b/vcl/unx/source/inc/mirror_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: mirror_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define mirror_curs_width 32
+#define mirror_curs_height 32
+#define mirror_curs_x_hot 14
+#define mirror_curs_y_hot 12
+static char mirror_curs_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x03, 0xf8, 0xf5, 0xff,
+ 0xfb, 0xfb, 0xee, 0xff, 0x0b, 0xfa, 0xf5, 0xff, 0xeb, 0xfa, 0xfa, 0xff,
+ 0xeb, 0xfa, 0xfa, 0xff, 0xeb, 0x7a, 0xfd, 0xff, 0xeb, 0x7a, 0xfd, 0xff,
+ 0xeb, 0xba, 0x7e, 0xff, 0xeb, 0xba, 0xbe, 0xfe, 0xeb, 0x5a, 0x5f, 0xfd,
+ 0x0b, 0x5a, 0xaf, 0xfa, 0xfb, 0xab, 0xd7, 0xf5, 0x03, 0xa8, 0xeb, 0xeb,
+ 0xff, 0xd7, 0xf5, 0xf5, 0xff, 0xd7, 0xfa, 0xfa, 0xff, 0x6b, 0x7d, 0xfd,
+ 0xff, 0xeb, 0xba, 0xfe, 0xff, 0xf5, 0x55, 0xff, 0xff, 0xf5, 0xab, 0xff,
+ 0xff, 0xfa, 0xd7, 0xff, 0x7f, 0xf7, 0xef, 0xff, 0xff, 0xfa, 0xff, 0xff,
+ 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/vcl/unx/source/inc/mirror_mask.h b/vcl/unx/source/inc/mirror_mask.h
new file mode 100644
index 000000000000..3337a2226d74
--- /dev/null
+++ b/vcl/unx/source/inc/mirror_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: mirror_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:46 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define mirror_mask_width 32
+#define mirror_mask_height 32
+static char mirror_mask_bits[] = {
+ 0x00, 0x00, 0x04, 0x00, 0xfe, 0x0f, 0x0e, 0x00, 0xfe, 0x0f, 0x1f, 0x00,
+ 0xfe, 0x8f, 0x3f, 0x00, 0xfe, 0x0f, 0x1f, 0x00, 0xfe, 0x8f, 0x0f, 0x00,
+ 0xbe, 0x8f, 0x0f, 0x00, 0xbe, 0xcf, 0x07, 0x00, 0xbe, 0xcf, 0x87, 0x00,
+ 0xbe, 0xef, 0xc3, 0x01, 0xbe, 0xef, 0xe3, 0x03, 0xfe, 0xff, 0xf1, 0x07,
+ 0xfe, 0xff, 0x79, 0x0f, 0xfe, 0xff, 0x3c, 0x1e, 0xfe, 0xff, 0x1e, 0x3c,
+ 0xfe, 0x7f, 0x0f, 0x1e, 0x00, 0xfc, 0x07, 0x0f, 0x00, 0xfe, 0x83, 0x07,
+ 0x00, 0xbe, 0xc7, 0x03, 0x00, 0x1f, 0xef, 0x01, 0x00, 0x1f, 0xfe, 0x00,
+ 0x80, 0x0f, 0x7c, 0x00, 0xc0, 0x1d, 0x38, 0x00, 0x80, 0x0f, 0x10, 0x00,
+ 0x00, 0x07, 0x00, 0x00, 0x00, 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};
diff --git a/vcl/unx/source/inc/movebezierweight_curs.h b/vcl/unx/source/inc/movebezierweight_curs.h
new file mode 100644
index 000000000000..ceb4cb7404d1
--- /dev/null
+++ b/vcl/unx/source/inc/movebezierweight_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movebezierweight_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:45 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movebezierweight_curs_width 32
+#define movebezierweight_curs_height 32
+#define movebezierweight_curs_x_hot 0
+#define movebezierweight_curs_y_hot 0
+static char movebezierweight_curs_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff,
+ 0x81, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff,
+ 0x01, 0xfc, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0x91, 0xff, 0xff, 0xff,
+ 0x99, 0xff, 0xff, 0xef, 0x3d, 0xff, 0xff, 0xef, 0x3f, 0xff, 0xff, 0xef,
+ 0x7f, 0xfe, 0xff, 0xf7, 0x7f, 0xfe, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xfb,
+ 0xff, 0x7c, 0xff, 0xec, 0xff, 0xbf, 0x0e, 0xd7, 0xff, 0x7f, 0xf3, 0xef,
+ 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff,
+ 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/vcl/unx/source/inc/movebezierweight_mask.h b/vcl/unx/source/inc/movebezierweight_mask.h
new file mode 100644
index 000000000000..ed5235fcdd3b
--- /dev/null
+++ b/vcl/unx/source/inc/movebezierweight_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: movebezierweight_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movebezierweight_mask_width 32
+#define movebezierweight_mask_height 32
+static char movebezierweight_mask_bits[] = {
+ 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x10,
+ 0xff, 0x00, 0x00, 0x38, 0xe7, 0x01, 0x00, 0x38, 0xe3, 0x01, 0x00, 0x38,
+ 0xc0, 0x03, 0x00, 0x1c, 0xc0, 0x03, 0x00, 0x1c, 0x80, 0x87, 0x00, 0x1f,
+ 0x80, 0xc7, 0xf1, 0x3f, 0x80, 0xe7, 0xff, 0x7f, 0x00, 0xc0, 0xff, 0x38,
+ 0x00, 0x80, 0x0f, 0x10, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/movedata_curs.h b/vcl/unx/source/inc/movedata_curs.h
new file mode 100644
index 000000000000..7a59a9a4ec90
--- /dev/null
+++ b/vcl/unx/source/inc/movedata_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movedata_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movedata_curs_width 32
+#define movedata_curs_height 32
+#define movedata_curs_x_hot 1
+#define movedata_curs_y_hot 1
+static char movedata_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
+ 0x7e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00,
+ 0xfe, 0x03, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
+ 0x66, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x10, 0x53, 0x00, 0x00,
+ 0x28, 0xa3, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00,
+ 0x10, 0x40, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00,
+ 0xa8, 0xaa, 0x00, 0x00, 0x50, 0x55, 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};
diff --git a/vcl/unx/source/inc/movedata_mask.h b/vcl/unx/source/inc/movedata_mask.h
new file mode 100644
index 000000000000..9b3af4d24282
--- /dev/null
+++ b/vcl/unx/source/inc/movedata_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movedata_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movedata_mask_width 32
+#define movedata_mask_height 32
+#define movedata_mask_x_hot 1
+#define movedata_mask_y_hot 1
+static char movedata_mask_bits[] = {
+ 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xe7, 0x03, 0x00, 0x00,
+ 0xe0, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00,
+ 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x3c, 0xe0, 0x01, 0x00,
+ 0x3c, 0xe0, 0x01, 0x00, 0x3c, 0xe0, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00,
+ 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/movedlnk_curs.h b/vcl/unx/source/inc/movedlnk_curs.h
new file mode 100644
index 000000000000..1bfd85decca1
--- /dev/null
+++ b/vcl/unx/source/inc/movedlnk_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movedlnk_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movedlnk_curs_width 32
+#define movedlnk_curs_height 32
+#define movedlnk_curs_x_hot 1
+#define movedlnk_curs_y_hot 1
+static char movedlnk_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
+ 0x7e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00,
+ 0xfe, 0x03, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
+ 0x66, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x10, 0x53, 0x00, 0x00,
+ 0x28, 0xa3, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf0, 0x81, 0x00, 0x00,
+ 0x30, 0x41, 0x00, 0x00, 0x10, 0x81, 0x00, 0x00, 0xd0, 0x41, 0x00, 0x00,
+ 0xf0, 0xa9, 0x00, 0x00, 0x00, 0x54, 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};
diff --git a/vcl/unx/source/inc/movedlnk_mask.h b/vcl/unx/source/inc/movedlnk_mask.h
new file mode 100644
index 000000000000..9fccbb7b72ff
--- /dev/null
+++ b/vcl/unx/source/inc/movedlnk_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movedlnk_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movedlnk_mask_width 32
+#define movedlnk_mask_height 32
+#define movedlnk_mask_x_hot 1
+#define movedlnk_mask_y_hot 1
+static char movedlnk_mask_bits[] = {
+ 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xe7, 0x03, 0x00, 0x00,
+ 0xe0, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00,
+ 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xf8, 0xe3, 0x01, 0x00,
+ 0xf8, 0xe3, 0x01, 0x00, 0xf8, 0xe3, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00,
+ 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0x00, 0xfe, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/movefile_curs.h b/vcl/unx/source/inc/movefile_curs.h
new file mode 100644
index 000000000000..99d565ac292f
--- /dev/null
+++ b/vcl/unx/source/inc/movefile_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movefile_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movefile_curs_width 32
+#define movefile_curs_height 32
+#define movefile_curs_x_hot 9
+#define movefile_curs_y_hot 9
+static char movefile_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x00, 0x00,
+ 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
+ 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x00,
+ 0xfe, 0x02, 0x00, 0x00, 0xfe, 0x06, 0x00, 0x00, 0xfe, 0x0e, 0x00, 0x00,
+ 0xfe, 0x1e, 0x00, 0x00, 0xfe, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+ 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x03, 0x00,
+ 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00,
+ 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/movefile_mask.h b/vcl/unx/source/inc/movefile_mask.h
new file mode 100644
index 000000000000..60c4291ce38a
--- /dev/null
+++ b/vcl/unx/source/inc/movefile_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movefile_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movefile_mask_width 32
+#define movefile_mask_height 32
+#define movefile_mask_x_hot 9
+#define movefile_mask_y_hot 9
+static char movefile_mask_bits[] = {
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00,
+ 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00,
+ 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00,
+ 0x00, 0xff, 0x01, 0x00, 0x00, 0xe7, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00,
+ 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/movefiles_curs.h b/vcl/unx/source/inc/movefiles_curs.h
new file mode 100644
index 000000000000..4a68f87e1881
--- /dev/null
+++ b/vcl/unx/source/inc/movefiles_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movefiles_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movefiles_curs_width 32
+#define movefiles_curs_height 32
+#define movefiles_curs_x_hot 8
+#define movefiles_curs_y_hot 9
+static char movefiles_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xe0, 0x2f, 0x00, 0x00,
+ 0xe8, 0x0f, 0x00, 0x00, 0xe8, 0x7f, 0x00, 0x00, 0xea, 0x7f, 0x00, 0x00,
+ 0xea, 0x7f, 0x00, 0x00, 0xea, 0x7f, 0x00, 0x00, 0x6a, 0x7e, 0x00, 0x00,
+ 0x6a, 0x7d, 0x00, 0x00, 0x6a, 0x7b, 0x00, 0x00, 0x6a, 0x77, 0x00, 0x00,
+ 0x6a, 0x6f, 0x00, 0x00, 0x6a, 0x5f, 0x00, 0x00, 0x0a, 0x3f, 0x00, 0x00,
+ 0x7a, 0x7f, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x7e, 0xff, 0x01, 0x00,
+ 0x00, 0x3f, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00,
+ 0x00, 0x61, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x01, 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};
diff --git a/vcl/unx/source/inc/movefiles_mask.h b/vcl/unx/source/inc/movefiles_mask.h
new file mode 100644
index 000000000000..2d7376344a81
--- /dev/null
+++ b/vcl/unx/source/inc/movefiles_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movefiles_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movefiles_mask_width 32
+#define movefiles_mask_height 32
+#define movefiles_mask_x_hot 8
+#define movefiles_mask_y_hot 9
+static char movefiles_mask_bits[] = {
+ 0xf0, 0x1f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00,
+ 0xfc, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00,
+ 0xff, 0xff, 0x03, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00,
+ 0x80, 0xff, 0x00, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0xf0, 0x01, 0x00,
+ 0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00,
+ 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/moveflnk_curs.h b/vcl/unx/source/inc/moveflnk_curs.h
new file mode 100644
index 000000000000..6f3c7374a700
--- /dev/null
+++ b/vcl/unx/source/inc/moveflnk_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: moveflnk_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define moveflnk_curs_width 32
+#define moveflnk_curs_height 32
+#define moveflnk_curs_x_hot 9
+#define moveflnk_curs_y_hot 9
+static char moveflnk_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x00, 0x00,
+ 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
+ 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00,
+ 0xbe, 0x02, 0x00, 0x00, 0xa6, 0x06, 0x00, 0x00, 0xa2, 0x0e, 0x00, 0x00,
+ 0xba, 0x1e, 0x00, 0x00, 0xbe, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+ 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x03, 0x00,
+ 0x00, 0x7e, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00,
+ 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/moveflnk_mask.h b/vcl/unx/source/inc/moveflnk_mask.h
new file mode 100644
index 000000000000..fc6e5ac17b4f
--- /dev/null
+++ b/vcl/unx/source/inc/moveflnk_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: moveflnk_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define moveflnk_mask_width 32
+#define moveflnk_mask_height 32
+#define moveflnk_mask_x_hot 9
+#define moveflnk_mask_y_hot 9
+static char moveflnk_mask_bits[] = {
+ 0xff, 0x01, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
+ 0xff, 0x0f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00,
+ 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,
+ 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00,
+ 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00,
+ 0x00, 0xff, 0x01, 0x00, 0x00, 0xe7, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00,
+ 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/movepoint_curs.h b/vcl/unx/source/inc/movepoint_curs.h
new file mode 100644
index 000000000000..17ff925c2dab
--- /dev/null
+++ b/vcl/unx/source/inc/movepoint_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: movepoint_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movepoint_curs_width 32
+#define movepoint_curs_height 32
+#define movepoint_curs_x_hot 0
+#define movepoint_curs_y_hot 0
+static char movepoint_curs_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff,
+ 0x81, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff,
+ 0x01, 0xfc, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0x91, 0xff, 0xff, 0xff,
+ 0x39, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff,
+ 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xfc, 0x83, 0xff, 0xff, 0xfc, 0x83, 0xff,
+ 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0x83, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/vcl/unx/source/inc/movepoint_mask.h b/vcl/unx/source/inc/movepoint_mask.h
new file mode 100644
index 000000000000..d7fa0c7d6bd1
--- /dev/null
+++ b/vcl/unx/source/inc/movepoint_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: movepoint_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define movepoint_mask_width 32
+#define movepoint_mask_height 32
+static char movepoint_mask_bits[] = {
+ 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0xef, 0x01, 0x00, 0x00, 0xe7, 0x01, 0x00, 0x00, 0xc3, 0x03, 0x00, 0x00,
+ 0xc0, 0x03, 0xfe, 0x00, 0x80, 0x07, 0xfe, 0x00, 0x80, 0x07, 0xfe, 0x00,
+ 0x80, 0x07, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x00,
+ 0x00, 0x00, 0xfe, 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};
diff --git a/vcl/unx/source/inc/nodrop_curs.h b/vcl/unx/source/inc/nodrop_curs.h
new file mode 100644
index 000000000000..739b69fed185
--- /dev/null
+++ b/vcl/unx/source/inc/nodrop_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: nodrop_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define nodrop_curs_width 32
+#define nodrop_curs_height 32
+#define nodrop_curs_x_hot 9
+#define nodrop_curs_y_hot 9
+static char nodrop_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00,
+ 0xf8, 0x7f, 0x00, 0x00, 0x7c, 0xf8, 0x00, 0x00, 0x1c, 0xfc, 0x00, 0x00,
+ 0x1e, 0xfe, 0x01, 0x00, 0x0e, 0xdf, 0x01, 0x00, 0x8e, 0xcf, 0x01, 0x00,
+ 0xce, 0xc7, 0x01, 0x00, 0xee, 0xc3, 0x01, 0x00, 0xfe, 0xe1, 0x01, 0x00,
+ 0xfc, 0xe0, 0x00, 0x00, 0x7c, 0xf8, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00,
+ 0xf0, 0x3f, 0x00, 0x00, 0xc0, 0x0f, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/nodrop_mask.h b/vcl/unx/source/inc/nodrop_mask.h
new file mode 100644
index 000000000000..81ae6be5d3f0
--- /dev/null
+++ b/vcl/unx/source/inc/nodrop_mask.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: nodrop_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define nodrop_mask_width 32
+#define nodrop_mask_height 32
+#define nodrop_mask_x_hot 9
+#define nodrop_mask_y_hot 9
+static char nodrop_mask_bits[] = {
+ 0xc0, 0x0f, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00,
+ 0xfc, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x7e, 0xfe, 0x01, 0x00,
+ 0x3f, 0xff, 0x03, 0x00, 0x9f, 0xff, 0x03, 0x00, 0xdf, 0xff, 0x03, 0x00,
+ 0xff, 0xef, 0x03, 0x00, 0xff, 0xe7, 0x03, 0x00, 0xff, 0xf3, 0x03, 0x00,
+ 0xfe, 0xf9, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00,
+ 0xf8, 0x7f, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xc0, 0x0f, 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, 0x00, 0x00, 0x00, 0x00};
diff --git a/vcl/unx/source/inc/null_curs.h b/vcl/unx/source/inc/null_curs.h
new file mode 100644
index 000000000000..884c4dd480f3
--- /dev/null
+++ b/vcl/unx/source/inc/null_curs.h
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * $RCSfile: null_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define nullcurs_width 4
+#define nullcurs_height 4
+#define nullcurs_x_hot 2
+#define nullcurs_y_hot 2
+static char nullcurs_bits[] = { 0x00, 0x00 };
diff --git a/vcl/unx/source/inc/null_mask.h b/vcl/unx/source/inc/null_mask.h
new file mode 100644
index 000000000000..f1f8c1c7c5aa
--- /dev/null
+++ b/vcl/unx/source/inc/null_mask.h
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * $RCSfile: null_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define nullmask_width 4
+#define nullmask_height 4
+static char nullmask_bits[] = { 0x00, 0x00 };
diff --git a/vcl/unx/source/inc/pivotcol_curs.h b/vcl/unx/source/inc/pivotcol_curs.h
new file mode 100644
index 000000000000..7dc40c274e69
--- /dev/null
+++ b/vcl/unx/source/inc/pivotcol_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: pivotcol_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define pivotcol_curs_width 32
+#define pivotcol_curs_height 32
+#define pivotcol_curs_x_hot 10
+#define pivotcol_curs_y_hot 13
+static char pivotcol_curs_bits[] = {
+ 0xff,0xff,0xff,0xff,0x01,0x80,0x00,0x80,0x55,0x95,0x54,0x95,0xa9,0xaa,0xaa,
+ 0xaa,0x01,0x80,0x00,0x80,0xff,0xff,0xff,0xff,0x81,0x80,0x80,0x80,0x95,0xaa,
+ 0xaa,0xaa,0xa9,0x94,0x94,0x94,0x95,0xaa,0xaa,0xaa,0xa9,0x94,0x94,0x94,0x81,
+ 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0x00,0x04,0x00,0x00,0x00,0x0c,0x00,0x00,
+ 0x00,0x14,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x84,0x00,
+ 0x00,0x00,0x04,0x01,0x00,0x00,0x04,0x02,0x00,0x00,0x04,0x04,0x00,0x00,0x04,
+ 0x08,0x00,0x00,0x04,0x1f,0x00,0x00,0x64,0x01,0x00,0x00,0x54,0x02,0x00,0x00,
+ 0x8c,0x02,0x00,0x00,0x84,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x09,0x00,
+ 0x00,0x00,0x0a,0x00,0x00,0x00,0x06,0x00};
diff --git a/vcl/unx/source/inc/pivotcol_mask.h b/vcl/unx/source/inc/pivotcol_mask.h
new file mode 100644
index 000000000000..75bba6d6dfc4
--- /dev/null
+++ b/vcl/unx/source/inc/pivotcol_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: pivotcol_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define pivotcol_mask_width 32
+#define pivotcol_mask_height 32
+#define pivotcol_mask_x_hot 10
+#define pivotcol_mask_y_hot 13
+static char pivotcol_mask_bits[] = {
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x04,0x00,0x00,0x00,0x0c,0x00,0x00,
+ 0x00,0x1c,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0xfc,0x00,
+ 0x00,0x00,0xfc,0x01,0x00,0x00,0xfc,0x03,0x00,0x00,0xfc,0x07,0x00,0x00,0xfc,
+ 0x0f,0x00,0x00,0xfc,0x1f,0x00,0x00,0xfc,0x01,0x00,0x00,0xdc,0x03,0x00,0x00,
+ 0x8c,0x03,0x00,0x00,0x84,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0f,0x00,
+ 0x00,0x00,0x0e,0x00,0x00,0x00,0x06,0x00};
diff --git a/vcl/unx/source/inc/pivotfld_curs.h b/vcl/unx/source/inc/pivotfld_curs.h
new file mode 100644
index 000000000000..a3ed760985f2
--- /dev/null
+++ b/vcl/unx/source/inc/pivotfld_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: pivotfld_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define pivotfld_curs_width 32
+#define pivotfld_curs_height 32
+#define pivotfld_curs_x_hot 10
+#define pivotfld_curs_y_hot 13
+static char pivotfld_curs_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0x3f,0x04,0x00,0x00,
+ 0x30,0xa4,0xaa,0xaa,0x3a,0x54,0x55,0x55,0x35,0xa4,0xaa,0xaa,0x3a,0x54,0x55,
+ 0x55,0x35,0xa4,0xaa,0xaa,0x3a,0x54,0x55,0x55,0x35,0xa4,0xaa,0xaa,0x3a,0xf4,
+ 0xff,0xff,0x3f,0xfc,0xff,0xff,0x3f,0x00,0x04,0x00,0x00,0x00,0x0c,0x00,0x00,
+ 0x00,0x14,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x84,0x00,
+ 0x00,0x00,0x04,0x01,0x00,0x00,0x04,0x02,0x00,0x00,0x04,0x04,0x00,0x00,0x04,
+ 0x08,0x00,0x00,0x04,0x1f,0x00,0x00,0x64,0x01,0x00,0x00,0x54,0x02,0x00,0x00,
+ 0x8c,0x02,0x00,0x00,0x84,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x09,0x00,
+ 0x00,0x00,0x0a,0x00,0x00,0x00,0x06,0x00};
diff --git a/vcl/unx/source/inc/pivotfld_mask.h b/vcl/unx/source/inc/pivotfld_mask.h
new file mode 100644
index 000000000000..2371fad5eea2
--- /dev/null
+++ b/vcl/unx/source/inc/pivotfld_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: pivotfld_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define pivotfld_mask_width 32
+#define pivotfld_mask_height 32
+#define pivotfld_mask_x_hot 10
+#define pivotfld_mask_y_hot 13
+static char pivotfld_mask_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0x3f,0xfc,0xff,0xff,
+ 0x3f,0xfc,0xff,0xff,0x3f,0xfc,0xff,0xff,0x3f,0xfc,0xff,0xff,0x3f,0xfc,0xff,
+ 0xff,0x3f,0xfc,0xff,0xff,0x3f,0xfc,0xff,0xff,0x3f,0xfc,0xff,0xff,0x3f,0xfc,
+ 0xff,0xff,0x3f,0xfc,0xff,0xff,0x3f,0x00,0x04,0x00,0x00,0x00,0x0c,0x00,0x00,
+ 0x00,0x1c,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0xfc,0x00,
+ 0x00,0x00,0xfc,0x01,0x00,0x00,0xfc,0x03,0x00,0x00,0xfc,0x07,0x00,0x00,0xfc,
+ 0x0f,0x00,0x00,0xfc,0x1f,0x00,0x00,0xfc,0x01,0x00,0x00,0xdc,0x03,0x00,0x00,
+ 0x8c,0x03,0x00,0x00,0x84,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0f,0x00,
+ 0x00,0x00,0x0e,0x00,0x00,0x00,0x06,0x00};
diff --git a/vcl/unx/source/inc/pivotrow_curs.h b/vcl/unx/source/inc/pivotrow_curs.h
new file mode 100644
index 000000000000..19e230131d88
--- /dev/null
+++ b/vcl/unx/source/inc/pivotrow_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: pivotrow_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define pivotrow_curs_width 32
+#define pivotrow_curs_height 32
+#define pivotrow_curs_x_hot 22
+#define pivotrow_curs_y_hot 13
+static char pivotrow_curs_bits[] = {
+ 0xff,0xff,0x3f,0x00,0x01,0x04,0x20,0x00,0xa9,0xa4,0x2a,0x00,0x55,0x55,0x25,
+ 0x00,0xa9,0xa4,0x2a,0x00,0x55,0x55,0x25,0x00,0xa9,0x04,0x20,0x00,0x55,0xfd,
+ 0x3f,0x00,0xa9,0x04,0x20,0x00,0x55,0x55,0x25,0x00,0xa9,0xa4,0x2a,0x00,0x55,
+ 0x55,0x25,0x00,0xa9,0xa4,0x2a,0x00,0x55,0x55,0x65,0x00,0x01,0x04,0xe0,0x00,
+ 0xff,0xff,0x7f,0x01,0x01,0x04,0x60,0x02,0x55,0x55,0x65,0x04,0xa9,0xa4,0x6a,
+ 0x08,0x55,0x55,0x65,0x10,0xa9,0xa4,0x6a,0x20,0x55,0x55,0x65,0x40,0xa9,0x04,
+ 0x60,0x80,0x55,0xfd,0x7f,0xf0,0xa9,0x04,0x60,0x16,0x55,0x55,0x65,0x25,0xa9,
+ 0xa4,0xea,0x28,0x55,0x55,0x65,0x48,0xa9,0xa4,0x2a,0x50,0x55,0x55,0x25,0x90,
+ 0x01,0x04,0x20,0xa0,0xff,0xff,0x3f,0x60};
diff --git a/vcl/unx/source/inc/pivotrow_mask.h b/vcl/unx/source/inc/pivotrow_mask.h
new file mode 100644
index 000000000000..52419ae19532
--- /dev/null
+++ b/vcl/unx/source/inc/pivotrow_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: pivotrow_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define pivotrow_mask_width 32
+#define pivotrow_mask_height 32
+#define pivotrow_curs_x_hot 22
+#define pivotrow_curs_y_hot 13
+static char pivotrow_mask_bits[] = {
+ 0xff,0xff,0x3f,0x00,0xff,0xff,0x3f,0x00,0xff,0xff,0x3f,0x00,0xff,0xff,0x3f,
+ 0x00,0xff,0xff,0x3f,0x00,0xff,0xff,0x3f,0x00,0xff,0xff,0x3f,0x00,0xff,0xff,
+ 0x3f,0x00,0xff,0xff,0x3f,0x00,0xff,0xff,0x3f,0x00,0xff,0xff,0x3f,0x00,0xff,
+ 0xff,0x3f,0x00,0xff,0xff,0x3f,0x00,0xff,0xff,0x7f,0x00,0xff,0xff,0xff,0x00,
+ 0xff,0xff,0xff,0x01,0xff,0xff,0xff,0x03,0xff,0xff,0xff,0x07,0xff,0xff,0xff,
+ 0x0f,0xff,0xff,0xff,0x1f,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0x7f,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xff,0xff,0xff,0x3d,0xff,
+ 0xff,0xff,0x38,0xff,0xff,0x7f,0x78,0xff,0xff,0x3f,0x70,0xff,0xff,0x3f,0xf0,
+ 0xff,0xff,0x3f,0xe0,0xff,0xff,0x3f,0x60};
diff --git a/vcl/unx/source/inc/rotate_curs.h b/vcl/unx/source/inc/rotate_curs.h
new file mode 100644
index 000000000000..1a9d1628e728
--- /dev/null
+++ b/vcl/unx/source/inc/rotate_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: rotate_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define rotate_curs_width 32
+#define rotate_curs_height 32
+#define rotate_curs_x_hot 15
+#define rotate_curs_y_hot 15
+static char rotate_curs_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0xd8, 0x00, 0x00,
+ 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00,
+ 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00, 0xe0, 0x03, 0x80, 0x00, 0x80, 0x00,
+ 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x02, 0x20, 0x00,
+ 0x00, 0x04, 0x10, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0xe0, 0x03, 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};
diff --git a/vcl/unx/source/inc/rotate_mask.h b/vcl/unx/source/inc/rotate_mask.h
new file mode 100644
index 000000000000..2ff24422007a
--- /dev/null
+++ b/vcl/unx/source/inc/rotate_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: rotate_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define rotate_mask_width 32
+#define rotate_mask_height 32
+static char rotate_mask_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
+ 0x00, 0xe0, 0x01, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xfc, 0x01, 0x00,
+ 0x00, 0xfe, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
+ 0x80, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x80, 0x00, 0xc0, 0x01, 0xc0, 0x01,
+ 0xc0, 0x01, 0xe0, 0x03, 0xc0, 0x01, 0xf0, 0x07, 0xc0, 0x01, 0xf0, 0x07,
+ 0x80, 0x03, 0xe0, 0x00, 0x80, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x70, 0x00,
+ 0x00, 0x1e, 0x3c, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00,
+ 0x00, 0xe0, 0x03, 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};
diff --git a/vcl/unx/source/inc/timemove_curs.h b/vcl/unx/source/inc/timemove_curs.h
new file mode 100644
index 000000000000..2f1a34027850
--- /dev/null
+++ b/vcl/unx/source/inc/timemove_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: timemove_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define timemove_curs_width 32
+#define timemove_curs_height 32
+#define timemove_curs_x_hot 16
+#define timemove_curs_y_hot 16
+static char timemove_curs_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,0x00,0x00,0x01,0x00,0x00,0x80,0x03,0x00,0x00,0xc0,0x07,0x00,0x00,
+ 0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xff,0x01,
+ 0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0xff,0xff,
+ 0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0xc0,
+ 0x07,0x00,0x00,0x80,0x03,0x00,0x00,0x00,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};
diff --git a/vcl/unx/source/inc/timemove_mask.h b/vcl/unx/source/inc/timemove_mask.h
new file mode 100644
index 000000000000..b2715335a988
--- /dev/null
+++ b/vcl/unx/source/inc/timemove_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: timemove_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define timemove_mask_width 32
+#define timemove_mask_height 32
+#define timemove_mask_x_hot 16
+#define timemove_mask_y_hot 16
+static char timemove_mask_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,
+ 0x01,0x00,0x00,0x80,0x03,0x00,0x00,0xc0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,
+ 0xc0,0x07,0x00,0x00,0x80,0x03,0x00,0x80,0xff,0xff,0x03,0x80,0xff,0xff,0x03,
+ 0x80,0xff,0xff,0x03,0x80,0xff,0xff,0x03,0x80,0xff,0xff,0x03,0x80,0xff,0xff,
+ 0x03,0x80,0xff,0xff,0x03,0x00,0x80,0x03,0x00,0x00,0xc0,0x07,0x00,0x00,0xe0,
+ 0x0f,0x00,0x00,0xc0,0x07,0x00,0x00,0x80,0x03,0x00,0x00,0x00,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};
diff --git a/vcl/unx/source/inc/timesize_curs.h b/vcl/unx/source/inc/timesize_curs.h
new file mode 100644
index 000000000000..7cc0d99926ae
--- /dev/null
+++ b/vcl/unx/source/inc/timesize_curs.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: timesize_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define timesize_curs_width 32
+#define timesize_curs_height 32
+#define timesize_curs_x_hot 16
+#define timesize_curs_y_hot 16
+static char timesize_curs_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,0x00,0xff,0xff,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
+ 0x01,0x01,0x01,0x00,0x81,0x03,0x01,0x00,0xc1,0x07,0x01,0x00,0x01,0x01,0x01,
+ 0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0xff,0xff,0x01,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0xc0,0x07,0x00,0x00,0x80,
+ 0x03,0x00,0x00,0x00,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};
diff --git a/vcl/unx/source/inc/timesize_mask.h b/vcl/unx/source/inc/timesize_mask.h
new file mode 100644
index 000000000000..036428e98202
--- /dev/null
+++ b/vcl/unx/source/inc/timesize_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: timesize_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:47 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define timesize_mask_width 32
+#define timesize_mask_height 32
+#define timesize_mask_x_hot 16
+#define timesize_mask_y_hot 16
+static char timesize_mask_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,0x80,0xff,
+ 0xff,0x03,0x80,0xff,0xff,0x03,0x80,0xff,0xff,0x03,0x80,0xff,0xff,0x03,0x80,
+ 0xff,0xff,0x03,0x80,0xff,0xff,0x03,0x80,0xff,0xff,0x03,0x80,0xff,0xff,0x03,
+ 0x80,0xff,0xff,0x03,0x80,0xff,0xff,0x03,0x80,0xff,0xff,0x03,0x80,0xff,0xff,
+ 0x03,0x00,0x80,0x03,0x00,0x00,0xc0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,
+ 0x07,0x00,0x00,0x80,0x03,0x00,0x00,0x00,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};
diff --git a/vcl/unx/source/inc/vshear_curs.h b/vcl/unx/source/inc/vshear_curs.h
new file mode 100644
index 000000000000..d5a2bc019770
--- /dev/null
+++ b/vcl/unx/source/inc/vshear_curs.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: vshear_curs.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define vshear_curs_width 32
+#define vshear_curs_height 32
+#define vshear_curs_x_hot 15
+#define vshear_curs_y_hot 15
+static char vshear_curs_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, 0x00, 0x20, 0x04, 0x00,
+ 0x00, 0x20, 0x04, 0x00, 0x00, 0x30, 0x04, 0x00, 0x00, 0x30, 0x04, 0x00,
+ 0x00, 0x38, 0x04, 0x00, 0x00, 0x38, 0x04, 0x00, 0x00, 0x20, 0x04, 0x00,
+ 0x00, 0x20, 0x04, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x20, 0x04, 0x00,
+ 0x00, 0x20, 0x1c, 0x00, 0x00, 0x20, 0x1c, 0x00, 0x00, 0x20, 0x0c, 0x00,
+ 0x00, 0x20, 0x0c, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x20, 0x04, 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};
diff --git a/vcl/unx/source/inc/vshear_mask.h b/vcl/unx/source/inc/vshear_mask.h
new file mode 100644
index 000000000000..9006fbb3f17f
--- /dev/null
+++ b/vcl/unx/source/inc/vshear_mask.h
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * $RCSfile: vshear_mask.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define vshear_mask_width 32
+#define vshear_mask_height 32
+static char vshear_mask_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, 0x70, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00,
+ 0x00, 0x70, 0x0e, 0x00, 0x00, 0x78, 0x0e, 0x00, 0x00, 0x78, 0x0e, 0x00,
+ 0x00, 0x7c, 0x0e, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x00, 0x7c, 0x0e, 0x00,
+ 0x00, 0x70, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x70, 0x3e, 0x00,
+ 0x00, 0x70, 0x3e, 0x00, 0x00, 0x70, 0x3e, 0x00, 0x00, 0x70, 0x1e, 0x00,
+ 0x00, 0x70, 0x1e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00,
+ 0x00, 0x70, 0x0e, 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};
diff --git a/vcl/unx/source/window/FWS.cxx b/vcl/unx/source/window/FWS.cxx
new file mode 100644
index 000000000000..3e340b104145
--- /dev/null
+++ b/vcl/unx/source/window/FWS.cxx
@@ -0,0 +1,314 @@
+/*************************************************************************
+ *
+ * $RCSfile: FWS.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#ifndef _FOREIGN_WINDOW_SYSTEM_HXX
+#include "FWS.hxx"
+#endif
+
+static Atom fwsIconAtom;
+
+static Atom FWS_CLIENT;
+static Atom FWS_COMM_WINDOW;
+static Atom FWS_PROTOCOLS;
+static Atom FWS_STACK_UNDER;
+static Atom FWS_PARK_ICONS;
+static Atom FWS_PASS_ALL_INPUT;
+static Atom FWS_PASSES_INPUT;
+static Atom FWS_HANDLES_FOCUS;
+
+static Atom FWS_REGISTER_WINDOW;
+static Atom FWS_STATE_CHANGE;
+static Atom FWS_UNSEEN_STATE;
+static Atom FWS_NORMAL_STATE;
+static Atom WM_PROTOCOLS;
+static Atom WM_CHANGE_STATE;
+
+static Bool fwsStackUnder;
+static Bool fwsParkIcons;
+static Bool fwsPassesInput;
+static Bool fwsHandlesFocus;
+
+static Window fwsCommWindow;
+
+/*************************************<->***********************************
+ *
+ * WMSupportsFWS() -
+ *
+ * Initialize our atoms and determine if the current window manager is
+ * providing FWS extension support.
+ *
+ *************************************<->***********************************/
+
+Bool
+WMSupportsFWS (Display *display, int screen)
+{
+ int i;
+ Atom protocol;
+ Atom propType;
+ int propFormat;
+ unsigned long propItems;
+ unsigned long propBytesAfter;
+ unsigned char *propData;
+ char propName[30];
+
+ FWS_CLIENT = XInternAtom(display, "_SUN_FWS_CLIENT", False);
+ FWS_COMM_WINDOW = XInternAtom(display, "_SUN_FWS_COMM_WINDOW", False);
+ FWS_PROTOCOLS = XInternAtom(display, "_SUN_FWS_PROTOCOLS", False);
+ FWS_STACK_UNDER = XInternAtom(display, "_SUN_FWS_STACK_UNDER", False);
+ FWS_PARK_ICONS = XInternAtom(display, "_SUN_FWS_PARK_ICONS", False);
+ FWS_PASS_ALL_INPUT = XInternAtom(display, "_SUN_FWS_PASS_ALL_INPUT", False);
+ FWS_PASSES_INPUT = XInternAtom(display, "_SUN_FWS_PASSES_INPUT", False);
+ FWS_HANDLES_FOCUS = XInternAtom(display, "_SUN_FWS_HANDLES_FOCUS", False);
+ FWS_REGISTER_WINDOW= XInternAtom(display, "_SUN_FWS_REGISTER_WINDOW",False);
+ FWS_STATE_CHANGE = XInternAtom(display, "_SUN_FWS_STATE_CHANGE", False);
+ FWS_UNSEEN_STATE = XInternAtom(display, "_SUN_FWS_UNSEEN_STATE", False);
+ FWS_NORMAL_STATE = XInternAtom(display, "_SUN_FWS_NORMAL_STATE", False);
+ WM_PROTOCOLS = XInternAtom(display, "WM_PROTOCOLS", False);
+ WM_CHANGE_STATE = XInternAtom(display, "WM_CHANGE_STATE", False);
+
+ sprintf (propName, "_SUN_FWS_NEXT_ICON_%d", screen);
+ fwsIconAtom = XInternAtom(display, propName, False);
+
+ if (XGetWindowProperty (display, DefaultRootWindow (display),
+ FWS_COMM_WINDOW, 0, 1,
+ False, AnyPropertyType, &propType,
+ &propFormat, &propItems,
+ &propBytesAfter, &propData) != Success)
+ return False;
+
+ if (propFormat != 32 ||
+ propItems != 1 ||
+ propBytesAfter != 0)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "Bad FWS_COMM_WINDOW property on root window.\n");
+ #endif
+ XFree (propData);
+ return False;
+ }
+
+ fwsCommWindow = *(Window *) propData;
+ #ifdef DEBUG
+ fprintf (stderr, "Using fwsCommWindow = 0x%lx.\n", fwsCommWindow);
+ #endif
+ XFree (propData);
+
+
+ if (XGetWindowProperty (display, DefaultRootWindow (display),
+ FWS_PROTOCOLS, 0, 10,
+ False, AnyPropertyType, &propType,
+ &propFormat, &propItems,
+ &propBytesAfter, &propData) != Success)
+ {
+ return False;
+ }
+
+ if (propFormat != 32 ||
+ propBytesAfter != 0)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "Bad FWS_PROTOCOLS property on root window.\n");
+ #endif
+ XFree (propData);
+ return False;
+ }
+
+ for (i = 0; i < propItems; ++i)
+ {
+ protocol = ((Atom *) propData)[i];
+ if (protocol == FWS_STACK_UNDER)
+ {
+ fwsStackUnder = True;
+ #ifdef DEBUG
+ fprintf (stderr, "Using fwsStackUnder.\n");
+ #endif
+ }
+ else
+ if (protocol == FWS_PARK_ICONS)
+ {
+ fwsParkIcons = True;
+ #ifdef DEBUG
+ fprintf (stderr, "Using fwsParkIcons.\n");
+ #endif
+ }
+ else
+ if (protocol == FWS_PASSES_INPUT)
+ {
+ fwsPassesInput = True;
+ #ifdef DEBUG
+ fprintf (stderr, "Using fwsPassesInput.\n");
+ #endif
+ }
+ else
+ if (protocol == FWS_HANDLES_FOCUS)
+ {
+ fwsHandlesFocus = True;
+ #ifdef DEBUG
+ fprintf (stderr, "Using fwsHandlesFocus.\n");
+ #endif
+ }
+ }
+
+ XFree (propData);
+ return True;
+}
+
+/*************************************<->***********************************
+ *
+ * newHandler() -
+ *
+ * Handle X errors (temporarily) to record the occurance of BadWindow
+ * errors without crashing. Used to detect the FWS_COMM_WINDOW root window
+ * property containing an old or obsolete window id.
+ *
+ *************************************<->***********************************/
+
+extern "C" {
+
+static Bool badWindowFound;
+static int (* oldHandler) (Display *, XErrorEvent *);
+
+static int
+newHandler (Display *display, XErrorEvent *xerror)
+{
+ if (xerror->error_code != BadWindow)
+ (*oldHandler)(display, xerror);
+ else
+ badWindowFound = True;
+
+ return 0;
+}
+
+}
+
+/*************************************<->***********************************
+ *
+ * RegisterFwsWindow() -
+ *
+ * Send a client message to the FWS_COMM_WINDOW indicating the existance
+ * of a new FWS client window. Be careful to avoid BadWindow errors on
+ * the XSendEvent in case the FWS_COMM_WINDOW root window property had
+ * old/obsolete junk in it.
+ *
+ *************************************<->***********************************/
+
+Bool
+RegisterFwsWindow (Display *display, Window window)
+{
+ XClientMessageEvent msg;
+
+ msg.type = ClientMessage;
+ msg.window = fwsCommWindow;
+ msg.message_type = FWS_REGISTER_WINDOW;
+ msg.format = 32;
+ msg.data.l[0] = window;
+
+ XSync (display, False);
+ badWindowFound = False;
+ oldHandler = XSetErrorHandler (newHandler);
+
+ XSendEvent (display, fwsCommWindow, False, NoEventMask,
+ (XEvent *) &msg);
+ XSync (display, False);
+
+ XSetErrorHandler (oldHandler);
+ #ifdef DEBUG
+ if (badWindowFound)
+ fprintf (stderr, "No FWS client window to register with.\n");
+ #endif
+
+ return !badWindowFound;
+}
+
+/*************************************<->***********************************
+ *
+ * AddFwsProtocols -
+ *
+ * Add the FWS protocol atoms to the WMProtocols property for the window.
+ *
+ *************************************<->***********************************/
+
+void
+AddFwsProtocols (Display *display, Window window)
+{
+ #define MAX_FWS_PROTOS 10
+
+ Atom fwsProtocols[ MAX_FWS_PROTOS ];
+ int nProtos = 0;
+
+ fwsProtocols[ nProtos++ ] = FWS_CLIENT;
+ fwsProtocols[ nProtos++ ] = FWS_STACK_UNDER;
+ fwsProtocols[ nProtos++ ] = FWS_STATE_CHANGE;
+ fwsProtocols[ nProtos++ ] = FWS_PASS_ALL_INPUT;
+ XChangeProperty (display, window, WM_PROTOCOLS,
+ XA_ATOM, 32, PropModeAppend,
+ (unsigned char *) fwsProtocols, nProtos);
+}
+
diff --git a/vcl/unx/source/window/FWS.hxx b/vcl/unx/source/window/FWS.hxx
new file mode 100644
index 000000000000..b70997ff7c96
--- /dev/null
+++ b/vcl/unx/source/window/FWS.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * $RCSfile: FWS.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _FOREIGN_WINDOW_SYSTEM_HXX
+#define _FOREIGN_WINDOW_SYSTEM_HXX
+
+#include <X11/Xlib.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Initialize our atoms and determine if the current window manager is
+ * providing FWS extension support.
+ */
+
+Bool
+WMSupportsFWS (Display *display, int screen);
+
+/* Send a client message to the FWS_COMM_WINDOW indicating the existance
+ * of a new FWS client window. Be careful to avoid BadWindow errors on
+ * the XSendEvent in case the FWS_COMM_WINDOW root window property had
+ * old/obsolete junk in it.
+ */
+
+Bool
+RegisterFwsWindow (Display *display, Window window);
+
+/* Add the FWS protocol atoms to the WMProtocols property for the window.
+ */
+
+void
+AddFwsProtocols (Display *display, Window window);
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif
+
+#endif _FOREIGN_WINDOW_SYSTEM_HXX
+
diff --git a/vcl/unx/source/window/makefile.mk b/vcl/unx/source/window/makefile.mk
new file mode 100644
index 000000000000..69d4cf6196dd
--- /dev/null
+++ b/vcl/unx/source/window/makefile.mk
@@ -0,0 +1,97 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salwin
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(OS)"=="MACOSX"
+
+dummy:
+ @echo "Nothing to build for Mac OS X"
+
+.ELSE # "$(OS)"=="MACOSX"
+
+.IF "$(remote)"
+SLOFILES= \
+ $(SLO)/FWS.obj $(SLO)/salframe.obj $(SLO)/salobj.obj
+.ENDIF
+
+.ENDIF # "$(OS)"=="MACOSX"
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx
new file mode 100644
index 000000000000..bde3233e1699
--- /dev/null
+++ b/vcl/unx/source/window/salframe.cxx
@@ -0,0 +1,2614 @@
+/*************************************************************************
+ *
+ * $RCSfile: salframe.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALFRAME_CXX
+
+// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <alloca.h>
+
+#include <prex.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+
+#ifndef _FOREIGN_WINDOW_SYSTEM_HXX
+#include "FWS.hxx"
+#endif
+
+#include <postx.h>
+
+#include <salunx.h>
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_KEYCOES_HXX
+#include <keycodes.hxx>
+#endif
+#ifndef _SV_SOICON_HXX
+#include <soicon.hxx>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+#ifndef _SV_DTINT_HXX
+#include <dtint.hxx>
+#endif
+#ifndef _VCL_SM_HXX
+#include <sm.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+
+#include <svapp.hxx>
+
+#ifndef _SAL_I18N_INPUTCONTEXT_HXX
+#include "i18n_ic.hxx"
+#endif
+
+// -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#define SHOWSTATE_UNKNOWN -1
+#define SHOWSTATE_MINIMIZED 0
+#define SHOWSTATE_NORMAL 1
+
+// | KeymapStateMask
+#define CLIENT_EVENTS StructureNotifyMask \
+ | SubstructureNotifyMask \
+ | KeyPressMask \
+ | KeyReleaseMask \
+ | ButtonPressMask \
+ | ButtonReleaseMask \
+ | PointerMotionMask \
+ | EnterWindowMask \
+ | LeaveWindowMask \
+ | FocusChangeMask \
+ | ExposureMask \
+ | VisibilityChangeMask \
+ | PropertyChangeMask \
+ | ColormapChangeMask
+
+// | ButtonPressMask | ButtonRelaseMask
+//#define NC_EVENTS KeyPressMask \
+// | KeyReleaseMask \
+// | PointerMotionMask \
+// | EnterWindowMask \
+// | LeaveWindowMask \
+// | ExposureMask
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#define _GetDrawable() maFrameData.GetDrawable()
+#define _GetDisplay() maFrameData.pDisplay_
+#define _GetXDisplay() maFrameData.GetXDisplay()
+#define _GetColormap() maFrameData.GetColormap()
+#define _GetPaintRegion() maFrameData.GetPaintRegion()
+#define _GetStyle() maFrameData.nStyle_
+#define _IsMapped() maFrameData.bMapped_
+
+// -=-= C++ statics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+static long sal_CallbackDummy( void*, SalFrame*, USHORT, const void* )
+{ return 0; }
+
+// -=-= SalInstance =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+SalFrame *SalInstance::CreateFrame( SalFrame *pParent,
+ ULONG nSalFrameStyle )
+{
+ SalFrame *pFrame = new SalFrame;
+
+ pFrame->maFrameData.mpParent = pParent;
+ if( pParent )
+ pParent->maFrameData.maChildren.Insert( pFrame );
+ pFrame->maFrameData.Init( nSalFrameStyle );
+
+ return pFrame;
+}
+
+SalFrame* SalInstance::CreateChildFrame( SystemParentData* pParentData, ULONG nStyle )
+{
+ SalFrame* pFrame = new SalFrame;
+ pFrame->maFrameData.mpParent = NULL;
+ pFrame->maFrameData.Init( nStyle, pParentData );
+
+ return pFrame;
+}
+
+void SalInstance::DestroyFrame( SalFrame* pFrame )
+{
+ delete pFrame;
+}
+
+// -=-= SalGraphics / SalGraphicsData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalGraphicsData::Init( SalFrame *pFrame )
+{
+ xColormap_ = &pFrame->_GetColormap();
+ hDrawable_ = pFrame->_GetDrawable();
+
+ bWindow_ = TRUE;
+
+ nPenPixel_ = GetPixel( nPenColor_ );
+ nTextPixel_ = GetPixel( nTextColor_ );
+ nBrushPixel_ = GetPixel( nBrushColor_ );
+}
+
+// -=-= SalFrame / SalFrameData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrameData::Init( USHORT nSalFrameStyle, SystemParentData* pParentData )
+{
+ nStyle_ = nSalFrameStyle;
+
+ XWMHints Hints;
+ Hints.flags = 0;
+
+ if( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
+ {
+ hShell_ = pDisplay_->GetShellWidget();
+ hComposite_ = pDisplay_->GetWidget();
+
+ XSelectInput( GetXDisplay(), XtWindow( hShell_ ), CLIENT_EVENTS );
+ XSelectInput( GetXDisplay(), XtWindow( hComposite_ ), CLIENT_EVENTS );
+
+ Hints.flags |= InputHint|IconPixmapHint;
+ Hints.input = True;
+ Hints.icon_pixmap = GetAppIconPixmap( pDisplay_ );
+ Hints.icon_mask = GetAppIconMask( pDisplay_ );
+ if( Hints.icon_mask )
+ Hints.flags |= IconMaskHint;
+ }
+ else if( nSalFrameStyle & SAL_FRAME_STYLE_FLOAT )
+ {
+ Arg aArgs[10];
+ int nArgs = 0;
+
+ SalVisual* pVis = GetDisplay()->GetVisual();
+ XtSetArg( aArgs[nArgs], XtNvisual, pVis->GetVisual() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNdepth, pVis->GetDepth() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNcolormap,
+ GetDisplay()->GetColormap().GetXColormap() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNwidth, 10 ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNheight, 10 ); nArgs++;
+
+ hShell_ = XtAppCreateShell( NULL, NULL,
+ overrideShellWidgetClass,
+ pDisplay_->GetDisplay(),
+ aArgs, nArgs );
+
+ XtSetMappedWhenManaged( hShell_, FALSE );
+ XtRealizeWidget( hShell_ );
+
+ hComposite_ = XtVaCreateManagedWidget(
+ "ShellComposite",
+ SAL_COMPOSITE_WIDGET,
+ hShell_,
+ NULL );
+ XtRealizeWidget( hComposite_ );
+#ifdef DEBUG
+ fprintf( stderr, "created new FLOAT style shell\n" );
+#endif
+ }
+ else if( nSalFrameStyle & SAL_FRAME_STYLE_CHILD && pParentData )
+ {
+ int x_ret, y_ret;
+ unsigned int w, h, bw, d;
+ XLIB_Window aRoot;
+ XLIB_Window aParent;
+
+ XGetGeometry( GetDisplay()->GetDisplay(), pParentData->aWindow,
+ &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d );
+
+ Arg aArgs[10];
+ int nArgs = 0;
+
+ SalVisual* pVis = GetDisplay()->GetVisual();
+ XtSetArg( aArgs[nArgs], XtNvisual, pVis->GetVisual() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNdepth, pVis->GetDepth() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNcolormap,
+ GetDisplay()->GetColormap().GetXColormap() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNwidth, w ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNheight, h ); nArgs++;
+
+ hShell_ = XtAppCreateShell( NULL, NULL,
+ overrideShellWidgetClass,
+ pDisplay_->GetDisplay(),
+ aArgs, nArgs );
+
+ XtSetMappedWhenManaged( hShell_, FALSE );
+ XtRealizeWidget( hShell_ );
+
+ XEvent aEvent;
+ XReparentWindow( GetDisplay()->GetDisplay(), XtWindow( hShell_ ),
+ pParentData->aWindow, 0, 0 );
+ GetDisplay()->GetXLib()->SetIgnoreXErrors( TRUE ); // hack for plugin
+ XSync( GetDisplay()->GetDisplay(), False );
+
+ while( ! XCheckTypedWindowEvent( GetDisplay()->GetDisplay(),
+ XtWindow( hShell_ ),
+ ReparentNotify,
+ &aEvent ) )
+ {
+ usleep(10000);
+ }
+
+ hComposite_ = XtVaCreateManagedWidget(
+ "ShellComposite",
+ SAL_COMPOSITE_WIDGET,
+ hShell_,
+ NULL );
+ XtRealizeWidget( hComposite_ );
+
+ hForeignParent_ = pParentData->aWindow;
+ // get foreign top level window
+ // we need the ConfigureNotifies of this window
+ // to update the positions of this frame's children of
+ // type SAL_FRAME_STYLE_FLOAT
+ aParent = hForeignParent_;
+ hForeignTopLevelWindow_ = hForeignParent_;
+ XLIB_Window* pChildren;
+ unsigned int nChildren;
+ do
+ {
+ XQueryTree( GetDisplay()->GetDisplay(), hForeignTopLevelWindow_,
+ &aRoot, &aParent, &pChildren, &nChildren );
+ XFree( pChildren );
+ if( aParent != aRoot )
+ hForeignTopLevelWindow_ = aParent;
+ } while( aParent != aRoot );
+
+ // check if this is really one of our own frames
+ // do not change the input mask in that case
+ SalFrame* pFrame = GetSalData()->pFirstFrame_;
+ while( pFrame &&
+ hForeignParent_ != pFrame->maFrameData.GetWindow() &&
+ hForeignParent_ != pFrame->maFrameData.GetShellWindow() )
+ pFrame = pFrame->maFrameData.pNextFrame_;
+
+ if( ! pFrame )
+ {
+ XSelectInput( GetDisplay()->GetDisplay(), hForeignParent_, StructureNotifyMask );
+ XSelectInput( GetDisplay()->GetDisplay(), hForeignTopLevelWindow_, StructureNotifyMask );
+ }
+
+ SetPosSize( Rectangle( Point( 0, 0 ), Size( w, h ) ) );
+ }
+ else
+ {
+ SalVisual *pVisual = pDisplay_->GetVisual();
+
+ int w = 500;
+ int h = 400;
+ if( pDisplay_->GetProperties() & PROPERTY_FEATURE_Maximize )
+ {
+ w = pDisplay_->GetScreenSize().Width();
+ h = pDisplay_->GetScreenSize().Height();
+ }
+
+ Arg aArgs[10];
+ int nArgs=0;
+ SalVisual* pVis = GetDisplay()->GetVisual();
+ XtSetArg( aArgs[nArgs], XtNvisual, pVis->GetVisual() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNdepth, pVis->GetDepth() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNcolormap,
+ GetDisplay()->GetColormap().GetXColormap() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNwidth, w ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNheight, h ); nArgs++;
+ if( mpParent )
+ XtSetArg( aArgs[nArgs], XtNtransientFor, mpParent->maFrameData.GetShellWidget() ), nArgs++;
+ if( ! ( nStyle_ & ~SAL_FRAME_STYLE_DEFAULT ) )
+ {
+ XtSetArg( aArgs[nArgs], XtNoverrideRedirect, True ); nArgs++;
+ }
+
+ hShell_ = XtAppCreateShell( "", "VCLSalFrame",
+ mpParent
+ ? transientShellWidgetClass :
+ applicationShellWidgetClass,
+ GetXDisplay(),
+ aArgs, nArgs );
+
+ // X-Window erzeugen
+ XtSetMappedWhenManaged( hShell_, FALSE );
+ XtRealizeWidget( hShell_ );
+
+ hComposite_ = XtVaCreateManagedWidget(
+ "ShellComposite",
+ SAL_COMPOSITE_WIDGET,
+ hShell_,
+ NULL );
+ XtRealizeWidget( hComposite_ );
+
+ XWMHints *pHints = XGetWMHints( GetXDisplay(),
+ pDisplay_->GetWindow() );
+
+ if( pHints
+ && pHints->flags & IconMaskHint
+ && pHints->flags & IconPixmapHint )
+ {
+ Hints.flags |= IconMaskHint|IconPixmapHint;
+ Hints.icon_pixmap = pHints->icon_pixmap;
+ Hints.icon_mask = pHints->icon_mask;
+ XFree( pHints );
+ }
+ else
+ {
+ Hints.flags |= IconPixmapHint;
+ Hints.icon_pixmap = GetAppIconPixmap( pDisplay_ );
+ Hints.icon_mask = GetAppIconMask( pDisplay_ );
+ if( Hints.icon_mask )
+ Hints.flags |= IconMaskHint;
+ }
+
+ Hints.flags |= WindowGroupHint;
+ Hints.window_group = pDisplay_->GetShellWindow();
+
+ }
+
+ if( hShell_ )
+ XSetWindowBackgroundPixmap( pDisplay_->GetDisplay(), XtWindow( hShell_ ), None );
+ if( hComposite_ )
+ XSetWindowBackgroundPixmap( pDisplay_->GetDisplay(), XtWindow( hComposite_ ), None );
+
+ if( ! ( nSalFrameStyle & SAL_FRAME_STYLE_CHILD && pParentData ) )
+ {
+ XSetWMHints( GetXDisplay(), XtWindow( hShell_ ), &Hints );
+
+
+ // WM Protocols && internals
+ Atom a[4];
+ int n = 0;
+
+ a[n++] = pDisplay_->GetICCCM().aWM_DeleteWindow_;
+ a[n++] = pDisplay_->GetICCCM().aWM_SaveYourself_;
+
+ XSetWMProtocols( GetXDisplay(), XtWindow( hShell_ ), a, n );
+ }
+
+ // Pointer
+ pFrame_->SetPointer( POINTER_ARROW );
+
+ // Setup for use of InputMethod
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE
+ && nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE )
+ {
+ mpInputContext = new SalI18N_InputContext( pFrame_ );
+ if ( mpInputContext->UseContext() )
+ {
+ mpInputContext->ExtendEventMask( XtWindow( hShell_ ) );
+ mpInputContext->Unmap();
+ }
+ }
+ else
+ {
+ mpInputContext = NULL;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+inline SalFrameData::SalFrameData( SalFrame *pFrame )
+{
+ SalData* pSalData = GetSalData();
+
+ // insert frame in framelist
+ pNextFrame_ = pSalData->pFirstFrame_;
+ pSalData->pFirstFrame_ = pFrame;
+ pFrame_ = pFrame;
+
+ pProc_ = sal_CallbackDummy;
+ pInst_ = (void*)ILLEGAL_POINTER;
+
+ pDisplay_ = pSalData->GetCurDisp();
+ hShell_ = NULL;
+ hComposite_ = NULL;
+ hForeignParent_ = None;
+ hNoFullscreenShell_ = NULL;
+ hNoFullscreenComposite_ = NULL;
+
+ pGraphics_ = NULL;
+ pFreeGraphics_ = NULL;
+ pPaintRegion_ = NULL;
+
+ hCursor_ = None;
+ nCaptured_ = 0;
+
+ nReleaseTime_ = 0;
+ nKeyCode_ = 0;
+ nKeyState_ = 0;
+ nCompose_ = -1;
+
+ nShowState_ = SHOWSTATE_UNKNOWN;
+ nLeft_ = 0;
+ nTop_ = 0;
+ nRight_ = 0;
+ nBottom_ = 0;
+ nMaxWidth_ = 0;
+ nMaxHeight_ = 0;
+ nWidth_ = 0;
+ nHeight_ = 0;
+ nStyle_ = 0;
+ bAlwaysOnTop_ = FALSE;
+ // #58928# fake to be mapped on startup, because the sclient may be
+ // resized before mapping and the
+ // SetPosSize / call(salevent_resize) / GetClientSize
+ // stuff will not work in that (unmapped) case
+ bViewable_ = TRUE;
+ bMapped_ = FALSE;
+ bDefaultPosition_ = TRUE;
+ nVisibility_ = VisibilityFullyObscured;
+
+ nScreenSaversTimeout_ = 0;
+
+ mpInputContext = NULL;
+}
+
+SalFrame::SalFrame() : maFrameData( this ) {}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+inline SalFrameData::~SalFrameData()
+{
+ if ( mpInputContext != NULL )
+ delete mpInputContext;
+
+ if( pGraphics_ )
+ {
+ stderr0( "SalFrameData::~SalFrameData pGraphics_\n" );
+ pGraphics_->maGraphicsData.DeInit();
+ delete pGraphics_;
+ }
+
+ if( pFreeGraphics_ )
+ {
+ pFreeGraphics_->maGraphicsData.DeInit();
+ delete pFreeGraphics_;
+ }
+
+ if( hShell_ != pDisplay_->GetWidget() )
+ XtDestroyWidget( hShell_ );
+
+ SalData* pSalData = GetSalData();
+
+ if( pFrame_ == pSalData->pFirstFrame_ )
+ pSalData->pFirstFrame_ = GetNextFrame();
+ else
+ {
+ SalFrameData *pTemp = &pSalData->pFirstFrame_->maFrameData;
+ while( pTemp->GetNextFrame() != pFrame_ )
+ pTemp = &pTemp->GetNextFrame()->maFrameData;
+
+ pTemp->pNextFrame_ = GetNextFrame();
+ }
+}
+
+SalFrame::~SalFrame()
+{
+ // aus papis child liste entfernen
+ if( maFrameData.mpParent )
+ maFrameData.mpParent->maFrameData.maChildren.Remove( this );
+ // einige kommen trotzdem immer noch durch
+ XSelectInput( _GetXDisplay(), maFrameData.GetShellWindow(), 0 );
+ XSelectInput( _GetXDisplay(), maFrameData.GetWindow(), 0 );
+
+ ShowFullScreen( FALSE );
+
+ if( _IsMapped() )
+ Show( FALSE );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// irgendwann auf Liste umstellen
+
+const SystemChildData* SalFrame::GetSystemData() const
+{
+ SalFrame *pFrame = const_cast<SalFrame*>(this);
+ pFrame->maFrameData.maSystemChildData.nSize = sizeof( SystemChildData );
+ pFrame->maFrameData.maSystemChildData.pDisplay = _GetXDisplay();
+ pFrame->maFrameData.maSystemChildData.aWindow = pFrame->maFrameData.GetWindow();
+ pFrame->maFrameData.maSystemChildData.pSalFrame = pFrame;
+ pFrame->maFrameData.maSystemChildData.pWidget = pFrame->maFrameData.GetWidget();
+ pFrame->maFrameData.maSystemChildData.pVisual = _GetDisplay()->GetVisual()->GetVisual();
+ pFrame->maFrameData.maSystemChildData.nDepth = _GetDisplay()->GetVisual()->GetDepth();
+ pFrame->maFrameData.maSystemChildData.aColormap = _GetDisplay()->GetColormap().GetXColormap();
+ pFrame->maFrameData.maSystemChildData.pAppContext = _GetDisplay()->GetXLib()->GetAppContext();
+ return &maFrameData.maSystemChildData;
+}
+
+SalGraphics *SalFrameData::GetGraphics()
+{
+ if( pGraphics_ )
+ return NULL;
+
+ if( pFreeGraphics_ )
+ {
+ pGraphics_ = pFreeGraphics_;
+ pFreeGraphics_ = NULL;
+ }
+ else
+ {
+ pGraphics_ = new SalGraphics;
+ pGraphics_->maGraphicsData.Init( pFrame_ );
+ }
+
+ return pGraphics_;
+}
+
+SalGraphics *SalFrame::GetGraphics()
+{ return maFrameData.GetGraphics(); }
+
+void SalFrame::ReleaseGraphics( SalGraphics *pGraphics )
+{
+ if( pGraphics != maFrameData.pGraphics_ )
+ {
+ stderr0( "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" );
+ return;
+ }
+
+ maFrameData.pFreeGraphics_ = pGraphics;
+ maFrameData.pGraphics_ = NULL;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+void SalFrame::Enable( BOOL bEnable )
+{
+ // NYI: enable/disable frame
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+void SalFrame::SetIcon( USHORT nIcon )
+{
+ // NYI: set a specific icon
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+void SalFrame::SetMinClientSize( long nWidth, long nHeight )
+{
+ if( maFrameData.hShell_ )
+ {
+ Arg args[10];
+ int n = 0;
+ XtSetArg( args[n++], XtNminWidth, nWidth );
+ XtSetArg( args[n++], XtNminHeight, nHeight );
+ XtSetValues( maFrameData.hShell_, args, n );
+ }
+}
+
+// Show + Pos (x,y,z) + Size (width,height)
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrame::Show( BOOL bVisible )
+{
+ maFrameData.bMapped_ = bVisible;
+ maFrameData.bViewable_ = bVisible;
+ if( bVisible )
+ {
+ if( maFrameData.nStyle_ & ( SAL_FRAME_STYLE_CHILD | SAL_FRAME_STYLE_FLOAT ) )
+ XtPopup( maFrameData.hShell_, XtGrabNone );
+ else
+ XtMapWidget( maFrameData.hShell_ );
+ // Manch ein WM verschluckt Key Events im Fullscreenmode ...
+ XSelectInput( _GetXDisplay(), maFrameData.GetShellWindow(), CLIENT_EVENTS );
+ XSelectInput( _GetXDisplay(), maFrameData.GetWindow(), CLIENT_EVENTS );
+
+ if( !maFrameData.aPosSize_.IsEmpty()
+ && (maFrameData.nWidth_ != maFrameData.aPosSize_.GetWidth()
+ || maFrameData.nHeight_ != maFrameData.aPosSize_.GetHeight()) )
+ {
+ maFrameData.nWidth_ = maFrameData.aPosSize_.GetWidth();
+ maFrameData.nHeight_ = maFrameData.aPosSize_.GetHeight();
+
+ maFrameData.Call( SALEVENT_RESIZE, NULL );
+ }
+
+ if( !_GetStyle() || maFrameData.hNoFullscreenShell_ )
+ {
+ XSync( _GetXDisplay(), False );
+ XSetInputFocus( _GetXDisplay(), maFrameData.GetShellWindow(), RevertToNone, CurrentTime );
+ }
+
+ XSync( _GetXDisplay(), False );
+ maFrameData.Call( SALEVENT_RESIZE, NULL );
+ }
+ else
+ {
+ if( maFrameData.nStyle_ & ( SAL_FRAME_STYLE_CHILD | SAL_FRAME_STYLE_FLOAT ) )
+ XtPopdown( maFrameData.hShell_ );
+ else
+ XtUnmapWidget( maFrameData.hShell_ );
+
+ if( !_GetStyle() || maFrameData.hNoFullscreenShell_ )
+ {
+ SalFrameData *pTemp = &GetSalData()->pFirstFrame_->maFrameData;
+ while( pTemp )
+ {
+ if( &maFrameData != pTemp
+ && _GetDisplay() == pTemp->pDisplay_
+ && SHOWSTATE_NORMAL == pTemp->nShowState_
+ && pTemp->bMapped_ )
+ {
+ /* #62634# */
+ XWindowAttributes window_attributes;
+ XGetWindowAttributes( _GetXDisplay(),
+ XtWindow( pTemp->hShell_ ), &window_attributes);
+ /* racing condition, we called ::Show(1), but the
+ * window may not be ready (i.e. bMapped_ != map_state) */
+ if ( window_attributes.map_state != IsViewable )
+ {
+ XtMapWidget( pTemp->hShell_ );
+ XSync( _GetXDisplay(), False );
+ }
+
+ /* #69412# double check whether the window is successfully mapped,
+ since fvwm2 prohibits the mapping of the initial frame, depending
+ on its window positioning policy for new windows */
+ XGetWindowAttributes( _GetXDisplay(), XtWindow( pTemp->hShell_ ), &window_attributes);
+ if ( window_attributes.map_state == IsViewable )
+ {
+ XSetInputFocus( _GetXDisplay(), XtWindow( pTemp->hShell_ ) ,
+ RevertToNone, CurrentTime );
+ }
+ break;
+ }
+ pTemp = &pTemp->pNextFrame_->maFrameData;
+ }
+ }
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+beta void SalFrame::ToTop( USHORT nFlags )
+{
+ int i;
+ // if one of our children is in fullscreen mode, ignore the to top
+ // and raise it instead. This will not work for grandchildren
+ // #58714#
+ for( i = 0; i < maFrameData.maChildren.Count(); i++ )
+ {
+ Widget pChild = maFrameData.maChildren.GetObject( i )->
+ maFrameData.hNoFullscreenShell_;
+ if( pChild )
+ {
+ XRaiseWindow( _GetXDisplay(), XtWindow( pChild ) );
+ return;
+ }
+ }
+
+ if( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN )
+ XtMapWidget( maFrameData.hShell_ );
+
+ XRaiseWindow( _GetXDisplay(), maFrameData.GetShellWindow() );
+ for( i=0; i < maFrameData.maChildren.Count(); i++ )
+ maFrameData.maChildren.GetObject( i )->ToTop( nFlags );
+ //XSetInputFocus( _GetXDisplay(), _GetShellWindow(), RevertToNone, CurrentTime );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrame::GetClientSize( long &rWidth, long &rHeight )
+{
+ if( ! maFrameData.bViewable_ && ! maFrameData.hNoFullscreenShell_ )
+ {
+ rWidth = rHeight = 0;
+ return;
+ }
+
+ rWidth = maFrameData.aPosSize_.GetWidth();
+ rHeight = maFrameData.aPosSize_.GetHeight();
+
+ if( !rWidth || !rHeight )
+ {
+ if( SHOWSTATE_UNKNOWN != maFrameData.nShowState_ ) abort();
+
+ XWindowAttributes aAttrib;
+
+ XGetWindowAttributes( _GetXDisplay(), maFrameData.GetShellWindow(), &aAttrib );
+
+ rWidth = aAttrib.width;
+ rHeight = aAttrib.height;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrame::SetClientSize( long nWidth, long nHeight )
+{
+ if( maFrameData.nStyle_ & SAL_FRAME_STYLE_CHILD )
+ return;
+
+ if( maFrameData.nStyle_ & SAL_FRAME_STYLE_FLOAT )
+ {
+ maFrameData.SetPosSize( Rectangle(
+ Point( maFrameData.aPosSize_.Left(), maFrameData.aPosSize_.Top() ),
+ Size( nWidth, nHeight ) ) );
+ return;
+ }
+
+ XLIB_Window aDummy;
+ int nX, nY, nScreenWidth, nScreenHeight;
+
+ nScreenWidth = _GetDisplay()->GetScreenSize().Width();
+ nScreenHeight = _GetDisplay()->GetScreenSize().Height();
+
+ XTranslateCoordinates ( _GetXDisplay(), maFrameData.GetShellWindow(),
+ _GetDisplay()->GetRootWindow(), 0, 0, &nX, &nY,
+ &aDummy );
+
+ if ( maFrameData.bDefaultPosition_ )
+ {
+ // center the application window
+
+ nX = (nScreenWidth - nWidth ) / 2;
+ nY = (nScreenHeight - nHeight) / 2;
+
+ maFrameData.bDefaultPosition_ = False;
+ }
+ else
+ {
+ // once centered, we leave the window where it is with new size
+ // but only if it does not run out of screen
+
+ if ( nX + nWidth > nScreenWidth ) nX = nScreenWidth - nWidth;
+ if ( nY + nHeight > nScreenHeight ) nY = nScreenHeight - nHeight;
+ if ( nX < 0 ) nX = 0;
+ if ( nY < 20 ) nY = 20;// guess size of top window
+ // decoration is 20
+ }
+
+ Size aSize ( nWidth, nHeight );
+ Point aPoint ( nX, nY );
+ maFrameData.SetPosSize( Rectangle ( aPoint, aSize ) );
+}
+
+#if 0
+void SalFrame::SetClientPosSize( const Rectangle& rRect )
+{
+ if( maFrameData.nStyle_ & SAL_FRAME_STYLE_CHILD )
+ return;
+
+ maFrameData.SetPosSize( rRect );
+}
+#endif
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrame::SetAlwaysOnTop( BOOL bOnTop )
+{
+ // #74406# do not raise fullscreenwindow since it may override the
+ // screenlocker
+ // maFrameData.bAlwaysOnTop_ = bOnTop;
+ if( bOnTop )
+ XRaiseWindow( _GetXDisplay(), maFrameData.GetShellWindow() );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrame::SetWindowState( const SalFrameState *pState )
+{
+ int nWidth = pState->mnWidth > 0 ? pState->mnWidth - 1 : 0 ;
+ int nHeight = pState->mnHeight > 0 ? pState->mnHeight - 1 : 0 ;
+
+ Rectangle aPosSize = Rectangle( pState->mnX,
+ pState->mnY,
+ pState->mnX + nWidth,
+ pState->mnY + nHeight );
+
+ maFrameData.SetPosSize( aPosSize );
+
+ if( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ {
+ maFrameData.nShowState_ = SHOWSTATE_NORMAL;
+ maFrameData.Maximize();
+ }
+ if( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
+ {
+ if ( maFrameData.nShowState_ == SHOWSTATE_UNKNOWN )
+ maFrameData.nShowState_ = SHOWSTATE_NORMAL;
+ maFrameData.Minimize();
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+BOOL SalFrame::GetWindowState( SalFrameState* pState )
+{
+ if( SHOWSTATE_MINIMIZED == maFrameData.nShowState_ )
+ pState->mnState = SAL_FRAMESTATE_MINIMIZED;
+ else
+ pState->mnState = 0;
+
+ Rectangle aPosSize;
+ if( !maFrameData.aRestoreMaximize_.IsEmpty() )
+ {
+ aPosSize = maFrameData.aRestoreMaximize_;
+ pState->mnState |= SAL_FRAMESTATE_MAXIMIZED;
+ }
+ else
+ maFrameData.GetPosSize( aPosSize );
+
+ pState->mnX = aPosSize.Left();
+ pState->mnY = aPosSize.Top();
+ pState->mnWidth = aPosSize.GetWidth();
+ pState->mnHeight = aPosSize.GetHeight();
+
+ return TRUE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrameData::GetPosSize( Rectangle &rPosSize )
+{
+ if( aPosSize_.IsEmpty() )
+ {
+ long w = nMaxWidth_
+ ? nMaxWidth_
+ : pDisplay_->GetScreenSize().Width() - nLeft_ - nRight_;
+ long h = nMaxHeight_
+ ? nMaxHeight_
+ : pDisplay_->GetScreenSize().Height() - nTop_ - nBottom_;
+
+ rPosSize = Rectangle( Point( nLeft_, nTop_ ), Size( w, h ) );
+ }
+ else
+ rPosSize = aPosSize_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrameData::SetSize( const Size &rSize )
+{
+ XWindowChanges values;
+ values.width = rSize.Width();
+ values.height = rSize.Height();
+ if (values.width > 0 && values.height > 0)
+ {
+ Arg args[10];
+ int n = 0;
+ XtSetArg(args[n], XtNheight, rSize.Height()); n++;
+ XtSetArg(args[n], XtNwidth, rSize.Width()); n++;
+ XtSetValues( hShell_, args, n );
+
+ if( ! ( nStyle_ & ( SAL_FRAME_STYLE_CHILD | SAL_FRAME_STYLE_FLOAT ) ) )
+ MarkWindowAsGoodPositioned( XtWindow( hShell_ ) );
+
+ aPosSize_.Right() = aPosSize_.Left() + rSize.Width() - 1;
+ aPosSize_.Bottom() = aPosSize_.Top() + rSize.Height() - 1;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrameData::SetPosSize( const Rectangle &rPosSize )
+{
+ XWindowChanges values;
+ values.x = rPosSize.Left();
+ values.y = rPosSize.Top();
+ values.width = rPosSize.GetWidth();
+ values.height = rPosSize.GetHeight();
+
+ if ( !values.width || !values.height )
+ return;
+
+ if( ! ( nStyle_ & ( SAL_FRAME_STYLE_CHILD | SAL_FRAME_STYLE_FLOAT ) ) )
+ {
+ MarkWindowAsGoodPositioned( XtWindow( hShell_ ) );
+
+ if( !(pDisplay_->GetProperties() & PROPERTY_SUPPORT_WM_ClientPos) )
+ {
+ values.x -= nLeft_;
+ values.y -= nTop_;
+ }
+ }
+ if( ( nStyle_ & SAL_FRAME_STYLE_FLOAT ) && mpParent )
+ {
+ XLIB_Window aChild;
+ // coordinates are relative to parent, so translate to root coordinates
+ XTranslateCoordinates( GetDisplay()->GetDisplay(),
+ mpParent->maFrameData.GetWindow(),
+ GetDisplay()->GetRootWindow(),
+ values.x, values.y,
+ &values.x, &values.y,
+ & aChild );
+ }
+
+ Arg args[10];
+ int n = 0;
+ XtSetArg(args[n], XtNheight, values.height); n++;
+ XtSetArg(args[n], XtNwidth, values.width); n++;
+ XtSetArg(args[n], XtNx, values.x); n++;
+ XtSetArg(args[n], XtNy, values.y); n++;
+ XtSetValues( hShell_, args, n );
+
+ if ( aPosSize_ != rPosSize )
+ {
+ aPosSize_ = rPosSize;
+ Call ( SALEVENT_RESIZE, NULL );
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrameData::Minimize()
+{
+ if( SHOWSTATE_UNKNOWN == nShowState_ )
+ {
+ stderr0( "SalFrameData::Minimize SHOWSTATE_UNKNOWN\n" );
+ return;
+ }
+
+ if( hNoFullscreenShell_ )
+ XtUnmapWidget( hNoFullscreenShell_ );
+ if( XIconifyWindow( GetXDisplay(),
+ XtWindow( hShell_ ),
+ pDisplay_->GetScreenNumber() ) )
+ nShowState_ = SHOWSTATE_MINIMIZED;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrameData::Maximize()
+{
+ if( SHOWSTATE_UNKNOWN == nShowState_ )
+ {
+ stderr0( "SalFrameData::Maximize SHOWSTATE_UNKNOWN\n" );
+ return;
+ }
+
+ if( SHOWSTATE_MINIMIZED == nShowState_ )
+ {
+ if( hNoFullscreenShell_ )
+ XtMapWidget( hNoFullscreenShell_ );
+ XtMapWidget( hShell_ );
+ nShowState_ = SHOWSTATE_NORMAL;
+ }
+
+ if( aRestoreMaximize_.IsEmpty() )
+ aRestoreMaximize_ = aPosSize_;
+
+ if( pDisplay_->GetProperties() & PROPERTY_SUPPORT_WM_Screen )
+ {
+ long w = nMaxWidth_
+ ? nMaxWidth_
+ : pDisplay_->GetScreenSize().Width() - nLeft_ - nRight_;
+ long h = nMaxHeight_
+ ? nMaxHeight_
+ : pDisplay_->GetScreenSize().Height() - nTop_ - nBottom_;
+
+ SetPosSize( Rectangle( Point( nLeft_, nTop_), Size( w, h ) ) );
+ }
+ else
+ {
+ Display *pDisplay = GetXDisplay();
+ XLIB_Window hRoot = pDisplay_->GetRootWindow();
+ XLIB_Window *Children, hDummy;
+ unsigned int nChildren, n;
+
+ // simulate WM-Maximize: clip iconbars
+ int nW = pDisplay_->GetScreenSize().Width();
+ int nH = pDisplay_->GetScreenSize().Height();
+
+ XRectangle aRect;
+ XLIB_Region pXRegA = XCreateRegion();
+
+ aRect.x = 0;
+ aRect.y = 0;
+ aRect.width = nW;
+ aRect.height = nH;
+
+ XUnionRectWithRegion( &aRect, pXRegA, pXRegA );
+
+ XQueryTree( pDisplay,
+ hRoot,
+ &hRoot,
+ &hDummy,
+ &Children,
+ &nChildren );
+
+ SalXLib *pXLib = GetSalData()->GetLib();
+ BOOL bOld = pXLib->GetIgnoreXErrors();
+
+ for( n = 0; n < nChildren; n++ )
+ {
+ XWindowAttributes aAttrib;
+
+ pXLib->SetIgnoreXErrors( TRUE ); // reset WasXError
+
+ XGetWindowAttributes( pDisplay, Children[n], &aAttrib );
+
+ aRect.x = aAttrib.x;
+ aRect.y = aAttrib.y;
+ aRect.width = aAttrib.width;
+ aRect.height = aAttrib.height;
+
+ if( !pXLib->WasXError()
+ && aAttrib.map_state == IsViewable
+ && (!aRect.x
+ || !aRect.y
+ || aRect.x + aRect.width == nW
+ || aRect.y + aRect.height == nH)
+ && aRect.width * aRect.height < (nW * nH) / 5 )
+ {
+ XLIB_Region pXRegB = XCreateRegion();
+
+ XUnionRectWithRegion( &aRect, pXRegB, pXRegB );
+ XSubtractRegion( pXRegA, pXRegB, pXRegA );
+
+ XDestroyRegion( pXRegB );
+ }
+ }
+
+ pXLib->SetIgnoreXErrors( bOld );
+
+ XClipBox( pXRegA, &aRect );
+
+ XDestroyRegion( pXRegA );
+
+ if( aRect.width * aRect.height > (nW * nH) / 2 )
+ {
+ Rectangle aPosSize( aRect.x + nLeft_,
+ aRect.y + nTop_,
+ aRect.x + aRect.width - 1 - nRight_,
+ aRect.y + aRect.height - 1 - nBottom_ );
+
+ SetPosSize( aPosSize );
+ }
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrameData::Restore()
+{
+ if( SHOWSTATE_UNKNOWN == nShowState_ )
+ {
+ stderr0( "SalFrameData::Restore SHOWSTATE_UNKNOWN\n" );
+ return;
+ }
+
+ if( SHOWSTATE_MINIMIZED == nShowState_ )
+ {
+ if( hNoFullscreenShell_ )
+ XtMapWidget( hNoFullscreenShell_ );
+ XtMapWidget( hShell_ );
+ nShowState_ = SHOWSTATE_NORMAL;
+ }
+
+ if( !aRestoreMaximize_.IsEmpty() )
+ {
+ SetPosSize( aRestoreMaximize_ );
+ aRestoreMaximize_ = Rectangle();
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrameData::ShowFullScreen( BOOL bFullScreen )
+{
+ if( aRestoreFullScreen_.IsEmpty() == !bFullScreen )
+ return;
+
+ const Size &aScreenSize( pDisplay_->GetScreenSize() );
+
+ long supplied;
+ XSizeHints hints;
+ if( !XGetWMNormalHints( GetXDisplay(), XtWindow( hShell_ ), &hints, &supplied ) )
+ hints.flags = supplied = 0;
+
+ if( bFullScreen )
+ {
+ GetPosSize( aRestoreFullScreen_ );
+
+ SalVisual *pVisual = pDisplay_->GetVisual();
+
+ hNoFullscreenShell_ = hShell_;
+ hNoFullscreenComposite_ = hComposite_;
+
+ XWithdrawWindow( GetXDisplay(), XtWindow( hNoFullscreenShell_ ),
+ GetDisplay()->GetScreenNumber() );
+
+ Arg aArgs[10];
+ int nArgs=0;
+ SalVisual* pVis = GetDisplay()->GetVisual();
+ XtSetArg( aArgs[nArgs], XtNvisual, pVis->GetVisual() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNdepth, pVis->GetDepth() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNcolormap,
+ GetDisplay()->GetColormap().GetXColormap() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNx, 0 ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNy, 0 ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNwidth, aScreenSize.Width() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNheight, aScreenSize.Height() ); nArgs++;
+ XtSetArg( aArgs[nArgs], XtNoverrideRedirect, True ); nArgs++;
+ hShell_ = XtAppCreateShell(
+ "VCLFullScreenShell", "VCLFullScreenFrame",
+ applicationShellWidgetClass,
+ GetXDisplay(),
+ aArgs, nArgs );
+ XtRealizeWidget( hShell_ );
+
+ hComposite_ = XtVaCreateManagedWidget(
+ "ShellComposite",
+ SAL_COMPOSITE_WIDGET,
+ hShell_,
+ NULL );
+ XtRealizeWidget( hComposite_ );
+
+ if( pGraphics_ )
+ pGraphics_->maGraphicsData.SetDrawable( XtWindow( hComposite_ ) );
+
+ delete pFreeGraphics_;
+ pFreeGraphics_ = NULL;
+
+ if( bMapped_ )
+ {
+ pFrame_->Show( TRUE );
+ XSetInputFocus( GetXDisplay(), XtWindow( hShell_ ),
+ RevertToNone, CurrentTime );
+ }
+
+ if ( WMSupportsFWS(GetXDisplay(), pDisplay_->GetRootWindow()) )
+ {
+ AddFwsProtocols( GetXDisplay(), XtWindow(hShell_) );
+ RegisterFwsWindow( GetXDisplay(), XtWindow(hShell_) );
+ }
+
+ aPosSize_ = Rectangle( Point( 0, 0 ), aScreenSize );
+ nWidth_ = aPosSize_.GetWidth();
+ nHeight_ = aPosSize_.GetHeight();
+
+ if ( mpInputContext != NULL )
+ {
+ delete mpInputContext;
+ mpInputContext = new SalI18N_InputContext( pFrame_ );
+ }
+ Call( SALEVENT_RESIZE, NULL );
+ }
+ else
+ {
+ if( pGraphics_ )
+ pGraphics_->maGraphicsData.SetDrawable( XtWindow( hNoFullscreenComposite_ ) );
+
+ delete pFreeGraphics_;
+ pFreeGraphics_ = NULL;
+
+ if ( mpInputContext != NULL )
+ delete mpInputContext;
+
+ XtDestroyWidget( hComposite_ );
+ XtDestroyWidget( hShell_ );
+
+ hComposite_ = hNoFullscreenComposite_;
+ hShell_ = hNoFullscreenShell_;
+
+ hNoFullscreenShell_ = None;
+ hNoFullscreenComposite_ = None;
+
+ if( bMapped_ )
+ pFrame_->Show( TRUE );
+ if ( mpInputContext != NULL )
+ {
+ mpInputContext = new SalI18N_InputContext( pFrame_ );
+ if ( bMapped_ )
+ mpInputContext->SetICFocus();
+ else
+ mpInputContext->Unmap();
+ }
+
+ SetPosSize( aRestoreFullScreen_ );
+ // SetPosSize macht Call( SALEVENT_RESIZE );
+ aRestoreFullScreen_ = Rectangle();
+ nWidth_ = aPosSize_.GetWidth();
+ nHeight_ = aPosSize_.GetHeight();
+ }
+}
+
+void SalFrame::ShowFullScreen( BOOL bFullScreen )
+{ maFrameData.ShowFullScreen( bFullScreen ); }
+
+/* ---------------------------------------------------------------------
+ the xautolock pseudo screen saver needs special treatment since it
+ doesn't cooperate with XxxxScreenSaver settings
+ ------------------------------------------------------------------- */
+
+static Bool
+IsRunningXAutoLock( Display *p_display, XLIB_Window a_window )
+{
+ const char *p_atomname = "XAUTOLOCK_SEMAPHORE_PID";
+ Atom a_pidatom;
+
+ // xautolock interns this atom
+ a_pidatom = XInternAtom( p_display, p_atomname, True );
+ if ( a_pidatom == None )
+ return False;
+
+ Atom a_type;
+ int n_format;
+ unsigned long n_items;
+ unsigned long n_bytes_after;
+ pid_t *p_pid;
+ pid_t n_pid;
+ // get pid of running xautolock
+ XGetWindowProperty (p_display, a_window, a_pidatom, 0L, 2L, False,
+ AnyPropertyType, &a_type, &n_format, &n_items, &n_bytes_after,
+ (unsigned char**) &p_pid );
+ n_pid = *p_pid;
+ XFree( p_pid );
+
+ if ( a_type == XA_INTEGER )
+ {
+ // check if xautolock pid points to a running process
+ if ( kill(n_pid, 0) == -1 )
+ return False;
+ else
+ return True;
+ }
+
+ return False;
+}
+
+/* definitions from xautolock.c (pl15) */
+#define XAUTOLOCK_DISABLE 1
+#define XAUTOLOCK_ENABLE 2
+
+static Bool
+MessageToXAutoLock( Display *p_display, int n_message )
+{
+ const char *p_atomname = "XAUTOLOCK_MESSAGE" ;
+ Atom a_messageatom;
+ XLIB_Window a_rootwindow;
+
+ a_rootwindow = RootWindowOfScreen( ScreenOfDisplay(p_display, 0) );
+ if ( ! IsRunningXAutoLock(p_display, a_rootwindow) )
+ {
+ // remove any pending messages
+ a_messageatom = XInternAtom( p_display, p_atomname, True );
+ if ( a_messageatom != None )
+ XDeleteProperty( p_display, a_rootwindow, a_messageatom );
+ return False;
+ }
+
+ a_messageatom = XInternAtom( p_display, p_atomname, False );
+ XChangeProperty (p_display, a_rootwindow, a_messageatom, XA_INTEGER,
+ 8, PropModeReplace, (unsigned char*)&n_message, sizeof(n_message) );
+
+ return True;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrame::StartPresentation( BOOL bStart )
+{
+ if ( bStart )
+ MessageToXAutoLock( _GetXDisplay(), XAUTOLOCK_DISABLE );
+ else
+ MessageToXAutoLock( _GetXDisplay(), XAUTOLOCK_ENABLE );
+
+ if( bStart || maFrameData.nScreenSaversTimeout_ )
+ {
+ int timeout, interval, prefer_blanking, allow_exposures;
+ XGetScreenSaver( _GetXDisplay(),
+ &timeout,
+ &interval,
+ &prefer_blanking,
+ &allow_exposures );
+ if( !bStart )
+ {
+ XSetScreenSaver( _GetXDisplay(),
+ maFrameData.nScreenSaversTimeout_,
+ interval,
+ prefer_blanking,
+ allow_exposures );
+ maFrameData.nScreenSaversTimeout_ = 0;
+ }
+ else if( timeout )
+ {
+ maFrameData.nScreenSaversTimeout_ = timeout;
+ XResetScreenSaver( _GetXDisplay() );
+ XSetScreenSaver( _GetXDisplay(),
+ 0,
+ interval,
+ prefer_blanking,
+ allow_exposures );
+ }
+ }
+}
+
+// Pointer
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+inline void SalFrameData::SetPointer( PointerStyle ePointerStyle )
+{
+ hCursor_ = pDisplay_->GetPointer( ePointerStyle );
+ XDefineCursor( GetXDisplay(), XtWindow( hComposite_ ), hCursor_ );
+
+ if( IsCaptured() )
+ XChangeActivePointerGrab( GetXDisplay(),
+ PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
+ hCursor_,
+ CurrentTime );
+}
+
+void SalFrame::SetPointer( PointerStyle ePointerStyle )
+{ maFrameData.SetPointer( ePointerStyle ); }
+
+void SalFrame::CaptureMouse( BOOL bCapture )
+{ maFrameData.CaptureMouse( bCapture ); }
+
+void SalFrame::SetPointerPos( long nX, long nY )
+{ XWarpPointer( _GetXDisplay(), None, maFrameData.GetShellWindow(), 0, 0, 0, 0, nX, nY ); }
+
+// PostEvent
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+BOOL SalFrame::PostEvent( void *pData )
+{
+ _GetDisplay()->SendEvent( _GetDisplay()->GetICCCM().aUserEvent_,
+ pData,
+ maFrameData.GetWindow() );
+ return TRUE;
+}
+
+// Title
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrame::SetTitle( const XubString& rTitle )
+{
+ ByteString aByteTitle( rTitle, gsl_getSystemTextEncoding() );
+
+ char* pTitle = (char*)aByteTitle.GetBuffer();
+ XTextProperty aTitle;
+
+ if( !XStringListToTextProperty( &pTitle, 1, &aTitle ) )
+ {
+ fprintf( stderr, "SalFrame::SetTitle !XStringListToTextProperty(%s)\n",
+ pTitle );
+ abort();
+ }
+
+ XSetWMName ( _GetXDisplay(), maFrameData.GetShellWindow(), &aTitle );
+ XSetWMIconName( _GetXDisplay(), maFrameData.GetShellWindow(), &aTitle );
+
+ XFree( aTitle.value );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Flush()
+{
+ XFlush( _GetDisplay()->GetDisplay() );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Sync()
+{
+ XSync( _GetDisplay()->GetDisplay(), False );
+}
+
+// Keyboard
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetInputContext( SalInputContext* pContext )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::UpdateExtTextInputArea()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::EndExtTextInput( USHORT nFlags )
+{
+ maFrameData.mpInputContext->EndExtTextInput( nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalFrame::GetKeyName( USHORT nKeyCode )
+{
+ return _GetDisplay()->GetKeyName( nKeyCode );
+}
+
+XubString SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode )
+{
+ return GetKeyName( nKeyCode );
+}
+
+// Settings
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+inline Color getColorFromLong( long nColor )
+{
+ return Color( (nColor & 0xff), (nColor & 0xff00)>>8, (nColor & 0xff0000)>>16);
+}
+
+void SalFrame::UpdateSettings( AllSettings& rSettings )
+{
+
+ static SystemLookInfo aInfo;
+ static BOOL bHaveInfo = FALSE;
+ static BOOL bInit = FALSE;
+
+ if( ! bInit )
+ {
+ bInit = TRUE;
+ DtIntegrator* pIntegrator = DtIntegrator::CreateDtIntegrator( this );
+ if( pIntegrator )
+ bHaveInfo = pIntegrator->GetSystemLook( aInfo );
+ }
+
+ if( bHaveInfo )
+ {
+ StyleSettings aStyleSettings = rSettings.GetStyleSettings();
+ if( aInfo.windowActiveStart.GetColor() != COL_TRANSPARENT )
+ {
+ aStyleSettings.SetActiveColor( aInfo.windowActiveStart );
+ if( aInfo.windowActiveEnd.GetColor() != COL_TRANSPARENT )
+ aStyleSettings.SetActiveColor2( aInfo.windowActiveEnd );
+ }
+ if( aInfo.windowInactiveStart.GetColor() != COL_TRANSPARENT )
+ {
+ aStyleSettings.SetDeactiveColor( aInfo.windowInactiveStart );
+ if( aInfo.windowInactiveEnd.GetColor() != COL_TRANSPARENT )
+ aStyleSettings.SetDeactiveColor2( aInfo.windowInactiveEnd );
+ }
+ if( aInfo.activeBorder.GetColor() != COL_TRANSPARENT )
+ aStyleSettings.SetActiveBorderColor( aInfo.activeBorder );
+ if( aInfo.inactiveBorder.GetColor() != COL_TRANSPARENT )
+ aStyleSettings.SetDeactiveBorderColor( aInfo.inactiveBorder );
+ if( aInfo.activeForeground.GetColor() != COL_TRANSPARENT )
+ aStyleSettings.SetActiveTextColor( aInfo.activeForeground );
+ if( aInfo.inactiveForeground.GetColor() != COL_TRANSPARENT )
+ aStyleSettings.SetDeactiveTextColor( aInfo.inactiveForeground );
+ if( aInfo.selectForeground.GetColor() != COL_TRANSPARENT )
+ aStyleSettings.SetHighlightTextColor( aInfo.selectForeground );
+ if( aInfo.selectBackground.GetColor() != COL_TRANSPARENT )
+ aStyleSettings.SetHighlightColor( aInfo.selectBackground );
+ if( aInfo.foreground.GetColor() != COL_TRANSPARENT )
+ {
+ aStyleSettings.SetDialogTextColor( aInfo.foreground );
+ aStyleSettings.SetMenuTextColor( aInfo.foreground );
+ aStyleSettings.SetButtonTextColor( aInfo.foreground );
+ aStyleSettings.SetRadioCheckTextColor( aInfo.foreground );
+ aStyleSettings.SetGroupTextColor( aInfo.foreground );
+ aStyleSettings.SetLabelTextColor( aInfo.foreground );
+ aStyleSettings.SetInfoTextColor( aInfo.foreground );
+ }
+ if( aInfo.background.GetColor() != COL_TRANSPARENT )
+ {
+ aStyleSettings.Set3DColors( aInfo.background );
+ aStyleSettings.SetFaceColor( aInfo.background );
+ aStyleSettings.SetDialogColor( aInfo.background );
+ aStyleSettings.SetMenuColor( aInfo.background );
+ if ( aStyleSettings.GetFaceColor() == COL_LIGHTGRAY )
+ aStyleSettings.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) );
+ else
+ {
+ // calculate Checked color
+ Color aColor2 = aStyleSettings.GetLightColor();
+ BYTE nRed = (BYTE)(((USHORT)aInfo.background.GetRed() + (USHORT)aColor2.GetRed())/2);
+ BYTE nGreen = (BYTE)(((USHORT)aInfo.background.GetGreen() + (USHORT)aColor2.GetGreen())/2);
+ BYTE nBlue = (BYTE)(((USHORT)aInfo.background.GetBlue() + (USHORT)aColor2.GetBlue())/2);
+ aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) );
+ }
+ }
+
+ if( aInfo.windowFont.Len() )
+ {
+ Font aWindowFont = aStyleSettings.GetTitleFont();
+ aWindowFont.SetName( aInfo.windowFont );
+ aStyleSettings.SetTitleFont( aWindowFont );
+ }
+
+ rSettings.SetStyleSettings( aStyleSettings );
+ }
+}
+
+// Sound
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrame::Beep( SoundType eSoundType ) // not fully suported
+{ _GetDisplay()->Beep(); }
+
+// Callback
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void SalFrame::SetCallback( void* pInst, SALFRAMEPROC pProc )
+{
+ maFrameData.pInst_ = pInst;
+ maFrameData.pProc_ = pProc ? pProc : sal_CallbackDummy;
+}
+
+// Event Handling
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+static USHORT sal_GetCode( int state )
+{
+ USHORT nCode = 0;
+
+ if( state & Button1Mask )
+ nCode |= MOUSE_LEFT;
+ if( state & Button2Mask )
+ nCode |= MOUSE_MIDDLE;
+ if( state & Button3Mask )
+ nCode |= MOUSE_RIGHT;
+
+ if( state & ShiftMask )
+ nCode |= KEY_SHIFT;
+ if( state & ControlMask )
+ nCode |= KEY_MOD1;
+ if( state & Mod1Mask )
+ nCode |= KEY_MOD2;
+
+ return nCode;
+}
+
+long SalFrameData::HandleMouseEvent( XEvent *pEvent )
+{
+ SalMouseEvent aMouseEvt;
+ USHORT nEvent;
+ static ULONG nLines = 0;
+
+ // Solaris X86: clicking the right button on a two-button mouse
+ // generates a button2 event not a button3 event
+ if (pDisplay_->GetProperties() & PROPERTY_SUPPORT_3ButtonMouse )
+ {
+ switch (pEvent->type)
+ {
+ case EnterNotify:
+ case LeaveNotify:
+ if ( pEvent->xcrossing.state & Button2Mask )
+ {
+ pEvent->xcrossing.state &= ~Button2Mask;
+ pEvent->xcrossing.state |= Button3Mask;
+ }
+ break;
+
+ case MotionNotify:
+ if ( pEvent->xmotion.state & Button2Mask )
+ {
+ pEvent->xmotion.state &= ~Button2Mask;
+ pEvent->xmotion.state |= Button3Mask;
+ }
+ break;
+
+ default:
+ if ( Button2 == pEvent->xbutton.button )
+ {
+ pEvent->xbutton.state &= ~Button2Mask;
+ pEvent->xbutton.state |= Button3Mask;
+ pEvent->xbutton.button = Button3;
+ }
+ break;
+ }
+ }
+
+
+ if( LeaveNotify == pEvent->type || EnterNotify == pEvent->type )
+ {
+ aMouseEvt.mnX = pEvent->xcrossing.x;
+ aMouseEvt.mnY = pEvent->xcrossing.y;
+ aMouseEvt.mnTime = pEvent->xcrossing.time;
+ aMouseEvt.mnCode = sal_GetCode( pEvent->xcrossing.state );
+
+ aMouseEvt.mnButton = 0;
+
+ nEvent = LeaveNotify == pEvent->type
+ ? SALEVENT_MOUSELEAVE
+ : SALEVENT_MOUSEMOVE;
+ }
+ else if( pEvent->type == MotionNotify )
+ {
+ aMouseEvt.mnX = pEvent->xmotion.x;
+ aMouseEvt.mnY = pEvent->xmotion.y;
+ aMouseEvt.mnTime = pEvent->xmotion.time;
+ aMouseEvt.mnCode = sal_GetCode( pEvent->xmotion.state );
+
+ aMouseEvt.mnButton = 0;
+
+ nEvent = SALEVENT_MOUSEMOVE;
+ }
+ else
+ {
+ // get input focus on SAL_FRAME_STYLE_CHILD windows
+ // because the focus handling in this case (running as plugin)
+ // is "a little tricky"
+ if( nStyle_ & SAL_FRAME_STYLE_CHILD )
+ XSetInputFocus( GetDisplay()->GetDisplay(), GetWindow(), RevertToParent, CurrentTime );
+ if( pEvent->xbutton.button == Button1 ||
+ pEvent->xbutton.button == Button2 ||
+ pEvent->xbutton.button == Button3 )
+ {
+ aMouseEvt.mnX = pEvent->xbutton.x;
+ aMouseEvt.mnY = pEvent->xbutton.y;
+ aMouseEvt.mnTime = pEvent->xbutton.time;
+ aMouseEvt.mnCode = sal_GetCode( pEvent->xbutton.state );
+
+ if( Button1 == pEvent->xbutton.button )
+ aMouseEvt.mnButton = MOUSE_LEFT;
+ else if( Button2 == pEvent->xbutton.button )
+ aMouseEvt.mnButton = MOUSE_MIDDLE;
+ else if( Button3 == pEvent->xbutton.button )
+ aMouseEvt.mnButton = MOUSE_RIGHT;
+
+ nEvent = ButtonPress == pEvent->type
+ ? SALEVENT_MOUSEBUTTONDOWN
+ : SALEVENT_MOUSEBUTTONUP;
+ }
+ else if( pEvent->xbutton.button == Button4 ||
+ pEvent->xbutton.button == Button5 )
+ {
+ if( ! nLines )
+ {
+ char* pEnv = getenv( "SAL_WHEELLINES" );
+ nLines = pEnv ? atoi( pEnv ) : 3;
+ if( nLines > 10 )
+ nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
+ }
+
+ SalWheelMouseEvent aWheelEvt;
+ aWheelEvt.mnTime = pEvent->xbutton.time;
+ aWheelEvt.mnX = pEvent->xbutton.x;
+ aWheelEvt.mnY = pEvent->xbutton.y;
+ aWheelEvt.mnDelta =
+ pEvent->xbutton.button == Button4 ? 120 : -120;
+ aWheelEvt.mnNotchDelta =
+ pEvent->xbutton.button == Button4 ? 1 : -1;
+ aWheelEvt.mnScrollLines = nLines;
+ aWheelEvt.mnCode = sal_GetCode( pEvent->xbutton.state );
+ aWheelEvt.mbHorz = FALSE;
+
+ nEvent = SALEVENT_WHEELMOUSE;
+
+ return Call( nEvent, &aWheelEvt );
+ }
+ }
+
+ if( nEvent == SALEVENT_MOUSELEAVE
+ || ( aMouseEvt.mnX < nWidth_ && aMouseEvt.mnX > -1 &&
+ aMouseEvt.mnY < nHeight_ && aMouseEvt.mnY > -1 )
+ || pDisplay_->MouseCaptured( this ) )
+ return Call( nEvent, &aMouseEvt );
+
+#ifdef DBG_UTIL
+ fprintf( stderr, "SalFrameData::HandleMouseEvent %d size=%d*%d event=%d.%d\n",
+ pEvent->type, nWidth_, nHeight_, aMouseEvt.mnX, aMouseEvt.mnY );
+#endif
+ return 0;
+}
+
+
+// F10 means either KEY_F10 or KEY_MENU, which has to be decided
+// in the independent part.
+struct KeyAlternate
+{
+ USHORT nKeyCode;
+ sal_Unicode nCharCode;
+ KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {}
+ KeyAlternate( USHORT nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {}
+};
+
+inline KeyAlternate
+GetAlternateKeyCode( const USHORT nKeyCode )
+{
+ KeyAlternate aAlternate;
+
+ switch( nKeyCode )
+ {
+ case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break;
+ case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break;
+ }
+
+ return aAlternate;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+long SalFrameData::HandleKeyEvent( XKeyEvent *pEvent )
+{
+ int nLen = 16;
+ unsigned char *pPrintable = (unsigned char*)alloca( nLen );
+ KeySym nKeySym;
+
+ // if we haven't got an input context yet then it's time to build it
+ if ( mpInputContext == NULL )
+ {
+ mpInputContext = new SalI18N_InputContext( pFrame_ );
+ if ( mpInputContext->UseContext() )
+ mpInputContext->ExtendEventMask( XtWindow( hShell_ ) );
+ }
+ // singlebyte code composed by input method, the new default
+ if ( mpInputContext->UseContext() )
+ {
+ Status nStatus;
+ nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen,
+ &nStatus, mpInputContext->GetContext() );
+ if ( nStatus == XBufferOverflow )
+ {
+ nLen += 1;
+ pPrintable = (unsigned char*)alloca( nLen );
+ nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen,
+ &nStatus, mpInputContext->GetContext() );
+ }
+ }
+ else
+ {
+ // fallback, this should never ever be called
+ Status nStatus = 0;
+ nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen, &nStatus );
+ if( !nLen )
+ pPrintable[0] = 0;
+ }
+
+ USHORT nModCode = 0;
+ if( pEvent->state & ShiftMask )
+ nModCode |= KEY_SHIFT;
+ if( pEvent->state & ControlMask )
+ nModCode |= KEY_MOD1;
+ if( pEvent->state & Mod1Mask )
+ {
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+ }
+
+ if( nKeySym == XK_Shift_L || nKeySym == XK_Shift_R
+ || nKeySym == XK_Control_L || nKeySym == XK_Control_R
+ || nKeySym == XK_Alt_L || nKeySym == XK_Alt_R
+ || nKeySym == XK_Meta_L || nKeySym == XK_Meta_R )
+ {
+ SalKeyModEvent aModEvt;
+
+ // pressing just the ctrl key leads to a keysym of XK_Control but
+ // the event state does not contain ControlMask. In the release
+ // event its the other way round: it does contain the Control mask.
+ // The modifier mode therefor has to be adapted manually.
+ if (pEvent->type == KeyRelease)
+ {
+ if ( (nKeySym == XK_Control_L) || (nKeySym == XK_Control_R) )
+ nModCode &= ~KEY_MOD1;
+ if ( (nKeySym == XK_Shift_L) || (nKeySym == XK_Shift_R) )
+ nModCode &= ~KEY_SHIFT;
+ if ( (nKeySym == XK_Alt_L) || (nKeySym == XK_Alt_R) )
+ nModCode &= ~KEY_MOD2;
+ }
+ else
+ {
+ if ( (nKeySym == XK_Control_L) || (nKeySym == XK_Control_R) )
+ nModCode |= KEY_MOD1;
+ if ( (nKeySym == XK_Shift_L) || (nKeySym == XK_Shift_R) )
+ nModCode |= KEY_SHIFT;
+ if ( (nKeySym == XK_Alt_L) || (nKeySym == XK_Alt_R) )
+ nModCode |= KEY_MOD2;
+ }
+
+ aModEvt.mnCode = nModCode;
+ aModEvt.mnTime = pEvent->time;
+
+ return Call( SALEVENT_KEYMODCHANGE, &aModEvt );
+ }
+
+ SalKeyEvent aKeyEvt;
+ USHORT nKeyCode;
+
+ nKeyCode = pDisplay_->GetKeyCode( nKeySym, (char*)pPrintable );
+ if( !nKeyCode && !pPrintable[0] )
+ return 0;
+
+ rtl_TextEncoding nEncoding = gsl_getSystemTextEncoding();
+ sal_Unicode *pBuffer;
+ sal_Size nSize;
+ if ( nEncoding != RTL_TEXTENCODING_UNICODE )
+ {
+ // create text converter
+ rtl_TextToUnicodeConverter aConverter =
+ rtl_createTextToUnicodeConverter( nEncoding );
+ rtl_TextToUnicodeContext aContext =
+ rtl_createTextToUnicodeContext( aConverter );
+
+ sal_Size nBufferSize = nLen * 2;
+ sal_uInt32 nConversionInfo;
+ sal_Size nConvertedChars;
+
+ pBuffer = (sal_Unicode*) alloca( nBufferSize + 1);
+
+ // convert to single byte text stream
+ nSize = rtl_convertTextToUnicode(
+ aConverter, aContext,
+ (char*)pPrintable, nLen,
+ pBuffer, nBufferSize,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE,
+ &nConversionInfo, &nConvertedChars );
+
+ // destroy converter
+ rtl_destroyTextToUnicodeContext( aConverter, aContext );
+ rtl_destroyTextToUnicodeConverter( aConverter );
+ }
+ else
+ {
+ pBuffer = (sal_Unicode*)pPrintable;
+ nSize = nLen;
+ }
+
+ // XXX it shouldn't be possible to create a keyrelease event with
+ // more than a single character in the event, but check it anyway
+ // as well it shouldn't be possible to generate more than a single
+ // char without an input method
+ if ( nSize > 1
+ && mpInputContext->UseContext()
+ && KeyRelease != pEvent->type )
+ {
+ mpInputContext->CommitStringCallback( pBuffer, nSize );
+ }
+ else
+ {
+ aKeyEvt.mnCode = nKeyCode | nModCode;
+ aKeyEvt.mnRepeat = 0;
+ aKeyEvt.mnTime = pEvent->time;
+ aKeyEvt.mnCharCode = pBuffer[ 0 ];
+
+ if( KeyRelease == pEvent->type )
+ {
+ Call( SALEVENT_KEYUP, &aKeyEvt );
+ }
+ else
+ {
+ if ( ! Call(SALEVENT_KEYINPUT, &aKeyEvt) )
+ {
+ // independent layer doesnt want to handle key-event, so check
+ // whether the keycode may have an alternate meaning
+ KeyAlternate aAlternate = GetAlternateKeyCode( nKeyCode );
+ if ( aAlternate.nKeyCode != 0 )
+ {
+ aKeyEvt.mnCode = aAlternate.nKeyCode | nModCode;
+ if( aAlternate.nCharCode )
+ aKeyEvt.mnCharCode = aAlternate.nCharCode;
+ Call(SALEVENT_KEYINPUT, &aKeyEvt);
+ }
+ }
+ }
+ }
+
+ return True;
+}
+
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+long SalFrameData::HandleFocusEvent( XFocusChangeEvent *pEvent )
+{
+ /* #55691# ignore focusout resulting from keyboard grabs
+ * we do not grab it and are not interested when
+ * someone else does CDE e.g. does a XGrabKey on arrow keys
+ * #73179# handle focus events with mode NotifyWhileGrabbed
+ * because with CDE alt-tab focus changing we do not get
+ * normal focus events
+ * #71791# cast focus event to the input context, otherwise the
+ * status window does not follow the application frame
+ */
+ if ( mpInputContext != NULL )
+ {
+ if( FocusIn == pEvent->type )
+ mpInputContext->SetICFocus();
+ else
+ mpInputContext->UnsetICFocus();
+ }
+
+ if ( pEvent->mode == NotifyNormal || pEvent->mode == NotifyWhileGrabbed )
+ {
+ if( FocusIn == pEvent->type )
+ {
+ return Call( SALEVENT_GETFOCUS, 0 );
+ }
+ else
+ {
+ return Call( SALEVENT_LOSEFOCUS, 0 );
+ }
+ }
+
+ return 0;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+class SalPeekExpose
+{
+ XEvent aEvent_;
+ XEvent *pEvent_;
+ USHORT nEvent_;
+
+public:
+ inline Bool Callback()
+ {
+ if( aEvent_.type != pEvent_->type
+ || aEvent_.xany.window != pEvent_->xany.window )
+ return !--nEvent_;
+ pEvent_->xexpose.count++;
+ return True;
+ }
+ inline SalPeekExpose( XEvent *p );
+};
+
+extern "C" Bool
+sal_PeekExpose( Display*, XEvent*, char *p )
+{
+ return ((SalPeekExpose*)p)->Callback();
+}
+
+inline SalPeekExpose::SalPeekExpose( XEvent *p ) : pEvent_( p )
+{
+#ifdef DBG_UTIL
+ memset( &aEvent_, 0, sizeof( aEvent_ ) );
+#endif
+ nEvent_ = QLength( p->xany.display );
+ XPeekIfEvent( p->xany.display, &aEvent_, sal_PeekExpose, (char*)this );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+long SalFrameData::HandleExposeEvent( XEvent *pEvent )
+{
+ XRectangle aRect;
+ USHORT nCount;
+
+ if( pEvent->type == Expose )
+ {
+ aRect.x = pEvent->xexpose.x;
+ aRect.y = pEvent->xexpose.y;
+ aRect.width = pEvent->xexpose.width;
+ aRect.height = pEvent->xexpose.height;
+ nCount = pEvent->xexpose.count;
+ }
+ else if( pEvent->type == GraphicsExpose )
+ {
+ aRect.x = pEvent->xgraphicsexpose.x;
+ aRect.y = pEvent->xgraphicsexpose.y;
+ aRect.width = pEvent->xgraphicsexpose.width;
+ aRect.height = pEvent->xgraphicsexpose.height;
+ nCount = pEvent->xgraphicsexpose.count;
+ }
+
+ if( hNoFullscreenShell_ != None )
+ // we are in fullscreen mode -> override redirect
+ // focus is probably lost, so reget it
+ XSetInputFocus( GetXDisplay(), XtWindow( hShell_ ), RevertToNone, CurrentTime );
+
+ if( !IsWaitingForExpose() )
+ {
+ // complete painting
+ if( !nCount
+ && !aRect.x
+ && !aRect.y
+ && aRect.width == nWidth_
+ && aRect.height == nHeight_ )
+ {
+ SalPaintEvent aPEvt;
+
+ aPEvt.mnBoundX = 0;
+ aPEvt.mnBoundY = 0;
+ aPEvt.mnBoundWidth = nWidth_;
+ aPEvt.mnBoundHeight = nHeight_;
+
+ Call( SALEVENT_PAINT, &aPEvt );
+
+ return 1;
+ }
+
+ pPaintRegion_ = XCreateRegion();
+ }
+
+ XUnionRectWithRegion( &aRect, pPaintRegion_, pPaintRegion_ );
+
+ if( nCount ) // wait for last expose rectangle
+ return 1;
+
+ if( QLength( pEvent->xany.display ) )
+ {
+ SalPeekExpose Peek( pEvent );
+
+ if( pEvent->xexpose.count )
+ {
+ stderr1( "SalFrameData::HandleExposeEvent %s\n",
+ ServerVendor(GetXDisplay()) );
+ return 1;
+ }
+ }
+
+ SalPaintEvent aPEvt;
+
+ XClipBox( pPaintRegion_, &aRect );
+
+ aPEvt.mnBoundX = aRect.x;
+ aPEvt.mnBoundY = aRect.y;
+ aPEvt.mnBoundWidth = aRect.width;
+ aPEvt.mnBoundHeight = aRect.height;
+
+ Call( SALEVENT_PAINT, &aPEvt );
+
+ XDestroyRegion( pPaintRegion_ );
+ pPaintRegion_ = NULL;
+
+ return 1;
+}
+
+void SalFrameData::RepositionFloatChildren()
+{
+ // move SAL_FRAME_STYLE_FLOAT children to new position
+ for( int nChild = 0; nChild < maChildren.Count(); nChild++ )
+ {
+ SalFrameData* pData = &maChildren.GetObject( nChild )->maFrameData;
+ if( pData->nStyle_ & SAL_FRAME_STYLE_FLOAT )
+ {
+#ifdef DEBUG
+ fprintf( stderr, "moving FLOAT child\n" );
+#endif
+ pData->SetPosSize( pData->aPosSize_ );
+ }
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+long SalFrameData::HandleSizeEvent( XConfigureEvent *pEvent )
+{
+ if ( pEvent->window != XtWindow( hShell_ )
+ && pEvent->window != XtWindow( hComposite_ )
+ && pEvent->window != hForeignParent_
+ && pEvent->window != hForeignTopLevelWindow_ )
+ {
+ // could be as well a sys-child window (aka SalObject)
+ return 1;
+ }
+
+ // ignore for now
+ if( nStyle_ & SAL_FRAME_STYLE_FLOAT )
+ return 1;
+
+ if( pEvent->window == hForeignTopLevelWindow_ )
+ {
+ // just update the children's positions
+ RepositionFloatChildren();
+ return 1;
+ }
+
+ if( pEvent->window == hForeignParent_ )
+ {
+ Arg args[10];
+ int n = 0;
+ XtSetArg(args[n], XtNheight, pEvent->height); n++;
+ XtSetArg(args[n], XtNwidth, pEvent->width); n++;
+ XtSetValues( hShell_, args, n );
+ }
+ if( SHOWSTATE_UNKNOWN == nShowState_ )
+ {
+ nShowState_ = SHOWSTATE_NORMAL;
+
+ XSizeHints hints;
+ long supplied;
+ if( XGetWMNormalHints( pEvent->display,
+ pEvent->window,
+ &hints,
+ &supplied ) )
+ {
+ if( hints.flags & PMaxSize ) // supplied
+ {
+ nMaxWidth_ = hints.max_width;
+ nMaxHeight_ = hints.max_height;
+ DBG_ASSERT( nMaxWidth_ && nMaxHeight_, "!MaxWidth^!MaxHeight" )
+ }
+ }
+ }
+
+ if( !pEvent->send_event )
+ {
+ XLIB_Window hDummy;
+ XTranslateCoordinates( GetXDisplay(),
+ XtWindow( hShell_ ),
+ pDisplay_->GetRootWindow(),
+ 0, 0,
+ &pEvent->x, &pEvent->y,
+ &hDummy );
+ }
+
+ if( nMaxWidth_ || nMaxHeight_ )
+ {
+ if( nMaxWidth_ != pEvent->width || nMaxHeight_ != pEvent->height )
+ aRestoreMaximize_ = Rectangle();
+ else if( aRestoreMaximize_.IsEmpty() )
+ {
+ stderr0( "SalFrameData::HandleSizeEvent zoomed\n" );
+ GetPosSize( aRestoreMaximize_ );
+ }
+ }
+ else
+ if( pEvent->x != nLeft_ || pEvent->y != nTop_ )
+ aRestoreMaximize_ = Rectangle();
+ else
+ {
+ Size aSize( pEvent->width + nLeft_ + nRight_,
+ pEvent->height + nTop_ + nBottom_ );
+
+ if( aSize != pDisplay_->GetScreenSize() )
+ aRestoreMaximize_ = Rectangle();
+ else
+ if( aRestoreMaximize_.IsEmpty() )
+ {
+ stderr0( "SalFrameData::HandleSizeEvent zoomed\n" );
+ GetPosSize( aRestoreMaximize_ );
+ }
+ }
+
+ aPosSize_.Left() = pEvent->x;
+ aPosSize_.Top() = pEvent->y;
+ aPosSize_.Right() = aPosSize_.Left() + pEvent->width - 1;
+ aPosSize_.Bottom() = aPosSize_.Top() + pEvent->height - 1;
+
+ // update children's position
+ RepositionFloatChildren();
+
+ if( nWidth_ != pEvent->width || nHeight_ != pEvent->height )
+ {
+ nWidth_ = pEvent->width;
+ nHeight_ = pEvent->height;
+
+ if( pEvent->window != XtWindow( hComposite_ ) )
+ {
+ XtResizeWidget(hComposite_, nWidth_, nHeight_, 0);
+
+ Arg args[4];
+ int n = 0;
+ XtSetArg(args[n], XtNheight, pEvent->height); n++;
+ XtSetArg(args[n], XtNwidth, pEvent->width); n++;
+ // XtSetValues(hComposite_, args, n);
+ }
+ Call( SALEVENT_RESIZE, NULL );
+ }
+ return 1;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+long SalFrameData::HandleReparentEvent( XReparentEvent *pEvent )
+{
+ Display *pDisplay = pEvent->display;
+ XLIB_Window hWM_Parent = pEvent->parent;
+ XLIB_Window hRoot, *Children, hDummy;
+ unsigned int nChildren, n;
+ BOOL bNone = pDisplay_->GetProperties()
+ & PROPERTY_SUPPORT_WM_Parent_Pixmap_None;
+
+ if( hWM_Parent == pDisplay_->GetRootWindow()
+ || hWM_Parent == hForeignParent_
+ || ( nStyle_ & SAL_FRAME_STYLE_FLOAT ) )
+ {
+ // Reparenting before Destroy
+ return 0;
+ }
+
+ if( !pEvent->x && !pEvent->y )
+ {
+ if( bNone )
+ XSetWindowBackgroundPixmap( pDisplay, hWM_Parent, None );
+
+ XQueryTree( GetXDisplay(),
+ hWM_Parent,
+ &hRoot,
+ &hWM_Parent,
+ &Children,
+ &nChildren );
+
+ XFree( Children );
+ }
+
+ if( hWM_Parent == hRoot )
+ hWM_Parent = pEvent->parent;
+ else if( bNone )
+ XSetWindowBackgroundPixmap( pDisplay, hWM_Parent, None );
+
+ XQueryTree( pDisplay,
+ hWM_Parent,
+ &hRoot,
+ &hDummy,
+ &Children,
+ &nChildren );
+
+#ifdef DBG_UTIL
+ if( hDummy != hRoot )
+ {
+ fprintf( stderr,
+ "SalFrameData::HandleReparentEvent hDummy!=hRoot"
+ " r=%ld d=%ld p=%ld n=%d\n",
+ hRoot, hDummy, hWM_Parent, nChildren );
+ pDisplay_->PrintEvent( "HandleReparentEvent", (XEvent*)pEvent );
+ }
+#endif
+#ifdef NC_EVENTS
+ for( n = 0; n < nChildren; n++ )
+ if( Children[n] != hShell_ && Children[n] != pEvent->parent )
+ XSelectInput( pDisplay, Children[n], NC_EVENTS );
+#endif
+ XFree( Children );
+ if( !XTranslateCoordinates( GetXDisplay(),
+ XtWindow( hShell_ ),
+ hWM_Parent,
+ 0, 0,
+ &nLeft_, &nTop_,
+ &hDummy ) )
+ {
+ fprintf( stderr, "SalFramaData::HandleReparentEvent !XTranslateCoordinates\n" );
+ abort();
+ }
+
+ nRight_ = nLeft_; // ???
+ nBottom_ = nLeft_; // ???
+
+ // hack: maximize if vendor is XFREE (why? MB!), only remote client
+
+ if( (aPosSize_.IsEmpty() || WindowNeedGoodPosition( XtWindow( hShell_ ) ) )
+ && pDisplay_->GetProperties() & PROPERTY_FEATURE_Maximize )
+ {
+ nShowState_ = SHOWSTATE_NORMAL;
+ Maximize();
+ aRestoreMaximize_ = Rectangle(); // not a real maximize
+ }
+ else
+ {
+ // limit width and height if we are too large: #47757
+ // olwm and fvwm need this, it doesnt harm the rest
+
+ int nScreenWidth = pDisplay_->GetScreenSize().Width();
+ int nScreenHeight = pDisplay_->GetScreenSize().Height();
+ int nFrameWidth = aPosSize_.GetWidth() + nLeft_ + nRight_;
+ int nFrameHeight = aPosSize_.GetHeight() + nTop_ + nBottom_;
+
+ if ((nFrameWidth > nScreenWidth) || (nFrameHeight > nScreenHeight))
+ {
+ Size aSize(aPosSize_.GetWidth(), aPosSize_.GetHeight());
+
+ if (nFrameWidth > nScreenWidth)
+ aSize.Width() = nScreenWidth - nRight_ - nLeft_;
+ if (nFrameHeight > nScreenHeight)
+ aSize.Height() = nScreenHeight - nBottom_ - nTop_;
+
+ SetSize (aSize);
+ }
+ }
+
+
+ return 1;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+alpha long SalFrameData::HandleColormapEvent( XColormapEvent *pEvent )
+{
+ return 0;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+long SalFrameData::HandleStateEvent( XPropertyEvent *pEvent )
+{
+ Atom actual_type;
+ int actual_format;
+ unsigned long nitems, bytes_after;
+ unsigned char *prop = NULL;
+
+ if( 0 != XGetWindowProperty( GetXDisplay(),
+ XtWindow( hShell_ ),
+ pEvent->atom, // property
+ 0, // long_offset (32bit)
+ 2, // long_length (32bit)
+ False, // delete
+ pEvent->atom, // req_type
+ &actual_type,
+ &actual_format,
+ &nitems,
+ &bytes_after,
+ &prop )
+ || ! prop
+ )
+ return 0;
+
+ DBG_ASSERT( actual_type = pEvent->atom
+ && 32 == actual_format
+ && 2 == nitems
+ && 0 == bytes_after, "HandleStateEvent" )
+
+ if( *(unsigned long*)prop == NormalState )
+ nShowState_ = SHOWSTATE_NORMAL;
+ else if( *(unsigned long*)prop == IconicState )
+ nShowState_ = SHOWSTATE_MINIMIZED;
+
+ XFree( prop );
+ return 1;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+long SalFrameData::HandleClientMessage( XClientMessageEvent *pEvent )
+{
+ SalICCCM &rICCCM = pDisplay_->GetICCCM();
+
+ if( rICCCM.IsUserEvent( pEvent->message_type ) )
+ {
+#if __SIZEOFLONG > 4
+ void* pData = (void*)
+ ( (pEvent->data.l[0] & 0xffffffff) | (pEvent->data.l[1] << 32) );
+#else
+ void* pData = (void*)(pEvent->data.l[0]);
+#endif
+ Call( SALEVENT_USEREVENT, pData );
+ return 1;
+ }
+ else if( rICCCM.IsQuitEvent( pEvent->message_type ) )
+ {
+ stderr0( "SalFrameData::Dispatch Quit\n" );
+ Close(); // ???
+ return 1;
+ }
+ else if( rICCCM.IsWM_Protocols( pEvent->message_type ) )
+ {
+ if( rICCCM.IsWM_DeleteWindow( pEvent->data.l[0] ) )
+ {
+ stderr0( "SalFrameData::Dispatch DeleteWindow\n" );
+ Close();
+ return 1;
+ }
+ else if( rICCCM.IsWM_SaveYourself( pEvent->data.l[0] ) )
+ {
+ SalFrame* pLast = GetSalData()->pFirstFrame_;
+ while( pLast->maFrameData.pNextFrame_ )
+ pLast = pLast->maFrameData.pNextFrame_;
+ if( pLast == pFrame_ )
+ {
+ ByteString aExec( SessionManagerClient::getExecName(), gsl_getSystemTextEncoding() );
+ char* argv[2];
+ argv[0] = "/bin/sh";
+ argv[1] = const_cast<char*>(aExec.GetBuffer());
+ XSetCommand( GetXDisplay(), XtWindow( hShell_ ), argv, 2 );
+ }
+ else
+ XDeleteProperty( GetXDisplay(), XtWindow( hShell_ ), rICCCM.aWM_Command_ );
+ }
+ }
+ return 0;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Bool SalFrameData::checkKeyReleaseForRepeat( Display* pDisplay, XEvent* pCheck, XPointer pSalFrameData )
+{
+ SalFrameData* pThis = (SalFrameData*)pSalFrameData;
+ return
+ pCheck->type == XLIB_KeyPress &&
+ pCheck->xkey.state == pThis->nKeyState_ &&
+ pCheck->xkey.keycode == pThis->nKeyCode_ &&
+ pCheck->xkey.time == pThis->nReleaseTime_ ? True : False;
+}
+
+long SalFrameData::Dispatch( XEvent *pEvent )
+{
+ long nRet = 0;
+
+ if( -1 == nCaptured_ )
+ {
+ CaptureMouse( TRUE );
+#ifdef DBG_UTIL
+ if( -1 != nCaptured_ )
+ pDisplay_->PrintEvent( "Captured", pEvent );
+#endif
+ }
+
+ if( pEvent->xany.window == XtWindow( hShell_ ) || pEvent->xany.window == XtWindow( hComposite_ ) )
+ {
+ switch( pEvent->type )
+ {
+ case XLIB_KeyPress:
+ nKeyCode_ = pEvent->xkey.keycode;
+ nKeyState_ = pEvent->xkey.state;
+ nRet = HandleKeyEvent( &pEvent->xkey );
+ break;
+
+ case KeyRelease:
+ if( -1 == nCompose_ )
+ {
+ nReleaseTime_ = pEvent->xkey.time;
+ XEvent aEvent;
+ if( XCheckIfEvent( pEvent->xkey.display, &aEvent, checkKeyReleaseForRepeat, (XPointer)this ) )
+ XPutBackEvent( pEvent->xkey.display, &aEvent );
+ else
+ nRet = HandleKeyEvent( &pEvent->xkey );
+ }
+ break;
+
+ case ButtonPress:
+ // #74406# if we loose the focus in presentation mode
+ // there are good chances that we never get it back
+ // since the WM ignores us
+ if( hNoFullscreenShell_ != None )
+ {
+ XSetInputFocus( GetXDisplay(), GetShellWindow(),
+ RevertToNone, CurrentTime );
+ }
+
+ case ButtonRelease:
+ case MotionNotify:
+ case EnterNotify:
+ case LeaveNotify:
+ nRet = HandleMouseEvent( pEvent );
+ break;
+
+ case FocusIn:
+ case FocusOut:
+ nRet = HandleFocusEvent( &pEvent->xfocus );
+ break;
+
+ case Expose:
+ case GraphicsExpose:
+ nRet = HandleExposeEvent( pEvent );
+ break;
+
+ case MapNotify:
+ if( pEvent->xmap.window == XtWindow( hShell_ ) ||
+ pEvent->xmap.window == XtWindow( hComposite_ ) )
+ {
+ bMapped_ = TRUE;
+ bViewable_ = TRUE;
+ nRet = TRUE;
+ if ( mpInputContext != NULL )
+ mpInputContext->Map( pFrame_ );
+ Call( SALEVENT_RESIZE, NULL );
+ }
+ break;
+
+ case UnmapNotify:
+ if( pEvent->xunmap.window == XtWindow( hShell_ ) )
+ {
+ bMapped_ = FALSE;
+ bViewable_ = FALSE;
+ nRet = TRUE;
+ if ( mpInputContext != NULL )
+ mpInputContext->Unmap();
+ Call( SALEVENT_RESIZE, NULL );
+ }
+ break;
+
+ case ConfigureNotify:
+ if( pEvent->xconfigure.window == XtWindow( hShell_ ) ||
+ pEvent->xconfigure.window == XtWindow( hComposite_ ) )
+ nRet = HandleSizeEvent( &pEvent->xconfigure );
+ break;
+
+ case VisibilityNotify:
+ nVisibility_ = pEvent->xvisibility.state;
+ nRet = TRUE;
+ break;
+
+ case ReparentNotify:
+ nRet = HandleReparentEvent( &pEvent->xreparent );
+ break;
+
+ case MappingNotify:
+ if( MappingPointer != pEvent->xmapping.request )
+ nRet = Call( SALEVENT_KEYBOARDCHANGED, 0 );
+ break;
+
+ case ColormapNotify:
+ nRet = HandleColormapEvent( &pEvent->xcolormap );
+ break;
+
+ case PropertyNotify:
+ {
+ SalICCCM &rICCCM = pDisplay_->GetICCCM();
+
+ if( rICCCM.IsWM_State( pEvent->xproperty.atom ) )
+ nRet = HandleStateEvent( &pEvent->xproperty );
+ else
+ nRet = 1;
+ break;
+ }
+
+ case ClientMessage:
+ nRet = HandleClientMessage( &pEvent->xclient );
+ break;
+ }
+ }
+ else
+ {
+ switch( pEvent->type )
+ {
+#ifdef NC_EVENTS
+ case XLIB_KeyPress:
+ case KeyRelease:
+ nRet = HandleNCKeyEvent()
+ break;
+
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case EnterNotify:
+ case LeaveNotify:
+ nRet = HandleNCMouseEvent( pEvent );
+ break;
+
+ case Expose:
+ nRet = HandleNCExposeEvent( pEvent );
+ break;
+#endif
+ case ConfigureNotify:
+ if( pEvent->xconfigure.window == hForeignParent_ ||
+ pEvent->xconfigure.window == hForeignTopLevelWindow_ )
+ nRet = HandleSizeEvent( &pEvent->xconfigure );
+ break;
+ }
+ }
+
+ // #74406# do not raise fullscreenwindow as it may override the
+ // screenlocker
+#if 0
+ if( bAlwaysOnTop_
+ && nVisibility_ != VisibilityUnobscured
+ && pEvent->type != ConfigureNotify
+ && pEvent->type != MotionNotify )
+ {
+ XRaiseWindow( GetXDisplay(), XtWindow( hShell_ ) );
+ }
+#endif
+
+
+ return nRet;
+}
+
diff --git a/vcl/unx/source/window/salobj.cxx b/vcl/unx/source/window/salobj.cxx
new file mode 100644
index 000000000000..56d2383d8928
--- /dev/null
+++ b/vcl/unx/source/window/salobj.cxx
@@ -0,0 +1,447 @@
+/*************************************************************************
+ *
+ * $RCSfile: salobj.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_SALOBJ_CXX
+
+#include <prex.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/shape.h>
+#ifdef USE_MOTIF
+#include <Xm/DrawingA.h>
+#else
+#include <X11/Xaw/Label.h>
+#endif
+#include <postx.h>
+
+#include <salunx.h>
+#include <salstd.hxx>
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALDISP_HXX
+#include <saldisp.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+
+#ifdef USE_MOTIF
+#define OBJECT_WIDGET_CLASS xmDrawingAreaWidgetClass
+#else
+#define OBJECT_WIDGET_CLASS labelWidgetClass
+#endif
+
+SalObjectList SalObjectData::aAllObjects;
+
+// =======================================================================
+
+long ImplSalObjCallbackDummy( void*, SalObject*, USHORT, const void* )
+{
+ return 0;
+}
+
+// =======================================================================
+// SalInstance memberfkts to create and destroy a SalObject
+
+SalObject* SalInstance::CreateObject( SalFrame* pParent )
+{
+ int error_base, event_base;
+ SalObject* pObject = new SalObject;
+ SystemChildData* pObjData = const_cast<SystemChildData*>(pObject->GetSystemData());
+
+ if ( ! XShapeQueryExtension( (Display*)pObjData->pDisplay,
+ &event_base, &error_base ) )
+ {
+ delete pObject;
+ return NULL;
+ }
+
+ SalDisplay* pSalDisp = pParent->maFrameData.GetDisplay();
+ Widget pWidgetParent = pParent->maFrameData.GetWidget();
+
+ pObject->maObjectData.maPrimary =
+ XtVaCreateManagedWidget( "salobject primary",
+ OBJECT_WIDGET_CLASS,
+ pWidgetParent,
+ NULL );
+ pObject->maObjectData.maSecondary =
+ XtVaCreateManagedWidget( "salobject secondary",
+ OBJECT_WIDGET_CLASS,
+ pObject->maObjectData.maPrimary,
+ NULL );
+ XtRealizeWidget( pObject->maObjectData.maPrimary );
+ XtRealizeWidget( pObject->maObjectData.maSecondary );
+
+ pObjData->pDisplay = XtDisplay( pObject->maObjectData.maPrimary );
+ pObjData->aWindow = XtWindow( pObject->maObjectData.maSecondary );
+ pObjData->pWidget = pObject->maObjectData.maSecondary;
+ pObjData->pVisual = pSalDisp->GetVisual()->GetVisual();
+ pObjData->nDepth = pSalDisp->GetVisual()->GetDepth();
+ pObjData->aColormap = pSalDisp->GetColormap().GetXColormap();
+ pObjData->pAppContext = pSalDisp->GetXLib()->GetAppContext();
+ return pObject;
+}
+
+
+void SalInstance::DestroyObject( SalObject* pObject )
+{
+ delete pObject;
+}
+
+
+// ======================================================================
+// SalClipRegion is a member of SalObject
+// definition of SalClipRegion my be found in unx/inc/salobj.h
+
+
+SalClipRegion::SalClipRegion()
+{
+ ClipRectangleList = NULL;
+ numClipRectangles = 0;
+ maxClipRectangles = 0;
+ nClipRegionType = SAL_OBJECT_CLIP_INCLUDERECTS;
+}
+
+
+SalClipRegion::~SalClipRegion()
+{
+ if ( ClipRectangleList )
+ delete ClipRectangleList;
+}
+
+
+void
+SalClipRegion::BeginSetClipRegion( ULONG nRects )
+{
+ if (ClipRectangleList)
+ delete ClipRectangleList;
+
+ ClipRectangleList = new XRectangle[nRects];
+ numClipRectangles = 0;
+ maxClipRectangles = nRects;
+}
+
+
+void
+SalClipRegion::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ if ( nWidth && nHeight && (numClipRectangles < maxClipRectangles) )
+ {
+ XRectangle *aRect = ClipRectangleList + numClipRectangles;
+
+ aRect->x = (short) nX;
+ aRect->y = (short) nY;
+ aRect->width = (unsigned short) nWidth;
+ aRect->height= (unsigned short) nHeight;
+
+ numClipRectangles++;
+ }
+}
+
+
+// =======================================================================
+// SalObject Implementation
+
+
+SalObject::SalObject()
+{
+ maObjectData.maSystemChildData.nSize = sizeof( SystemChildData );
+ maObjectData.maSystemChildData.pDisplay = GetSalData()->GetDefDisp()->GetDisplay();
+ maObjectData.maSystemChildData.aWindow = None;
+ maObjectData.maSystemChildData.pSalFrame = 0;
+ maObjectData.maSystemChildData.pWidget = 0;
+ maObjectData.maSystemChildData.pVisual = 0;
+ maObjectData.maSystemChildData.nDepth = 0;
+ maObjectData.maSystemChildData.aColormap = 0;
+
+ maObjectData.mpInst = NULL;
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+ maObjectData.maPrimary = NULL;
+ maObjectData.maSecondary = NULL;
+
+ SalObjectData::aAllObjects.Insert( this, LIST_APPEND );
+}
+
+
+SalObject::~SalObject()
+{
+ SalObjectData::aAllObjects.Remove( this );
+ if ( maObjectData.maPrimary )
+ XtDestroyWidget ( maObjectData.maPrimary );
+ if ( maObjectData.maSecondary )
+ XtDestroyWidget ( maObjectData.maSecondary );
+}
+
+
+void
+SalObject::ResetClipRegion()
+{
+ maObjectData.maClipRegion.ResetClipRegion();
+
+ const int dest_kind = ShapeBounding;
+ const int op = ShapeSet;
+ const int ordering = YSorted;
+
+ XWindowAttributes win_attrib;
+ XRectangle win_size;
+
+ XGetWindowAttributes ( (Display*)maObjectData.maSystemChildData.pDisplay,
+ maObjectData.maSystemChildData.aWindow,
+ &win_attrib );
+
+ win_size.x = 0;
+ win_size.y = 0;
+ win_size.width = win_attrib.width;
+ win_size.height = win_attrib.width;
+
+ XShapeCombineRectangles ( (Display*)maObjectData.maSystemChildData.pDisplay,
+ maObjectData.maSystemChildData.aWindow,
+ dest_kind,
+ 0, 0, // x_off, y_off
+ &win_size, // list of rectangles
+ 1, // number of rectangles
+ op, ordering );
+}
+
+
+void
+SalObject::BeginSetClipRegion( ULONG nRectCount )
+{
+ maObjectData.maClipRegion.BeginSetClipRegion ( nRectCount );
+}
+
+
+void
+SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ maObjectData.maClipRegion.UnionClipRegion ( nX, nY, nWidth, nHeight );
+}
+
+
+void
+SalObject::EndSetClipRegion()
+{
+ XRectangle *pRectangles = maObjectData.maClipRegion.EndSetClipRegion ();
+ const int nType = maObjectData.maClipRegion.GetClipRegionType();
+ const int nRectangles = maObjectData.maClipRegion.GetRectangleCount();
+
+ const int dest_kind = ShapeBounding;
+ const int ordering = YSorted;
+ int op;
+
+ switch ( nType )
+ {
+ case SAL_OBJECT_CLIP_INCLUDERECTS :
+ op = ShapeSet;
+ break;
+ case SAL_OBJECT_CLIP_EXCLUDERECTS :
+ op = ShapeSubtract;
+ break;
+ case SAL_OBJECT_CLIP_ABSOLUTE :
+ op = ShapeSet;
+ break;
+ default :
+ op = ShapeUnion;
+ }
+
+ XShapeCombineRectangles ( (Display*)maObjectData.maSystemChildData.pDisplay,
+ maObjectData.maSystemChildData.aWindow,
+ dest_kind,
+ 0, 0, // x_off, y_off
+ pRectangles,
+ nRectangles,
+ op, ordering );
+}
+
+
+USHORT
+SalObject::GetClipRegionType()
+{
+ return maObjectData.maClipRegion.GetClipRegionType();
+}
+
+// -----------------------------------------------------------------------
+
+void
+SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
+{
+ if ( maObjectData.maPrimary && maObjectData.maSecondary && nWidth && nHeight )
+ {
+ XtConfigureWidget( maObjectData.maPrimary,
+ nX, nY, nWidth, nHeight, 0 );
+ XtConfigureWidget( maObjectData.maSecondary,
+ 0, 0, nWidth, nHeight, 0 );
+ }
+}
+
+
+void
+SalObject::Show( BOOL bVisible )
+{
+ if ( ! maObjectData.maSystemChildData.aWindow )
+ return;
+
+ if ( bVisible )
+ XtMapWidget( (Widget)maObjectData.maPrimary );
+ else
+ XtUnmapWidget( (Widget)maObjectData.maPrimary );
+
+ maObjectData.mbVisible = bVisible;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::Enable( BOOL bEnable )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::GrabFocus()
+{
+ if( maObjectData.mbVisible )
+ XSetInputFocus( (Display*)maObjectData.maSystemChildData.pDisplay,
+ maObjectData.maSystemChildData.aWindow,
+ RevertToNone,
+ CurrentTime );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground( SalColor nSalColor )
+{
+}
+
+// -----------------------------------------------------------------------
+
+const SystemChildData* SalObject::GetSystemData() const
+{
+ return &maObjectData.maSystemChildData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc )
+{
+ maObjectData.mpInst = pInst;
+ if ( pProc )
+ maObjectData.mpProc = pProc;
+ else
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+}
+
+long SalObjectData::Dispatch( XEvent* pEvent )
+{
+ for( int n= 0; n < aAllObjects.Count(); n++ )
+ {
+ SalObject* pObject = aAllObjects.GetObject( n );
+ if( pEvent->xany.window == XtWindow( pObject->maObjectData.maPrimary ) ||
+ pEvent->xany.window == XtWindow( pObject->maObjectData.maSecondary ) )
+ {
+ switch( pEvent->type )
+ {
+ case UnmapNotify:
+ pObject->maObjectData.mbVisible = FALSE;
+ return 1;
+ case MapNotify:
+ pObject->maObjectData.mbVisible = TRUE;
+ return 1;
+ case ButtonPress:
+ pObject->maObjectData.mpProc(
+ pObject->maObjectData.mpInst,
+ pObject,
+ SALOBJ_EVENT_TOTOP,
+ NULL );
+ return 1;
+ case FocusIn:
+ pObject->maObjectData.mpProc(
+ pObject->maObjectData.mpInst,
+ pObject,
+ SALOBJ_EVENT_GETFOCUS,
+ NULL );
+ return 1;
+ case FocusOut:
+ pObject->maObjectData.mpProc(
+ pObject->maObjectData.mpInst,
+ pObject,
+ SALOBJ_EVENT_LOSEFOCUS,
+ NULL );
+ return 1;
+ default: break;
+ }
+ return 0;
+ }
+ }
+ return 0;
+}
diff --git a/vcl/util/makefile.mk b/vcl/util/makefile.mk
new file mode 100644
index 000000000000..6eeccee61607
--- /dev/null
+++ b/vcl/util/makefile.mk
@@ -0,0 +1,609 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=VCL
+TARGET=vcl
+VERSION=$(UPD)
+USE_LDUMP2=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+LDUMP=ldump2.exe
+
+# --- Allgemein ----------------------------------------------------------
+
+.IF "$(depend)" == ""
+
+HXXDEPNLST= $(INC)$/accel.hxx \
+ $(INC)$/animate.hxx \
+ $(INC)$/apptypes.hxx \
+ $(INC)$/bitmap.hxx \
+ $(INC)$/bitmapex.hxx \
+ $(INC)$/bmpacc.hxx \
+ $(INC)$/btndlg.hxx \
+ $(INC)$/button.hxx \
+ $(INC)$/ctrl.hxx \
+ $(INC)$/color.hxx \
+ $(INC)$/config.hxx \
+ $(INC)$/cursor.hxx \
+ $(INC)$/clip.hxx \
+ $(INC)$/cmdevt.hxx \
+ $(INC)$/drag.hxx \
+ $(INC)$/decoview.hxx \
+ $(INC)$/dialog.hxx \
+ $(INC)$/dockwin.hxx \
+ $(INC)$/edit.hxx \
+ $(INC)$/event.hxx \
+ $(INC)$/exchange.hxx \
+ $(INC)$/field.hxx \
+ $(INC)$/fixed.hxx \
+ $(INC)$/floatwin.hxx \
+ $(INC)$/font.hxx \
+ $(INC)$/floatwin.hxx \
+ $(INC)$/graph.hxx \
+ $(INC)$/group.hxx \
+ $(INC)$/help.hxx \
+ $(INC)$/jobset.hxx \
+ $(INC)$/keycodes.hxx \
+ $(INC)$/keycod.hxx \
+ $(INC)$/image.hxx \
+ $(INC)$/line.hxx \
+ $(INC)$/lstbox.h \
+ $(INC)$/lstbox.hxx \
+ $(INC)$/mapmod.hxx \
+ $(INC)$/metaact.hxx \
+ $(INC)$/menu.hxx \
+ $(INC)$/menubtn.hxx \
+ $(INC)$/metric.hxx \
+ $(INC)$/morebtn.hxx \
+ $(INC)$/msgbox.hxx \
+ $(INC)$/octree.hxx \
+ $(INC)$/outdev.hxx \
+ $(INC)$/outdev3d.hxx \
+ $(INC)$/pointr.hxx \
+ $(INC)$/poly.hxx \
+ $(INC)$/ptrstyle.hxx \
+ $(INC)$/prntypes.hxx \
+ $(INC)$/print.hxx \
+ $(INC)$/prndlg.hxx \
+ $(INC)$/region.hxx \
+ $(INC)$/rc.hxx \
+ $(INC)$/resid.hxx \
+ $(INC)$/resary.hxx \
+ $(INC)$/salbtype.hxx \
+ $(INC)$/scrbar.hxx \
+ $(INC)$/slider.hxx \
+ $(INC)$/seleng.hxx \
+ $(INC)$/settings.hxx \
+ $(INC)$/sound.hxx \
+ $(INC)$/sndstyle.hxx \
+ $(INC)$/split.hxx \
+ $(INC)$/splitwin.hxx \
+ $(INC)$/spin.hxx \
+ $(INC)$/spinfld.hxx \
+ $(INC)$/status.hxx \
+ $(INC)$/stdtext.hxx \
+ $(INC)$/sv.h \
+ $(INC)$/svapp.hxx \
+ $(INC)$/syschild.hxx \
+ $(INC)$/sysdata.hxx \
+ $(INC)$/system.hxx \
+ $(INC)$/syswin.hxx \
+ $(INC)$/tabctrl.hxx \
+ $(INC)$/tabdlg.hxx \
+ $(INC)$/tabpage.hxx \
+ $(INC)$/toolbox.hxx \
+ $(INC)$/timer.hxx \
+ $(INC)$/virdev.hxx \
+ $(INC)$/wall.hxx \
+ $(INC)$/waitobj.hxx \
+ $(INC)$/wintypes.hxx \
+ $(INC)$/window.hxx \
+ $(INC)$/wrkwin.hxx
+
+.IF "$(linkinc)" != ""
+SHL11FILE= $(MISC)$/app.slo
+SHL12FILE= $(MISC)$/gdi.slo
+SHL13FILE= $(MISC)$/win.slo
+SHL14FILE= $(MISC)$/ctrl.slo
+#SHL15FILE= $(MISC)$/ex.slo
+SHL16FILE= $(MISC)$/salapp.slo
+SHL17FILE= $(MISC)$/salwin.slo
+SHL18FILE= $(MISC)$/salgdi.slo
+.ENDIF
+
+LIB1TARGET= $(SLB)$/$(TARGET).lib
+LIB1FILES= $(SLB)$/app.lib \
+ $(SLB)$/gdi.lib \
+ $(SLB)$/win.lib \
+ $(SLB)$/ctrl.lib \
+ $(SLB)$/ex.lib \
+ $(SLB)$/helper.lib
+
+.IF "$(remote)" != ""
+LIB1FILES+= \
+ $(SLB)$/remote.lib
+.IF "$(COM)"=="GCC"
+LIB1OBJFILES=$(SLO)$/salmain.obj
+.ENDIF
+.ELSE
+LIB1FILES+= \
+ $(SLB)$/salwin.lib \
+ $(SLB)$/salgdi.lib \
+ $(SLB)$/salapp.lib
+.ENDIF
+
+SHL1TARGET= vcl$(VERSION)$(DLLPOSTFIX)
+SHL1IMPLIB= ivcl
+SHL1STDLIBS=$(TOOLSLIB) \
+ $(SOTLIB) \
+ $(VOSLIB) \
+ $(SALLIB) \
+ $(CPPUHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(CPPULIB) \
+ $(UNOTOOLSLIB)
+
+.IF "$(remote)" != ""
+SHL1STDLIBS+=\
+ $(UNOLIB)
+.ENDIF
+
+.IF "$(GUI)"!="MAC"
+SHL1DEPN= $(L)$/itools.lib $(L)$/sot.lib
+.ENDIF
+
+SHL1LIBS= $(LIB1TARGET)
+.IF "$(GUI)"!="UNX"
+SHL1OBJS= $(SLO)$/salshl.obj
+.ENDIF
+
+.IF "$(GUI)" != "MAC"
+.IF "$(GUI)" != "UNX"
+SHL1RES= $(RES)$/salsrc.res
+.ENDIF
+.ENDIF
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+ALLTAR+= $(LIB1TARGET)
+
+# --- VCL-Light ----------------------------------------------------------
+
+.IF "$(VCL_LIGHT)" != ""
+LIB2TARGET= $(SLB)$/vll.lib
+LIB2FILES= $(SLO)$/access.obj \
+ $(SLO)$/config.obj \
+ $(SLO)$/dbggui.obj \
+ $(SLO)$/system.obj \
+ $(SLO)$/oldsv.obj \
+ $(SLO)$/help.obj \
+ $(SLO)$/idlemgr.obj \
+ $(SLO)$/resmgr.obj \
+ $(SLO)$/settings.obj \
+ $(SLO)$/sound.obj \
+ $(SLO)$/stdtext.obj \
+ $(SLO)$/svapp.obj \
+ $(SLO)$/svdata.obj \
+ $(SLO)$/svmain.obj \
+ $(SLO)$/timer.obj \
+ $(SLO)$/animate.obj \
+ $(SLO)$/salmisc.obj \
+ $(SLO)$/impanmvw.obj \
+ $(SLO)$/bitmap.obj \
+ $(SLO)$/bitmap2.obj \
+ $(SLO)$/bitmap3.obj \
+ $(SLO)$/bitmap4.obj \
+ $(SLO)$/alpha.obj \
+ $(SLO)$/bitmapex.obj \
+ $(SLO)$/imgcons.obj \
+ $(SLO)$/bmpacc.obj \
+ $(SLO)$/bmpacc2.obj \
+ $(SLO)$/bmpacc3.obj \
+ $(SLO)$/color.obj \
+ $(SLO)$/cvtsvm.obj \
+ $(SLO)$/cvtgrf.obj \
+ $(SLO)$/font.obj \
+ $(SLO)$/gdimtf.obj \
+ $(SLO)$/gfxlink.obj \
+ $(SLO)$/graph.obj \
+ $(SLO)$/impgraph.obj \
+ $(SLO)$/gradient.obj \
+ $(SLO)$/hatch.obj \
+ $(SLO)$/image.obj \
+ $(SLO)$/impbmp.obj \
+ $(SLO)$/impimage.obj \
+ $(SLO)$/impprn.obj \
+ $(SLO)$/impvect.obj \
+ $(SLO)$/implncvt.obj \
+ $(SLO)$/jobset.obj \
+ $(SLO)$/line.obj \
+ $(SLO)$/lineinfo.obj \
+ $(SLO)$/mapmod.obj \
+ $(SLO)$/metaact.obj \
+ $(SLO)$/metric.obj \
+ $(SLO)$/octree.obj \
+ $(SLO)$/outmap.obj \
+ $(SLO)$/outdev.obj \
+ $(SLO)$/outdev2.obj \
+ $(SLO)$/outdev3.obj \
+ $(SLO)$/outdev4.obj \
+ $(SLO)$/outdev5.obj \
+ $(SLO)$/outdev6.obj \
+ $(SLO)$/opengl.obj \
+ $(SLO)$/poly.obj \
+ $(SLO)$/poly2.obj \
+ $(SLO)$/print.obj \
+ $(SLO)$/print2.obj \
+ $(SLO)$/regband.obj \
+ $(SLO)$/region.obj \
+ $(SLO)$/virdev.obj \
+ $(SLO)$/wall.obj \
+ $(SLO)$/accel.obj \
+ $(SLO)$/accmgr.obj \
+ $(SLO)$/brdwin.obj \
+ $(SLO)$/btndlg.obj \
+ $(SLO)$/cursor.obj \
+ $(SLO)$/dockwin.obj \
+ $(SLO)$/decoview.obj \
+ $(SLO)$/dialog.obj \
+ $(SLO)$/dlgctrl.obj \
+ $(SLO)$/floatwin.obj \
+ $(SLO)$/keycod.obj \
+ $(SLO)$/menu.obj \
+ $(SLO)$/mnemonic.obj \
+ $(SLO)$/msgbox.obj \
+ $(SLO)$/syschild.obj \
+ $(SLO)$/syswin.obj \
+ $(SLO)$/toolbox.obj \
+ $(SLO)$/toolbox2.obj \
+ $(SLO)$/window.obj \
+ $(SLO)$/window2.obj \
+ $(SLO)$/winproc.obj \
+ $(SLO)$/wrkwin.obj \
+ $(SLO)$/scrwnd.obj \
+ $(SLO)$/button.obj \
+ $(SLO)$/ctrl.obj \
+ $(SLO)$/combobox.obj \
+ $(SLO)$/edit.obj \
+ $(SLO)$/field.obj \
+ $(SLO)$/fixed.obj \
+ $(SLO)$/group.obj \
+ $(SLO)$/ilstbox.obj \
+ $(SLO)$/lstbox.obj \
+ $(SLO)$/morebtn.obj \
+ $(SLO)$/spinfld.obj \
+ $(SLO)$/scrbar.obj \
+ $(SLO)$/tabctrl.obj \
+ $(SLB)$/ex.lib \
+ $(SLB)$/helper.lib \
+ $(SLB)$/salwin.lib \
+ $(SLB)$/salgdi.lib \
+ $(SLB)$/salapp.lib
+
+# $(SLO)$/resary.obj \
+# $(SLO)$/filedlg.obj \
+# $(SLO)$/seleng.obj \
+# $(SLO)$/split.obj \
+# $(SLO)$/splitwin.obj \
+# $(SLO)$/status.obj \
+# $(SLO)$/tabdlg.obj \
+# $(SLO)$/tabpage.obj \
+# $(SLO)$/field2.obj \
+# $(SLO)$/imgctrl.obj \
+# $(SLO)$/longcurr.obj \
+# $(SLO)$/fixbrd.obj \
+# $(SLO)$/menubtn.obj \
+# $(SLO)$/slider.obj \
+# $(SLO)$/spinbtn.obj \
+
+SHL2TARGET= vll$(VERSION)$(DLLPOSTFIX)
+SHL2IMPLIB= ivll
+SHL2STDLIBS=$(TOOLSLIB) \
+ $(SOTLIB) \
+ $(VOSLIB) \
+ $(SALLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(UNOTOOLSLIB)
+.IF "$(GUI)"!="MAC"
+SHL2DEPN= $(L)$/itools.lib $(L)$/sot.lib
+.ENDIF
+SHL2LIBS= $(LIB2TARGET)
+
+.IF "$(GUI)"!="UNX"
+SHL2OBJS= $(SLO)$/salshl.obj
+.ENDIF
+
+.IF "$(GUI)" != "MAC"
+.IF "$(GUI)" != "UNX"
+SHL2RES= $(RES)$/salsrc.res
+.ENDIF
+.ENDIF
+SHL2DEF= $(MISC)$/$(SHL2TARGET).def
+
+ALLTAR+= $(LIB2TARGET)
+
+.ENDIF
+
+# --- All ----------------------------------------------------------------
+
+ALL: ALLTAR
+
+# ---MAC----------------------------------------------------------------
+
+.IF "$(GUI)" == "MAC"
+
+$(MISC)$/$(SHL1TARGET).def: makefile.mk
+ delete -i $@
+ $(LINK) $(LINKFLAGS) $(LINKFLAGSSHL) $(SHL$(TNR)OBJS) $(SHL$(TNR)LIBS) -f $@.exp dev:null
+ duplicate -y $@.exp $@
+ delete -i $@.exp
+.IF "$(RUECKWAERTS)" != "" || "$(rueckwaerts)" != ""
+ filter_import "$(SOLARINCDIR)"$/GLOBAL.IMP $@
+.ENDIF
+
+.IF "$(VCL_LIGHT)" != ""
+$(MISC)$/$(SHL2TARGET).def: makefile.mk
+ delete -i $@
+ $(LINK) $(LINKFLAGS) $(LINKFLAGSSHL) $(SHL$(TNR)OBJS) $(SHL$(TNR)LIBS) -f $@.exp dev:null
+ duplicate -y $@.exp $@
+ delete -i $@.exp
+.IF "$(RUECKWAERTS)" != "" || "$(rueckwaerts)" != ""
+ filter_import "$(SOLARINCDIR)"$/GLOBAL.IMP $@
+.ENDIF
+.ENDIF
+
+.ENDIF
+
+# --- W32 ----------------------------------------------------------------
+
+.IF "$(GUI)" == "WNT"
+
+SHL1STDLIBS += gdi32.lib \
+ winspool.lib \
+ ole32.lib \
+ shell32.lib \
+ advapi32.lib \
+ imm32.lib
+
+#.IF ("$(COM)" == "MSC") && ("$(GUI)" == "WNT") && (("$(CPU)" == "A") || ("$(CPU)"=="P") || ("$(CPU)" == "M"))
+.IF "$(COM)$(GUI)" == "MSCWNT"
+.IF $(CPU)" == "A" || "$(CPU)"=="P" || "$(CPU)" == "M"
+LINKFLAGSSHL += /ENTRY:LibMain
+.ENDIF
+.ENDIF
+
+#.IF ("$(COM)" == "MSC") && ("$(GUI)" == "WNT") && ("$(CPU)" == "I")
+.IF "$(GUI)$(COM)$(CPU)" == "WNTMSCI"
+LINKFLAGSSHL += /ENTRY:LibMain@12
+.ENDIF
+
+# --- Def-File ---
+
+$(MISC)$/$(SHL1TARGET).def: $(MISC)$/$(SHL1TARGET).flt \
+ $(HXXDEPNLST) \
+ makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @+-attrib -r defs
+ @echo LIBRARY $(SHL1TARGET) >$@
+ @echo DESCRIPTION 'VCL' >>$@
+ @echo DATA READWRITE NONSHARED >>$@
+ @echo EXPORTS >>$@
+ @echo GetVersionInfo >>$@
+ $(LIBMGR) -EXTRACT:/ /OUT:$(TARGET).exp $(LIB1TARGET)
+ @$(LDUMP) -E20 -F$(MISC)$/$(SHL1TARGET).flt $(TARGET).exp >>$@
+ +-del $(TARGET).exp
+
+# --- VCL-Light ---
+
+.IF "$(VCL_LIGHT)" != ""
+
+SHL2STDLIBS += gdi32.lib \
+ winspool.lib \
+ ole32.lib \
+ shell32.lib \
+ advapi32.lib \
+ imm32.lib
+
+#.IF ("$(COM)" == "MSC") && ("$(GUI)" == "WNT") && (("$(CPU)" == "A") || ("$(CPU)"=="P") || ("$(CPU)" == "M"))
+.IF "$(COM)$(GUI)" == "MSCWNT"
+.IF $(CPU)" == "A" || "$(CPU)"=="P" || "$(CPU)" == "M"
+LINKFLAGSSHL += /ENTRY:LibMain
+.ENDIF
+.ENDIF
+
+#.IF ("$(COM)" == "MSC") && ("$(GUI)" == "WNT") && ("$(CPU)" == "I")
+.IF "$(GUI)$(COM)$(CPU)" == "WNTMSCI"
+LINKFLAGSSHL += /ENTRY:LibMain@12
+.ENDIF
+
+# --- Def-File ---
+
+$(MISC)$/$(SHL2TARGET).def: $(MISC)$/$(SHL1TARGET).flt \
+ $(HXXDEPNLST) \
+ makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo LIBRARY $(SHL2TARGET) >$@
+ @echo DESCRIPTION 'VCL' >>$@
+ @echo DATA READWRITE NONSHARED >>$@
+ @echo EXPORTS >>$@
+ @echo GetVersionInfo >>$@
+ $(LIBMGR) -EXTRACT:/ /OUT:vll.exp $(LIB2TARGET)
+ @$(LDUMP) -E20 -F$(MISC)$/$(SHL1TARGET).flt vll.exp >>$@
+ +-del vll.exp
+
+.ENDIF
+
+.ENDIF
+
+# --- OS2 ----------------------------------------------------------------
+
+.IF "$(GUI)" == "OS2"
+
+# --- Def-File ---
+
+$(MISC)$/$(SHL1TARGET).def: $(MISC)$/$(SHL1TARGET).flt \
+ $(HXXDEPNLST) \
+ makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo LIBRARY $(SHL1TARGET) INITINSTANCE TERMINSTANCE >$@
+ @echo DESCRIPTION 'VCL' >>$@
+ @echo PROTMODE >>$@
+ @echo CODE LOADONCALL >>$@
+ @echo DATA PRELOAD MULTIPLE NONSHARED >>$@
+ @echo EXPORTS >>$@
+ @$(LDUMP) -E1 -A -F$(MISC)$/$(SHL1TARGET).flt $(LIB1TARGET) >>$@
+
+# --- VCL-Light ---
+
+.IF "$(VCL_LIGHT)" != ""
+
+$(MISC)$/$(SHL2TARGET).def: $(MISC)$/$(SHL1TARGET).flt \
+ $(HXXDEPNLST) \
+ makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo LIBRARY $(SHL2TARGET) INITINSTANCE TERMINSTANCE >$@
+ @echo DESCRIPTION 'VCL' >>$@
+ @echo PROTMODE >>$@
+ @echo CODE LOADONCALL >>$@
+ @echo DATA PRELOAD MULTIPLE NONSHARED >>$@
+ @echo EXPORTS >>$@
+ @$(LDUMP) -E1 -A -F$(MISC)$/$(SHL1TARGET).flt $(LIB2TARGET) >>$@
+
+.ENDIF
+
+.ENDIF
+
+# --- UNX ----------------------------------------------------------------
+
+.IF "$(GUI)"=="UNX"
+
+.IF "$(OS)"=="SOLARIS"
+SHL1STDLIBS += -lxp$(UPD)$(DLLPOSTFIX) -lXm -lXt -lX11
+.ELIF "$(OS)"=="MACOSX"
+SHL1STDLIBS +=
+.ELSE
+SHL1STDLIBS += -lxp$(UPD)$(DLLPOSTFIX) -lXaw -lXt -lX11
+.ENDIF
+
+.IF "$(OS)"=="LINUX" || "$(OS)"=="SOLARIS"
+SHL1STDLIBS += -laudio
+.ENDIF
+
+# --- VCL-Light ---
+
+.IF "$(VCL_LIGHT)" != ""
+
+.IF "$(OS)"=="SOLARIS"
+SHL2STDLIBS += -lxp$(UPD)$(DLLPOSTFIX) -lXm -lXt -lX11
+.ELSE
+SHL2STDLIBS += -lxp$(UPD)$(DLLPOSTFIX) -lXaw -lXt -lX11
+.ENDIF
+
+.IF "$(OS)"=="LINUX" || "$(OS)"=="SOLARIS"
+SHL2STDLIBS += -laudio
+.ENDIF
+
+.ENDIF
+
+.ENDIF
+
+# --- Allgemein ----------------------------------------------------------
+
+# --- VCL-Filter-Datei ---
+
+$(MISC)$/$(SHL1TARGET).flt: makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo Impl > $@
+ @echo Sal>> $@
+ @echo Dbg>> $@
+ @echo HelpTextWindow>> $@
+ @echo MenuBarWindow>> $@
+ @echo MenuFloatingWindow>> $@
+ @echo MenuItemList>> $@
+ @echo LibMain>> $@
+ @echo LIBMAIN>> $@
+ @echo Wep>> $@
+ @echo WEP>> $@
+ @echo RmEvent>> $@
+ @echo RmFrameWindow>> $@
+ @echo RmPrinter>> $@
+ @echo RmBitmap>> $@
+ @echo RmSound>> $@
+ @echo __CT>> $@
+
+# --- Targets ------------------------------------------------------------
+
+.ENDIF
+
+.INCLUDE : target.mk
diff --git a/vcl/util/makefile.pmk b/vcl/util/makefile.pmk
new file mode 100644
index 000000000000..dd76e1cfd051
--- /dev/null
+++ b/vcl/util/makefile.pmk
@@ -0,0 +1,68 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.pmk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+PROJECTPCH4DLL=TRUE
+PROJECTPCH=vclpch
+PROJECTPCHSOURCE=$(PRJ)$/util$/vclpch
+PDBTARGET=vcl
+.IF "$(OS)"=="MACOSX"
+GUIBASE=aqua
+.ENDIF
diff --git a/vcl/util/target.pmk b/vcl/util/target.pmk
new file mode 100644
index 000000000000..96285fb5c46e
--- /dev/null
+++ b/vcl/util/target.pmk
@@ -0,0 +1,74 @@
+#*************************************************************************
+#
+# $RCSfile: target.pmk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+ALLSLO: $(SLOFILES)
+
+SOSHL: $(SHL1TARGETN)
+
+WHOLEPRJ .SETDIR=$(PRJ)$/prj:
+ make debug linkinc prjpch compinc
+ @echo "READY"
+
+ONLYDLL .SETDIR=$(PRJ)$/util: $(SLOFILES)
+ $(RM) ..$/$(OUTPATH)$/bin$/sv$(UPD)$(DLLSUFFIX).dll
+ dmake debug=t prjpch=t linkinc=t compinc=t ..$/$(OUTPATH)$/bin$/sv$(UPD)$(DLLSUFFIX).dll
+ @echo "READY"
+
diff --git a/vcl/win/inc/saldata.hxx b/vcl/win/inc/saldata.hxx
new file mode 100644
index 000000000000..2d75109116e5
--- /dev/null
+++ b/vcl/win/inc/saldata.hxx
@@ -0,0 +1,358 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldata.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALDATA_HXX
+#define _SV_SALDATA_HXX
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_SALWTYPE_HXX
+#include <salwtype.hxx>
+#endif
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+
+class AutoTimer;
+class SalInstance;
+class SalObject;
+class SalFrame;
+class SalVirtualDevice;
+class SalPrinter;
+class Font;
+struct HDCCache;
+
+// --------------------
+// - Standard-Defines -
+// --------------------
+
+#define MAX_STOCKPEN 4
+#define MAX_STOCKBRUSH 4
+#define SAL_CLIPRECT_COUNT 16
+
+// -----------
+// - SalData -
+// -----------
+
+struct SalData
+{
+ HINSTANCE mhInst; // default instance handle
+ HINSTANCE mhPrevInst; // previous instance handle
+ int mnCmdShow; // default frame show style
+ // Erst hier koennen Daten kompatible eingefuegt werden, da die
+ // oberen Daten in salmain.cxx modifiziert werden
+ HPALETTE mhDitherPal; // dither palette
+ HGLOBAL mhDitherDIB; // dither memory handle
+ BYTE* mpDitherDIB; // dither memory
+ BYTE* mpDitherDIBData; // beginning of DIB data
+ long* mpDitherDiff; // Dither mapping table
+ BYTE* mpDitherLow; // Dither mapping table
+ BYTE* mpDitherHigh; // Dither mapping table
+ ULONG mnTimerMS; // Current Time (in MS) of the Timer
+ ULONG mnTimerOrgMS; // Current Original Time (in MS)
+ UINT mnTimerId; // windows timer id
+ SALTIMERPROC mpTimerProc; // timer callback proc
+ HHOOK mhSalObjMsgHook; // hook um SalObject relevante Message mitzubekommen
+ HWND mhWantLeaveMsg; // window handle, that want a MOUSELEAVE message
+ AutoTimer* mpMouseLeaveTimer; // Timer for MouseLeave Test
+ SalInstance* mpFirstInstance; // pointer of first instance
+ SalFrame* mpFirstFrame; // pointer of first frame
+ SalObject* mpFirstObject; // pointer of first object window
+ SalVirtualDevice* mpFirstVD; // first VirDev
+ SalPrinter* mpFirstPrinter; // first printing printer
+ HDCCache* mpHDCCache; // Cache for three DC's
+ HBITMAP mh50Bmp; // 50% Bitmap
+ HBRUSH mh50Brush; // 50% Brush
+ COLORREF maStockPenColorAry[MAX_STOCKPEN];
+ COLORREF maStockBrushColorAry[MAX_STOCKBRUSH];
+ HPEN mhStockPenAry[MAX_STOCKPEN];
+ HBRUSH mhStockBrushAry[MAX_STOCKBRUSH];
+ USHORT mnStockPenCount; // Anzahl statischer Pens
+ USHORT mnStockBrushCount; // Anzahl statischer Brushes
+ WPARAM mnSalObjWantKeyEvt; // KeyEvent, welcher vom SalObj-Hook verarbeitet werden soll
+ BOOL mbObjClassInit; // Ist SALOBJECTCLASS initialised
+ BOOL mbInPalChange; // is in WM_QUERYNEWPALETTE
+ DWORD mnAppThreadId; // Id from Applikation-Thread
+ WIN_BOOL mbScrSvrEnabled; // ScreenSaver enabled
+ int mnSageStatus; // Status der Sage-DLL (DISABLE_AGENT == nicht vorhanden)
+ HINSTANCE mhSageInst; // Instance-Handle zur Sage-DLL
+ SysAgt_Enable_PROC mpSageEnableProc; // Funktion zum deaktivieren des Systemagenten
+};
+
+inline void SetSalData( SalData* pData ) { ImplGetSVData()->mpSalData = (void*)pData; }
+inline SalData* GetSalData() { return (SalData*)ImplGetSVData()->mpSalData; }
+inline SalData* GetAppSalData() { return (SalData*)ImplGetAppSVData()->mpSalData; }
+
+// --------------
+// - SalShlData -
+// --------------
+
+struct SalShlData
+{
+ HINSTANCE mhInst; // Instance of SAL-DLL
+ UINT mnVKAdd; // VK-Code von KEY_ADD
+ UINT mnVKSubtract; // VK-Code von KEY_SUBTRACT
+ UINT mnVKMultiply; // VK-Code von KEY_MULTIPLY
+ UINT mnVKDivide; // VK-Code von KEY_DIVIDE
+ UINT mnVKPoint; // VK-Code von KEY_POINT
+ UINT mnVKComma; // VK-Code von KEY_KOMMA
+ UINT mnVKLess; // VK-Code von KEY_LESS
+ UINT mnVKGreater; // VK-Code von KEY_GREATER
+ UINT mnVKEqual; // VK-Code von KEY_EQUAL
+ UINT mnWheelScrollLines; // WheelScrollLines
+ UINT mnWheelMsgId; // Wheel-Message-Id fuer W95
+ WORD mnVersion; // System-Version (311 == 3.11)
+ WIN_BOOL mbWNT; // kein W16/W95/W98 sondern ein NT
+ WIN_BOOL mbW40; // Is System-Version >= 4.0
+};
+
+extern SalShlData aSalShlData;
+
+// ------------
+// - GDICache -
+// ------------
+
+#define CACHESIZE_HDC 3
+#define CACHED_HDC_1 0
+#define CACHED_HDC_2 1
+#define CACHED_HDC_DRAW 2
+#define CACHED_HDC_DEFEXT 64
+
+struct HDCCache
+{
+ HDC mhDC;
+ HPALETTE mhDefPal;
+ HBITMAP mhDefBmp;
+ HBITMAP mhSelBmp;
+ HBITMAP mhActBmp;
+};
+
+void ImplClearHDCCache( SalData* pData );
+HDC ImplGetCachedDC( ULONG nID, HBITMAP hBmp = 0 );
+void ImplReleaseCachedDC( ULONG nID );
+
+// ------------------------------------------------------
+// - SALSHL.CXX - Funktionen fuer DLL-Resource-Zugriffe -
+// ------------------------------------------------------
+
+HCURSOR ImplLoadSalCursor( int nId );
+HBITMAP ImplLoadSalBitmap( int nId );
+BOOL ImplLoadSalIcon( int nId, HICON& rIcon, HICON& rSmallIcon );
+
+// SALGDI.CXX
+void ImplInitSalGDI();
+void ImplFreeSalGDI();
+
+// --------------
+// - Prototypes -
+// --------------
+
+// \\WIN\SOURCE\APP\SALINST.CXX
+void ImplSalYieldMutexAcquireWithWait();
+BOOL ImplSalYieldMutexTryToAcquire();
+void ImplSalYieldMutexAcquire();
+void ImplSalYieldMutexRelease();
+ULONG ImplSalReleaseYieldMutex();
+void ImplSalAcquireYieldMutex( ULONG nCount );
+
+// \\WIN\SOURCE\WINDOW\SALFRAME.CXX
+LRESULT CALLBACK SalFrameWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+LRESULT CALLBACK SalFrameWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+// \SV\WIN\SOURCE\APP\SALTIMER.CXX
+void CALLBACK SalTimerProc( HWND hWnd, UINT nMsg, UINT nId, DWORD nTime );
+
+// \WIN\SOURCE\WINDOW\SALFRAME.CXX
+void SalTestMouseLeave();
+
+// \WIN\SOURCE\WINDOW\SALFRAME.CXX
+long ImplHandleSalObjKeyMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+long ImplHandleSalObjSysCharMsg( HWND hWnd, WPARAM wParam, LPARAM lParam );
+BOOL ImplHandleGlobalMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT& rlResult );
+
+// \WIN\SOURCE\WINDOW\SALOBJ.CXX
+SalObject* ImplFindSalObject( HWND hWndChild );
+BOOL ImplSalPreDispatchMsg( MSG* pMsg );
+void ImplSalPostDispatchMsg( MSG* pMsg, LRESULT nDispatchResult );
+
+// \WIN\SOURCE\GDI\SALGDI3.CXX
+void ImplSalLogFontToFontA( const LOGFONTA& rLogFont, Font& rFont );
+void ImplSalLogFontToFontW( const LOGFONTW& rLogFont, Font& rFont );
+
+// \WIN\SOURCE\APP\SALDATA.CXX
+rtl_TextEncoding ImplSalGetSystemEncoding();
+ByteString ImplSalGetWinAnsiString( const UniString& rStr, BOOL bFileName = FALSE );
+UniString ImplSalGetUniString( const sal_Char* pStr, xub_StrLen nLen = STRING_LEN );
+int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 );
+
+// -----------
+// - Defines -
+// -----------
+
+#define SAL_FRAME_WNDEXTRA sizeof( DWORD )
+#define SAL_FRAME_THIS 0
+#define SAL_FRAME_CLASSNAMEA "SALFRAME"
+#define SAL_FRAME_CLASSNAMEW L"SALFRAME"
+#define SAL_FRAME_CLASSNAME_SBA "SALFRAMESB"
+#define SAL_FRAME_CLASSNAME_SBW L"SALFRAMESB"
+#define SAL_OBJECT_WNDEXTRA sizeof( DWORD )
+#define SAL_OBJECT_THIS 0
+#define SAL_OBJECT_CLASSNAMEA "SALOBJECT"
+#define SAL_OBJECT_CLASSNAMEW L"SALOBJECT"
+#define SAL_OBJECT_CHILDCLASSNAMEA "SALOBJECTCHILD"
+#define SAL_OBJECT_CHILDCLASSNAMEW L"SALOBJECTCHILD"
+#define SAL_COM_CLASSNAMEA "SALCOMWND"
+#define SAL_COM_CLASSNAMEW L"SALCOMWND"
+
+#define SAL_MOUSELEAVE_TIMEOUT 300
+
+// wParam == hDC; lParam == 0
+#define SAL_MSG_PRINTABORTJOB (WM_USER+110)
+// wParam == bWait; lParam == 0
+#define SAL_MSG_THREADYIELD (WM_USER+111)
+// wParam == 0; lParam == 0
+#define SAL_MSG_RELEASEWAITYIELD (WM_USER+112)
+// wParam == 0; lParam == nMS
+#define SAL_MSG_STARTTIMER (WM_USER+113)
+// wParam == nFrameStyle; lParam == pParent; lResult == pFrame
+#define SAL_MSG_CREATEFRAME (WM_USER+114)
+// wParam == 0; lParam == 0
+#define SAL_MSG_DESTROYFRAME (WM_USER+115)
+// wParam == 0; lParam == pParent; lResult == pObject
+#define SAL_MSG_CREATEOBJECT (WM_USER+116)
+// wParam == 0; lParam == pObject;
+#define SAL_MSG_DESTROYOBJECT (WM_USER+117)
+// wParam == 0; lParam == this; lResult == bRet
+#define SAL_MSG_CREATESOUND (WM_USER+118)
+// wParam == 0; lParam == this
+#define SAL_MSG_DESTROYSOUND (WM_USER+119)
+
+// wParam == 0; lParam == pData
+#define SAL_MSG_USEREVENT (WM_USER+130)
+// wParam == 0; lParam == MousePosition relativ to upper left of screen
+#define SAL_MSG_MOUSELEAVE (WM_USER+131)
+// NULL-Message, soll nicht verarbeitet werden
+#define SAL_MSG_DUMMY (WM_USER+132)
+// wParam == 0; lParam == 0
+#define SAL_MSG_POSTFOCUS (WM_USER+133)
+// wParam == wParam; lParam == lParam
+#define SAL_MSG_POSTQUERYNEWPAL (WM_USER+134)
+// wParam == wParam; lParam == lParam
+#define SAL_MSG_POSTPALCHANGED (WM_USER+135)
+// wParam == wParam; lParam == lParam
+#define SAL_MSG_POSTMOVE (WM_USER+136)
+// wParam == wParam; lParam == lParam
+#define SAL_MSG_POSTCALLSIZE (WM_USER+137)
+// wParam == pRECT
+#define SAL_MSG_POSTPAINT (WM_USER+138)
+// wParam == 0; lParam == pFrame; lResult 0
+#define SAL_MSG_FORCEPALETTE (WM_USER+139)
+// wParam == 0; lParam == 0;
+#define SAL_MSG_CAPTUREMOUSE (WM_USER+140)
+// wParam == 0; lParam == 0
+#define SAL_MSG_RELEASEMOUSE (WM_USER+141)
+// wParam == nFlags; lParam == 0
+#define SAL_MSG_TOTOP (WM_USER+142)
+// wParam == bVisible; lParam == 0
+#define SAL_MSG_SHOW (WM_USER+143)
+
+// SysChild-ToTop; wParam = 0; lParam = 0
+#define SALOBJ_MSG_TOTOP (WM_USER+160)
+// POSTFOCUS-Message; wParam == bFocus; lParam == 0
+#define SALOBJ_MSG_POSTFOCUS (WM_USER+161)
+
+// -----------------
+// - Helpfunctions -
+// -----------------
+
+// A/W-Wrapper
+LONG ImplSetWindowLong( HWND hWnd, int nIndex, DWORD dwNewLong );
+LONG ImplGetWindowLong( HWND hWnd, int nIndex );
+WIN_BOOL ImplPostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
+WIN_BOOL ImplSendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
+WIN_BOOL ImplGetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax );
+WIN_BOOL ImplPeekMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg );
+LONG ImplDispatchMessage( CONST MSG *lpMsg );
+
+inline void SetWindowPtr( HWND hWnd, SalFrame* pThis )
+{
+ ImplSetWindowLong( hWnd, SAL_FRAME_THIS, (LONG)pThis );
+}
+
+inline SalFrame* GetWindowPtr( HWND hWnd )
+{
+ return (SalFrame*)ImplGetWindowLong( hWnd, SAL_FRAME_THIS );
+}
+
+inline void SetSalObjWindowPtr( HWND hWnd, SalObject* pThis )
+{
+ ImplSetWindowLong( hWnd, SAL_OBJECT_THIS, (LONG)pThis );
+}
+
+inline SalObject* GetSalObjWindowPtr( HWND hWnd )
+{
+ return (SalObject*)ImplGetWindowLong( hWnd, SAL_OBJECT_THIS );
+}
+
+#endif // _SV_SALDATA_HXX
diff --git a/vcl/win/inc/salframe.h b/vcl/win/inc/salframe.h
new file mode 100644
index 000000000000..4991dd4937b6
--- /dev/null
+++ b/vcl/win/inc/salframe.h
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * $RCSfile: salframe.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALFRAME_H
+#define _SV_SALFRAME_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+// ----------------
+// - SalFrameData -
+// ----------------
+
+class SalFrameData
+{
+public:
+ HWND mhWnd; // Window handle
+ HCURSOR mhCursor; // cursor handle
+ HIMC mhDefIMEContext; // default IME-Context
+ SalGraphics* mpGraphics; // current frame graphics
+ SalFrame* mpNextFrame; // pointer to next frame
+ void* mpInst; // instance handle for callback
+ SALFRAMEPROC mpProc; // callback proc
+ SystemEnvData maSysData; // system data
+ SalFrameState maState; // frame state
+ int mnShowState; // show state
+ long mnWidth; // client width in pixeln
+ long mnHeight; // client height in pixeln
+ RECT maFullScreenRect; // fullscreen rect
+ int mnFullScreenShowState; // fullscreen restore show state
+ UINT mnInputLang; // current Input Language
+ UINT mnInputCodePage; // current Input CodePage
+ USHORT mnStyle; // style
+ BOOL mbGraphics; // is Graphics used
+ BOOL mbCaption; // has window a caption
+ BOOL mbBorder; // has window a border
+ BOOL mbSizeBorder; // has window a sizeable border
+ BOOL mbFullScreen; // TRUE: in full screen mode
+ BOOL mbPresentation; // TRUE: Presentation Mode running
+ BOOL mbInShow; // innerhalb eines Show-Aufrufs
+ BOOL mbRestoreMaximize; // Restore-Maximize
+ BOOL mbInMoveMsg; // Move-Message wird verarbeitet
+ BOOL mbInSizeMsg; // Size-Message wird verarbeitet
+ BOOL mbFullScreenToolWin; // WS_EX_TOOLWINDOW reset in FullScreenMode
+ BOOL mbDefPos; // default-position
+ BOOL mbOverwriteState; // TRUE: WindowState darf umgesetzt werden
+ BOOL mbIME; // TRUE: We are in IME Mode
+ BOOL mbHandleIME; // TRUE: Wir handeln die IME-Messages
+ BOOL mbSpezIME; // TRUE: Spez IME
+ BOOL mbAtCursorIME; // TRUE: Wir behandeln nur einige IME-Messages
+ BOOL mbCompositionMode; // TRUE: Wir befinden uns im Composition-Modus
+ BOOL mbCandidateMode; // TRUE: Wir befinden uns im Candidate-Modus
+};
+
+#endif // _SV_SALFRAME_H
diff --git a/vcl/win/inc/salgdi.h b/vcl/win/inc/salgdi.h
new file mode 100644
index 000000000000..ef89bc3f1f7d
--- /dev/null
+++ b/vcl/win/inc/salgdi.h
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALGDI_H
+#define _SV_SALGDI_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#define RGB_TO_PALRGB(nRGB) ((nRGB)|0x02000000)
+#define PALRGB_TO_RGB(nPalRGB) ((nPalRGB)&0x00ffffff)
+
+// -------------------
+// - SalGraphicsData -
+// -------------------
+
+class SalGraphicsData
+{
+public:
+ HDC mhDC; // HDC
+ HWND mhWnd; // Window-Handle, when Window-Graphics
+ HPEN mhPen; // Pen
+ HBRUSH mhBrush; // Brush
+ HFONT mhFont; // Font
+ HRGN mhRegion; // Region Handle
+ HPEN mhDefPen; // DefaultPen
+ HBRUSH mhDefBrush; // DefaultBrush
+ HFONT mhDefFont; // DefaultFont
+ HPALETTE mhDefPal; // DefaultPalette
+ COLORREF mnPenColor; // PenColor
+ COLORREF mnBrushColor; // BrushColor
+ COLORREF mnTextColor; // TextColor
+ RGNDATA* mpClipRgnData; // ClipRegion-Data
+ RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data
+ RECT* mpNextClipRect; // Naechstes ClipRegion-Rect
+ BOOL mbFirstClipRect; // Flag for first cliprect to insert
+ LOGFONTA* mpLogFont; // LOG-Font which is currently selected (only W9x)
+ BYTE* mpFontCharSets; // All Charsets for the current font
+ BYTE mnFontCharSetCount; // Number of Charsets of the current font; 0 - if not queried
+ KERNINGPAIR* mpFontKernPairs; // Kerning Pairs of the current Font
+ ULONG mnFontKernPairCount;// Number of Kerning Pairs of the current Font
+ BOOL mbFontKernInit; // FALSE: FontKerns must be queried
+ int mnFontOverhang; // Font-Overhang
+ int mnPenWidth; // Linienbreite
+ BOOL mbStockPen; // is Pen a stockpen
+ BOOL mbStockBrush; // is Brush a stcokbrush
+ BOOL mbPen; // is Pen (FALSE == NULL_PEN)
+ BOOL mbBrush; // is Brush (FALSE == NULL_BRUSH)
+ BOOL mbPrinter; // is Printer
+ BOOL mbVirDev; // is VirDev
+ BOOL mbWindow; // is Window
+ BOOL mbScreen; // is Screen compatible
+ BOOL mbXORMode; // _every_ output with RasterOp XOR
+ BOOL mbCalcOverhang; // calc overhang
+};
+
+// Init/Deinit Graphics
+void ImplSalInitGraphics( SalGraphicsData* mpData );
+void ImplSalDeInitGraphics( SalGraphicsData* mpData );
+void ImplUpdateSysColorEntries();
+int ImplIsSysColorEntry( SalColor nSalColor );
+
+// -----------
+// - Defines -
+// -----------
+
+#ifdef WIN
+#define MAX_64KSALPOINTS ((((USHORT)0xFFFF)-4)/sizeof(POINT))
+#else
+#define MAX_64KSALPOINTS ((((USHORT)0xFFFF)-8)/sizeof(POINTS))
+#endif
+
+#endif // _SV_SALGDI_H
diff --git a/vcl/win/inc/salids.hrc b/vcl/win/inc/salids.hrc
new file mode 100644
index 000000000000..6caf4048b13a
--- /dev/null
+++ b/vcl/win/inc/salids.hrc
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * $RCSfile: salids.hrc,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALIDS_HRC
+#define _SV_SALIDS_HRC
+
+// Cursor
+#define SAL_RESID_POINTER_NULL 10000
+#ifndef W40ONLY
+#define SAL_RESID_POINTER_HELP 10001
+#endif
+#ifndef WNT
+#define SAL_RESID_POINTER_HSIZE 10002
+#define SAL_RESID_POINTER_VSIZE 10003
+#define SAL_RESID_POINTER_NESWSIZE 10004
+#define SAL_RESID_POINTER_NWSESIZE 10005
+#endif
+#define SAL_RESID_POINTER_CROSS 10006
+#define SAL_RESID_POINTER_MOVE 10007
+#define SAL_RESID_POINTER_HSPLIT 10008
+#define SAL_RESID_POINTER_VSPLIT 10009
+#define SAL_RESID_POINTER_HSIZEBAR 10010
+#define SAL_RESID_POINTER_VSIZEBAR 10011
+#define SAL_RESID_POINTER_HAND 10012
+#define SAL_RESID_POINTER_REFHAND 10013
+#define SAL_RESID_POINTER_PEN 10014
+#define SAL_RESID_POINTER_MAGNIFY 10015
+#define SAL_RESID_POINTER_FILL 10016
+#define SAL_RESID_POINTER_ROTATE 10017
+#define SAL_RESID_POINTER_HSHEAR 10018
+#define SAL_RESID_POINTER_VSHEAR 10019
+#define SAL_RESID_POINTER_MIRROR 10020
+#define SAL_RESID_POINTER_CROOK 10021
+#define SAL_RESID_POINTER_CROP 10022
+#define SAL_RESID_POINTER_MOVEPOINT 10023
+#define SAL_RESID_POINTER_MOVEBEZIERWEIGHT 10024
+#define SAL_RESID_POINTER_MOVEDATA 10025
+#define SAL_RESID_POINTER_COPYDATA 10026
+#define SAL_RESID_POINTER_LINKDATA 10027
+#define SAL_RESID_POINTER_MOVEDATALINK 10028
+#define SAL_RESID_POINTER_COPYDATALINK 10029
+#define SAL_RESID_POINTER_MOVEFILE 10030
+#define SAL_RESID_POINTER_COPYFILE 10031
+#define SAL_RESID_POINTER_LINKFILE 10032
+#define SAL_RESID_POINTER_MOVEFILELINK 10033
+#define SAL_RESID_POINTER_COPYFILELINK 10034
+#define SAL_RESID_POINTER_MOVEFILES 10035
+#define SAL_RESID_POINTER_COPYFILES 10036
+#define SAL_RESID_POINTER_NOTALLOWED 10037
+#define SAL_RESID_POINTER_DRAW_LINE 10038
+#define SAL_RESID_POINTER_DRAW_RECT 10039
+#define SAL_RESID_POINTER_DRAW_POLYGON 10040
+#define SAL_RESID_POINTER_DRAW_BEZIER 10041
+#define SAL_RESID_POINTER_DRAW_ARC 10042
+#define SAL_RESID_POINTER_DRAW_PIE 10043
+#define SAL_RESID_POINTER_DRAW_CIRCLECUT 10044
+#define SAL_RESID_POINTER_DRAW_ELLIPSE 10045
+#define SAL_RESID_POINTER_DRAW_FREEHAND 10046
+#define SAL_RESID_POINTER_DRAW_CONNECT 10047
+#define SAL_RESID_POINTER_DRAW_TEXT 10048
+#define SAL_RESID_POINTER_DRAW_CAPTION 10049
+#define SAL_RESID_POINTER_CHART 10050
+#define SAL_RESID_POINTER_DETECTIVE 10051
+#define SAL_RESID_POINTER_PIVOT_COL 10052
+#define SAL_RESID_POINTER_PIVOT_ROW 10053
+#define SAL_RESID_POINTER_PIVOT_FIELD 10054
+#define SAL_RESID_POINTER_CHAIN 10055
+#define SAL_RESID_POINTER_CHAIN_NOTALLOWED 10056
+#define SAL_RESID_POINTER_TIMEEVENT_MOVE 10057
+#define SAL_RESID_POINTER_TIMEEVENT_SIZE 10058
+#define SAL_RESID_POINTER_AUTOSCROLL_N 10059
+#define SAL_RESID_POINTER_AUTOSCROLL_S 10060
+#define SAL_RESID_POINTER_AUTOSCROLL_W 10061
+#define SAL_RESID_POINTER_AUTOSCROLL_E 10062
+#define SAL_RESID_POINTER_AUTOSCROLL_NW 10063
+#define SAL_RESID_POINTER_AUTOSCROLL_NE 10064
+#define SAL_RESID_POINTER_AUTOSCROLL_SW 10065
+#define SAL_RESID_POINTER_AUTOSCROLL_SE 10066
+#define SAL_RESID_POINTER_AUTOSCROLL_NS 10067
+#define SAL_RESID_POINTER_AUTOSCROLL_WE 10068
+#define SAL_RESID_POINTER_AUTOSCROLL_NSWE 10069
+#define SAL_RESID_POINTER_AIRBRUSH 10070
+
+#define SAL_RESID_BITMAP_50 11000
+
+#define SAL_RESID_ICON_DEFAULT 1
+
+#endif // _SV_SALIDS_HRC
diff --git a/vcl/win/inc/salinst.h b/vcl/win/inc/salinst.h
new file mode 100644
index 000000000000..23046d961e0b
--- /dev/null
+++ b/vcl/win/inc/salinst.h
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALINST_H
+#define _SV_SALINST_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+#ifdef _VOS_NO_NAMESPACE
+class OMutex;
+#else
+namespace vos { class OMutex; }
+#endif
+class SalYieldMutex;
+class SalInstance;
+class SalFrame;
+class SalObject;
+
+// -------------------
+// - SalInstanceData -
+// -------------------
+
+class SalInstanceData
+{
+public:
+ HINSTANCE mhInst; // Instance Handle
+ HWND mhComWnd; // window, for communication (between threads and the main thread)
+ void* mpFilterInst;
+ void* mpFilterCallback;
+ SalYieldMutex* mpSalYieldMutex; // Sal-Yield-Mutex
+#ifdef _VOS_NO_NAMESPACE
+ OMutex* mpSalWaitMutex; // Sal-Wait-Mutex
+#else
+ vos::OMutex* mpSalWaitMutex; // Sal-Wait-Mutex
+#endif
+ USHORT mnYieldWaitCount; // Wait-Count
+};
+
+// --------------
+// - Prototypen -
+// --------------
+
+SalFrame* ImplSalCreateFrame( SalInstance* pInst, HWND hWndParent, ULONG nSalFrameStyle );
+SalObject* ImplSalCreateObject( SalInstance* pInst, SalFrame* pParent );
+void ImplSalStartTimer( ULONG nMS, BOOL bMutex = FALSE );
+void ImplSalPrinterAbortJobAsync( HDC hPrnDC );
+
+#endif // _SV_SALINST_H
diff --git a/vcl/win/inc/salobj.h b/vcl/win/inc/salobj.h
new file mode 100644
index 000000000000..e32ba7e2d706
--- /dev/null
+++ b/vcl/win/inc/salobj.h
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * $RCSfile: salobj.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALOBJ_H
+#define _SV_SALOBJ_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+// -----------------
+// - SalObjectData -
+// -----------------
+
+class SalObjectData
+{
+public:
+ HWND mhWnd; // Window handle
+ HWND mhWndChild; // Child Window handle
+ HWND mhLastFocusWnd; // Child-Window, welches als letztes den Focus hatte
+ SystemChildData maSysData; // SystemEnvData
+ RGNDATA* mpClipRgnData; // ClipRegion-Data
+ RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data
+ RECT* mpNextClipRect; // Naechstes ClipRegion-Rect
+ BOOL mbFirstClipRect; // Flag for first cliprect to insert
+ SalObject* mpNextObject; // pointer to next object
+ void* mpInst; // instance handle for callback
+ SALOBJECTPROC mpProc; // callback proc
+};
+
+#endif // _SV_SALOBJ_H
diff --git a/vcl/win/inc/salogl.hxx b/vcl/win/inc/salogl.hxx
new file mode 100644
index 000000000000..f3b6d480eb7c
--- /dev/null
+++ b/vcl/win/inc/salogl.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * $RCSfile: salogl.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALOGL_HXX
+#define _SV_SALOGL_HXX
+
+#define _OPENGL_EXT
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _GEN_HXX
+#include <tools/gen.hxx>
+#endif
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+#ifndef _SV_SALOTYPE_HXX
+#include <salotype.hxx>
+#endif
+
+// -----------------
+// - State defines -
+// -----------------
+
+#define OGL_STATE_UNLOADED (0x00000000)
+#define OGL_STATE_INVALID (0x00000001)
+#define OGL_STATE_VALID (0x00000002)
+
+// -------------
+// - SalOpenGL -
+// -------------
+
+class SalGraphics;
+class String;
+
+class SalOpenGL
+{
+private:
+ static HGLRC mhOGLContext;
+ static HDC mhOGLLastDC;
+ static ULONG mnOGLState;
+
+private:
+ static BOOL ImplInitLib();
+ static BOOL ImplInit();
+ static void ImplFreeLib();
+
+public:
+ SalOpenGL( SalGraphics* pGraphics );
+ ~SalOpenGL();
+
+ static BOOL Create();
+ static void Release();
+ static ULONG GetState() { return SalOpenGL::mnOGLState; }
+ static BOOL IsValid() { return( OGL_STATE_VALID == SalOpenGL::mnOGLState ); }
+
+ static void* GetOGLFnc( const char* pFncName );
+
+ static void OGLEntry( SalGraphics* pGraphics );
+ static void OGLExit( SalGraphics* pGraphics );
+};
+
+#endif // _SV_SALOGL_HXX
diff --git a/vcl/win/inc/salprn.h b/vcl/win/inc/salprn.h
new file mode 100644
index 000000000000..6baca8eaf352
--- /dev/null
+++ b/vcl/win/inc/salprn.h
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * $RCSfile: salprn.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALPRN_H
+#define _SV_SALPRN_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+class SalGraphics;
+class SalInfoPrinter;
+
+// -----------------
+// - SalDriverData -
+// -----------------
+
+// WNT3
+#define SAL_DRIVERDATA_SYSSIGN ((ULONG)0x574E5433)
+#define SAL_DRIVERDATA_VERSION 1
+#define SAL_DEVMODE( pSetupData ) ((LPDEVMODE)((pSetupData->mpDriverData) + (((SalDriverData*)(pSetupData->mpDriverData))->mnDriverOffset)))
+
+#pragma pack( 1 )
+
+struct SalDriverData
+{
+ ULONG mnSysSignature;
+ USHORT mnVersion;
+ USHORT mnDriverOffset;
+ BYTE maDriverData[1];
+};
+
+#pragma pack()
+
+// -------------------
+// - SalSysQueueData -
+// -------------------
+
+struct SalSysQueueData
+{
+ XubString maDriverName; // printer driver name
+ XubString maDeviceName; // printer device name
+ XubString maPortName; // printer port name
+ ByteString maDriverNameA; // printer driver name
+ ByteString maDeviceNameA; // printer device name
+ ByteString maPortNameA; // printer port name
+ BOOL mbAnsi; // TRUE - use A functions
+};
+
+// ----------------------
+// - SalInfoPrinterData -
+// ----------------------
+
+class SalInfoPrinterData
+{
+public:
+ SalGraphics* mpGraphics; // current Printer graphics
+ XubString maDriverName; // printer driver name
+ XubString maDeviceName; // printer device name
+ XubString maPortName; // printer port name
+ ByteString maDriverNameA; // printer driver name
+ ByteString maDeviceNameA; // printer device name
+ ByteString maPortNameA; // printer port name
+ HDC mhDC; // printer hdc
+ BOOL mbGraphics; // is Graphics used
+ BOOL mbAnsi;
+};
+
+// ------------------
+// - SalPrinterData -
+// ------------------
+
+class SalPrinterData
+{
+public:
+ SalGraphics* mpGraphics; // current Printer graphics
+ SalInfoPrinter* mpInfoPrinter; // pointer to the compatible InfoPrinter
+ SalPrinter* mpNextPrinter; // next printing printer
+ HDC mhDC; // printer hdc
+ ULONG mnError; // Error Code
+ ULONG mnCopies; // Kopien
+ BOOL mbCollate; // Sortierte Kopien
+ BOOL mbAbort; // Job Aborted
+};
+
+#endif // _SV_SALPRN_H
diff --git a/vcl/win/inc/salsys.h b/vcl/win/inc/salsys.h
new file mode 100644
index 000000000000..ea1b99504c26
--- /dev/null
+++ b/vcl/win/inc/salsys.h
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * $RCSfile: salsys.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALSYS_H
+#define _SV_SALSYS_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+class SalFrame;
+
+// -----------------
+// - SalSystemData -
+// -----------------
+
+class SalSystemData
+{
+};
+
+#endif // _SV_SALSYS_H
diff --git a/vcl/win/inc/salvd.h b/vcl/win/inc/salvd.h
new file mode 100644
index 000000000000..33439dc618f0
--- /dev/null
+++ b/vcl/win/inc/salvd.h
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * $RCSfile: salvd.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SALVD_H
+#define _SV_SALVD_H
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+class SalGraphics;
+class SalVirtualDevice;
+
+// -----------------
+// - SalVirDevData -
+// -----------------
+
+class SalVirDevData
+{
+public:
+ HDC mhDC; // HDC or 0 for Cache Device
+ HBITMAP mhBmp; // Memory Bitmap
+ HBITMAP mhDefBmp; // Default Bitmap
+ SalGraphics* mpGraphics; // current VirDev graphics
+ SalVirtualDevice* mpNext; // next VirDev
+ USHORT mnBitCount; // BitCount (0 or 1)
+ BOOL mbGraphics; // is Graphics used
+};
+
+#endif // _SV_SALVD_H
diff --git a/vcl/win/inc/svsys.h b/vcl/win/inc/svsys.h
new file mode 100644
index 000000000000..6dec218faed3
--- /dev/null
+++ b/vcl/win/inc/svsys.h
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * $RCSfile: svsys.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_SVSYS_H
+#define _SV_SVSYS_H
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#endif // _SV_SVSYS_H
diff --git a/vcl/win/inc/wincomp.hxx b/vcl/win/inc/wincomp.hxx
new file mode 100644
index 000000000000..52c646f18c2d
--- /dev/null
+++ b/vcl/win/inc/wincomp.hxx
@@ -0,0 +1,453 @@
+/*************************************************************************
+ *
+ * $RCSfile: wincomp.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SV_WINCOMP_HXX
+#define _SV_WINCOMP_HXX
+
+#ifndef _STRING_H
+#include <string.h>
+#endif
+
+#ifndef _SV_SV_H
+#include <sv.h>
+#endif
+
+// ----------
+// - Strict -
+// ----------
+
+// Anpassungen fuer TypeChecking
+
+inline HPEN SelectPen( HDC hDC, HPEN hPen )
+{
+ return (HPEN)SelectObject( hDC, (HGDIOBJ)hPen );
+}
+
+inline void DeletePen( HPEN hPen )
+{
+ DeleteObject( (HGDIOBJ)hPen );
+}
+
+inline HPEN GetStockPen( int nObject )
+{
+ return (HPEN)GetStockObject( nObject );
+}
+
+inline HBRUSH SelectBrush( HDC hDC, HBRUSH hBrush )
+{
+ return (HBRUSH)SelectObject( hDC, (HGDIOBJ)hBrush );
+}
+
+inline void DeleteBrush( HBRUSH hBrush )
+{
+ DeleteObject( (HGDIOBJ)hBrush );
+}
+
+inline HBRUSH GetStockBrush( int nObject )
+{
+ return (HBRUSH)GetStockObject( nObject );
+}
+
+inline HFONT SelectFont( HDC hDC, HFONT hFont )
+{
+ return (HFONT)SelectObject( hDC, (HGDIOBJ)hFont );
+}
+
+inline void DeleteFont( HFONT hFont )
+{
+ DeleteObject( (HGDIOBJ)hFont );
+}
+
+inline HFONT GetStockFont( int nObject )
+{
+ return (HFONT)GetStockObject( nObject );
+}
+
+inline HBITMAP SelectBitmap( HDC hDC, HBITMAP hBitmap )
+{
+ return (HBITMAP)SelectObject( hDC, (HGDIOBJ)hBitmap );
+}
+
+inline void DeleteBitmap( HBITMAP hBitmap )
+{
+ DeleteObject( (HGDIOBJ)hBitmap );
+}
+
+inline void DeleteRegion( HRGN hRegion )
+{
+ DeleteObject( (HGDIOBJ)hRegion );
+}
+
+inline HPALETTE GetStockPalette( int nObject )
+{
+ return (HPALETTE)GetStockObject( nObject );
+}
+
+inline void DeletePalette( HPALETTE hPalette )
+{
+ DeleteObject( (HGDIOBJ)hPalette );
+}
+
+inline void SetWindowStyle( HWND hWnd, DWORD nStyle )
+{
+ SetWindowLong( hWnd, GWL_STYLE, nStyle );
+}
+
+inline DWORD GetWindowStyle( HWND hWnd )
+{
+ return GetWindowLong( hWnd, GWL_STYLE );
+}
+
+inline void SetWindowExStyle( HWND hWnd, DWORD nStyle )
+{
+ SetWindowLong( hWnd, GWL_EXSTYLE, nStyle );
+}
+
+inline DWORD GetWindowExStyle( HWND hWnd )
+{
+ return GetWindowLong( hWnd, GWL_EXSTYLE );
+}
+
+inline WIN_BOOL IsMinimized( HWND hWnd )
+{
+ return IsIconic( hWnd );
+}
+
+inline WIN_BOOL IsMaximized( HWND hWnd )
+{
+ return IsZoomed( hWnd );
+}
+
+inline void SetWindowFont( HWND hWnd, HFONT hFont, WIN_BOOL bRedraw )
+{
+ SendMessage( hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM((UINT)bRedraw,0) );
+}
+
+inline HFONT GetWindowFont( HWND hWnd )
+{
+ return (HFONT)(UINT)SendMessage( hWnd, WM_GETFONT, 0, 0 );
+}
+
+// ---------------------
+// - Windows/Window NT -
+// ---------------------
+
+// Anpassung fuer Unterschiede zwischen 3.x und NT
+
+inline void SetClassCursor( HWND hWnd, HCURSOR hCursor )
+{
+#ifndef WNT
+ SetClassWord( hWnd, GCW_HCURSOR, (WORD)hCursor );
+#else
+ SetClassLong( hWnd, GCL_HCURSOR, (DWORD)hCursor );
+#endif
+}
+
+inline HCURSOR GetClassCursor( HWND hWnd )
+{
+#ifndef WNT
+ return (HCURSOR)GetClassWord( hWnd, GCW_HCURSOR );
+#else
+ return (HCURSOR)GetClassLong( hWnd, GCL_HCURSOR );
+#endif
+}
+
+inline void SetClassIcon( HWND hWnd, HICON hIcon )
+{
+#ifndef WNT
+ SetClassWord( hWnd, GCW_HICON, (WORD)hIcon );
+#else
+ SetClassLong( hWnd, GCL_HICON, (DWORD)hIcon );
+#endif
+}
+
+inline HICON GetClassIcon( HWND hWnd )
+{
+#ifndef WNT
+ return (HICON)GetClassWord( hWnd, GCW_HICON );
+#else
+ return (HICON)GetClassLong( hWnd, GCL_HICON );
+#endif
+}
+
+inline HBRUSH SetClassBrush( HWND hWnd, HBRUSH hBrush )
+{
+#ifndef WNT
+ return (HBRUSH)SetClassWord( hWnd, GCW_HBRBACKGROUND, (WORD)hBrush );
+#else
+ return (HBRUSH)SetClassLong( hWnd, GCL_HBRBACKGROUND, (DWORD)hBrush );
+#endif
+}
+
+inline HBRUSH GetClassBrush( HWND hWnd )
+{
+#ifndef WNT
+ return (HBRUSH)GetClassWord( hWnd, GCW_HBRBACKGROUND );
+#else
+ return (HBRUSH)GetClassLong( hWnd, GCL_HBRBACKGROUND );
+#endif
+}
+
+inline HINSTANCE GetWindowInstance( HWND hWnd )
+{
+#ifndef WNT
+ return (HINSTANCE)GetWindowWord( hWnd, GWW_HINSTANCE );
+#else
+ return (HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE );
+#endif
+}
+
+#ifndef WNT
+inline UINT CharLowerBuff( LPSTR lpStr, UINT nLen )
+{
+ return AnsiLowerBuff( lpStr, nLen );
+}
+#endif
+
+#ifndef WNT
+inline UINT CharUpperBuff( LPSTR lpStr, UINT nLen )
+{
+ return AnsiUpperBuff( lpStr, nLen );
+}
+#endif
+
+#ifndef WNT
+inline void OemToChar( LPCSTR lpStr1, LPSTR lpStr2 )
+{
+ OemToAnsi( lpStr1, lpStr2 );
+}
+#endif
+
+
+// -----------------------------------
+// - Unterschiede zwischen 16/32-Bit -
+// -----------------------------------
+
+#ifdef WIN
+#define SVWINAPI WINAPI
+#else
+#define SVWINAPI APIENTRY
+#endif
+
+#ifdef WIN
+#define NEARDATA _near
+#else
+#define NEARDATA
+#endif
+
+// Zum kopieren von mehr als 64 KB
+#ifdef WIN
+inline void lmemcpy( void* pDst, const void* pSrc, ULONG nSize )
+{
+ hmemcpy( pDst, pSrc, nSize );
+}
+#else
+inline void lmemcpy( void* pDst, const void* pSrc, ULONG nSize )
+{
+ memcpy( pDst, pSrc, nSize );
+}
+#endif
+
+#ifdef WNT
+typedef LONG WinWeight;
+#else
+typedef int WinWeight;
+#endif
+
+
+// ----------------------------------------------------
+// - Steuerungen fuer Versionen und Laufzeit-Abfragen -
+// ----------------------------------------------------
+
+#if defined( WNT )
+#define W95_VERSION 400
+#else
+#define W95_VERSION 395
+#endif
+
+// Wenn eine 32-Bit SV Version die nur unter W95 laeuft gebildet werden soll,
+// muss nur dieses Define W40ONLY definiert werden
+#if ( WINVER >= 0x0400 )
+#define W40ONLY
+#endif
+
+// Wenn wir sowieso erst ab W95 laufen, brauchen wir auch keine
+// Laufzeit-Abfragen
+#ifdef W40ONLY
+#define W40IF
+#define W40NIF
+#define W40ELSE
+
+#else
+
+// Nur ein 32-Bit-SDK definiert WINVER >= 0x0400 und somit brauchen wir
+// diese W40-Abfragen auch nur hier. Die Abfragen, die sowohl fuer 3.1
+// als auch fuer NT gelten sind als normale if-Abfragen kodiert
+#ifdef WIN
+#define W40NIF
+#else
+#define W40IF if ( aSalShlData.mbW40 )
+#define W40NIF if ( !aSalShlData.mbW40 )
+#define W40ELSE else
+#endif
+
+#endif
+
+/****************************
+
+Beispiel fuer Klammerung:
+
+#if ( WINVER >= 0x0400 )
+ W40IF
+ {
+ ... W40-Code
+ }
+ W40ELSE
+#endif
+#ifndef W40ONLY
+ {
+ ... Normaler 3.1 und NT 3.5(1)-Code
+ }
+#endif
+
+*****************************/
+
+
+// ------------------------
+// - ZMouse Erweiterungen -
+// ------------------------
+
+#if defined( WNT )
+
+#ifdef UNICODE
+#define MSH_MOUSEWHEEL L"MSWHEEL_ROLLMSG"
+#else
+#define MSH_MOUSEWHEEL "MSWHEEL_ROLLMSG"
+#endif
+
+// Default value for rolling one notch
+#ifndef WHEEL_DELTA
+#define WHEEL_DELTA 120
+#endif
+
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x020A
+#endif
+
+#ifndef WHEEL_PAGESCROLL
+// signifies to scroll a page, also defined in winuser.h in the NT4.0 SDK
+#define WHEEL_PAGESCROLL (UINT_MAX)
+#endif
+
+#ifdef UNICODE
+#define MOUSEZ_CLASSNAME L"MouseZ" // wheel window class
+#define MOUSEZ_TITLE L"Magellan MSWHEEL" // wheel window title
+#else
+#define MOUSEZ_CLASSNAME "MouseZ" // wheel window class
+#define MOUSEZ_TITLE "Magellan MSWHEEL" // wheel window title
+#endif
+
+#define MSH_WHEELMODULE_CLASS (MOUSEZ_CLASSNAME)
+#define MSH_WHEELMODULE_TITLE (MOUSEZ_TITLE)
+
+#ifdef UNICODE
+#define MSH_SCROLL_LINES L"MSH_SCROLL_LINES_MSG"
+#else
+#define MSH_SCROLL_LINES "MSH_SCROLL_LINES_MSG"
+#endif
+
+#ifndef SPI_GETWHEELSCROLLLINES
+#define SPI_GETWHEELSCROLLLINES 104
+#endif
+#ifndef SPI_SETWHEELSCROLLLINES
+#define SPI_SETWHEELSCROLLLINES 105
+#endif
+
+#endif
+
+
+// -----------------------------
+// - SystemAgent Erweiterungen -
+// -----------------------------
+
+#if ( WINVER >= 0x0400 )
+#define ENABLE_AGENT 1
+#define DISABLE_AGENT 2
+#define GET_AGENT_STATUS 3
+
+typedef int (SVWINAPI* SysAgt_Enable_PROC)( int );
+#endif
+
+// ---------------------
+// - 5.0-Erweiterungen -
+// ---------------------
+
+#ifndef COLOR_HOTLIGHT
+#define COLOR_HOTLIGHT 26
+#endif
+#ifndef COLOR_GRADIENTACTIVECAPTION
+#define COLOR_GRADIENTACTIVECAPTION 27
+#endif
+#ifndef COLOR_GRADIENTINACTIVECAPTION
+#define COLOR_GRADIENTINACTIVECAPTION 28
+#endif
+
+#endif // _SV_WINCOMP_HXX
diff --git a/vcl/win/source/app/MAKEFILE.MK b/vcl/win/source/app/MAKEFILE.MK
new file mode 100644
index 000000000000..f53f534b69a1
--- /dev/null
+++ b/vcl/win/source/app/MAKEFILE.MK
@@ -0,0 +1,40 @@
+#*************************************************************************
+#*
+#* $Workfile: makefile. $
+#*
+#* Ersterstellung TH 01.04.97
+#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:49 $
+#* $Revision: 1.1.1.1 $
+#*
+#* $Logfile: T:/sv2/win/source/app/makefile.__v $
+#*
+#* Copyright (c) 1990 - 2000, STAR DIVISION
+#*
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salapp
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= $(OBJ)$/salmain.obj
+
+SLOFILES= $(SLO)$/salshl.obj \
+ $(SLO)$/saldata.obj \
+ $(SLO)$/salinst.obj \
+ $(SLO)$/saltimer.obj \
+ $(SLO)$/salsound.obj \
+ $(SLO)$/salinfo.obj \
+ $(SLO)$/salsys.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/win/source/app/saldata.cxx b/vcl/win/source/app/saldata.cxx
new file mode 100644
index 000000000000..7142badf3a20
--- /dev/null
+++ b/vcl/win/source/app/saldata.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldata.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALDATA_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+
+// =======================================================================
+
+rtl_TextEncoding ImplSalGetSystemEncoding()
+{
+ static UINT nOldAnsiCodePage = 0;
+ static rtl_TextEncoding eEncoding = RTL_TEXTENCODING_MS_1252;
+
+ UINT nAnsiCodePage = GetACP();
+ if ( nAnsiCodePage != nOldAnsiCodePage )
+ {
+ switch ( nAnsiCodePage )
+ {
+ case 1252:
+ eEncoding = RTL_TEXTENCODING_MS_1252;
+ break;
+ case 1250:
+ eEncoding = RTL_TEXTENCODING_MS_1250;
+ break;
+ case 1251:
+ eEncoding = RTL_TEXTENCODING_MS_1251;
+ break;
+ case 1253:
+ eEncoding = RTL_TEXTENCODING_MS_1253;
+ break;
+ case 1254:
+ eEncoding = RTL_TEXTENCODING_MS_1254;
+ break;
+ case 1255:
+ eEncoding = RTL_TEXTENCODING_MS_1255;
+ break;
+ case 1256:
+ eEncoding = RTL_TEXTENCODING_MS_1256;
+ break;
+ case 1257:
+ eEncoding = RTL_TEXTENCODING_MS_1257;
+ break;
+ case 1258:
+ eEncoding = RTL_TEXTENCODING_MS_1258;
+ break;
+ case 874:
+ eEncoding = RTL_TEXTENCODING_MS_874;
+ break;
+ case 932:
+ eEncoding = RTL_TEXTENCODING_MS_932;
+ break;
+ case 936:
+ eEncoding = RTL_TEXTENCODING_MS_936;
+ break;
+ case 949:
+ eEncoding = RTL_TEXTENCODING_MS_949;
+ break;
+ case 950:
+ eEncoding = RTL_TEXTENCODING_MS_950;
+ break;
+// case 1381:
+// eEncoding = RTL_TEXTENCODING_MS_1381;
+// break;
+ }
+ }
+
+ return eEncoding;
+}
+
+// -----------------------------------------------------------------------
+
+ByteString ImplSalGetWinAnsiString( const UniString& rStr, BOOL bFileName )
+{
+ rtl_TextEncoding eEncoding = ImplSalGetSystemEncoding();
+ if ( bFileName )
+ {
+ return ByteString( rStr, eEncoding,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 );
+ }
+ else
+ {
+ return ByteString( rStr, eEncoding,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+UniString ImplSalGetUniString( const sal_Char* pStr, xub_StrLen nLen )
+{
+ return UniString( pStr, nLen, ImplSalGetSystemEncoding(),
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT );
+}
+
+// =======================================================================
+
+int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 )
+{
+ int nRet;
+ wchar_t c1;
+ char c2;
+ do
+ {
+ // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
+ c1 = *pStr1;
+ c2 = *pStr2;
+ if ( (c1 >= 65) && (c1 <= 90) )
+ c1 += 32;
+ if ( (c2 >= 65) && (c2 <= 90) )
+ c2 += 32;
+ nRet = ((sal_Int32)c1)-((sal_Int32)((unsigned char)c2));
+ if ( nRet != 0 )
+ break;
+
+ pStr1++;
+ pStr2++;
+ }
+ while ( c2 );
+
+ return nRet;
+}
+
+// =======================================================================
+
+LONG ImplSetWindowLong( HWND hWnd, int nIndex, DWORD dwNewLong )
+{
+ if ( aSalShlData.mbWNT )
+ return SetWindowLongW( hWnd, nIndex, dwNewLong );
+ else
+ return SetWindowLongA( hWnd, nIndex, dwNewLong );
+}
+
+// -----------------------------------------------------------------------
+
+LONG ImplGetWindowLong( HWND hWnd, int nIndex )
+{
+ if ( aSalShlData.mbWNT )
+ return GetWindowLongW( hWnd, nIndex );
+ else
+ return GetWindowLongA( hWnd, nIndex );
+}
+
+// -----------------------------------------------------------------------
+
+WIN_BOOL ImplPostMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ if ( aSalShlData.mbWNT )
+ return PostMessageW( hWnd, nMsg, wParam, lParam );
+ else
+ return PostMessageA( hWnd, nMsg, wParam, lParam );
+}
+
+// -----------------------------------------------------------------------
+
+WIN_BOOL ImplSendMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ if ( aSalShlData.mbWNT )
+ return SendMessageW( hWnd, nMsg, wParam, lParam );
+ else
+ return SendMessageA( hWnd, nMsg, wParam, lParam );
+}
+
+// -----------------------------------------------------------------------
+
+WIN_BOOL ImplGetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax )
+{
+ if ( aSalShlData.mbWNT )
+ return GetMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax );
+ else
+ return GetMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax );
+}
+
+// -----------------------------------------------------------------------
+
+WIN_BOOL ImplPeekMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg )
+{
+ if ( aSalShlData.mbWNT )
+ return PeekMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg );
+ else
+ return PeekMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg );
+}
+
+// -----------------------------------------------------------------------
+
+LONG ImplDispatchMessage( CONST MSG *lpMsg )
+{
+ if ( aSalShlData.mbWNT )
+ return DispatchMessageW( lpMsg );
+ else
+ return DispatchMessageA( lpMsg );
+}
+
diff --git a/vcl/win/source/app/salinfo.cxx b/vcl/win/source/app/salinfo.cxx
new file mode 100644
index 000000000000..97a3b0c97e35
--- /dev/null
+++ b/vcl/win/source/app/salinfo.cxx
@@ -0,0 +1,884 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinfo.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef ENABLEUNICODE
+
+#define VCL_NEED_BASETSD
+
+#include <tools/presys.h>
+#include <windows.h>
+#include <imagehlp.h>
+#include <tools/postsys.h>
+
+#include <salsys.hxx>
+
+/* !!! UNICODE !!! */
+XubString SalSystem::GetSummarySystemInfos( ULONG nFlags )
+{
+ return XubString();
+}
+
+#else
+
+#define VCL_NEED_BASETSD
+
+#include <tools/presys.h>
+#include <windows.h>
+#include <imagehlp.h>
+#include <tools/postsys.h>
+
+#include <stdio.h>
+#include <tools/string.hxx>
+#include <salsys.hxx>
+
+// Wegen Stacktrace-Generierung
+#pragma optimize ("", off)
+
+// #include <tlhelp32.h>
+// ToolHelp32
+#define MAX_MODULE_NAME32 255
+#define TH32CS_SNAPMODULE 0x00000008
+
+typedef struct tagMODULEENTRY32
+{
+ DWORD dwSize;
+ DWORD th32ModuleID; // This module
+ DWORD th32ProcessID; // owning process
+ DWORD GlblcntUsage; // Global usage count on the module
+ DWORD ProccntUsage; // Module usage count in th32ProcessID's context
+ BYTE * modBaseAddr; // Base address of module in th32ProcessID's context
+ DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr
+ HMODULE hModule; // The hModule of this module in th32ProcessID's context
+ char szModule[MAX_MODULE_NAME32 + 1];
+ char szExePath[MAX_PATH];
+} MODULEENTRY32;
+typedef MODULEENTRY32 * PMODULEENTRY32;
+typedef MODULEENTRY32 * LPMODULEENTRY32;
+
+// PSAPI functions - Windows NT only
+typedef struct _MODULEINFO {
+ LPVOID lpBaseOfDll;
+ DWORD SizeOfImage;
+ LPVOID EntryPoint;
+} MODULEINFO, *LPMODULEINFO;
+
+
+
+// PSAPI
+typedef BOOL (WINAPI *ENUMPROCESSMODULESPROC)( HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded );
+typedef BOOL (WINAPI *GETMODULEINFORMATIONPROC)( HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb );
+typedef DWORD (WINAPI *GETMODULEBASENAMEAPROC)( HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize );
+typedef DWORD (WINAPI *GETMODULEFILENAMEEXAPROC)( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize );
+typedef HANDLE (WINAPI *CREATESNAPSHOTPROC)(DWORD dwFlags, DWORD th32ProcessID);
+typedef BOOL (WINAPI *MODULE32FIRSTPROC)( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
+typedef BOOL (WINAPI *MODULE32NEXTPROC)( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
+
+
+// ImageHlp
+typedef int (__stdcall *STACKWALKPROC) ( DWORD, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE,PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE );
+typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)( HANDLE, DWORD );
+typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)( HANDLE, DWORD );
+typedef DWORD (__stdcall *SYMSETOPTIONSPROC ) (DWORD dwSymOptions);
+typedef int (__stdcall *SYMINITIALIZEPROC ) ( HANDLE, LPSTR, int );
+typedef int (__stdcall *SYMCLEANUPPROC)( HANDLE );
+typedef DWORD (__stdcall WINAPI *UNDECORATESYMBOLNAMEPROC)( PCSTR, PSTR, DWORD, DWORD );
+typedef DWORD (__stdcall *SYMLOADMODULEPROC) ( HANDLE, HANDLE, LPSTR, LPSTR, DWORD, DWORD );
+typedef int (__stdcall *SYMGETSYMFROMADDR)( HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL );
+
+
+struct ModuleInfo
+{
+ struct ModuleInfo* pNext;
+
+ char szModBaseName[MAX_PATH];
+ char szModFileName[MAX_PATH];
+ unsigned long nBaseAddress;
+ unsigned long nSize;
+// unsigned long nEntryPoint;
+// HANDLE nHandle;
+// PIMAGE_DEBUG_INFORMATION pDebugInfos;
+};
+
+struct ModuleInfo* FindModuleContainingAddress( struct ModuleInfo* pStart, void* pAddr );
+
+
+
+struct SystemInfos
+{
+ DWORD nCurrentProcessId;
+ HANDLE hCurrentProcess;
+ DWORD nCurrentThreadId;
+ HANDLE hCurrentThread;
+
+ ModuleInfo* pModInfos;
+
+ String aStack;
+ String aModules;
+ String aSystemVersion;
+ String aCPUType;
+ String aMemoryInfo;
+ String aLocalVolumes;
+ String aSystemDirs;
+ String aMouseInfo;
+
+ SystemInfos()
+ {
+ nCurrentProcessId = 0;
+ hCurrentProcess = 0;
+ hCurrentThread = 0;
+ pModInfos = NULL;
+ }
+};
+
+void DebugThread( SystemInfos* pSysInfos );
+
+
+typedef struct _Thread
+{
+ DWORD dwThreadId;
+ HANDLE hThread;
+} Thread;
+
+
+struct ModuleInfo* WNT_CreateModuleInfos();
+
+String ImplCreateToken( const String& rToken )
+{
+ String aToken( '<' );
+ aToken += rToken;
+ aToken += ' ';
+ while ( aToken.Len() < 25 )
+ aToken += '-';
+ aToken += '>';
+ return aToken;
+}
+
+
+
+String WNT_CreateModulePath( struct ModuleInfo* pModInfos )
+{
+ String aPath;
+ struct ModuleInfo* pM = pModInfos;
+ while ( pM )
+ {
+ String aTmpPath = pM->szModFileName;
+ USHORT n = aTmpPath.SearchBackward( '\\' );
+ if ( n != STRING_NOTFOUND )
+ aTmpPath.Erase( n );
+ aTmpPath += ';';
+ aTmpPath.ToLower();
+ if ( aPath.Search( aTmpPath ) == STRING_NOTFOUND )
+ aPath += aTmpPath;
+
+ pM = pM->pNext;
+ }
+ return aPath;
+}
+
+
+struct ModuleInfo* WNT_CreateModuleInfos()
+{
+ struct ModuleInfo* pModInfos = NULL;
+
+ OSVERSIONINFO aOSVersion;
+ aOSVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+ if ( GetVersionEx( &aOSVersion ) )
+ {
+ if ( aOSVersion.dwPlatformId == VER_PLATFORM_WIN32_NT )
+ {
+ HINSTANCE hPSAPILib = LoadLibrary( "PSAPI.DLL" );
+ if( hPSAPILib )
+ {
+ ENUMPROCESSMODULESPROC _fpEnumProcessModules = (ENUMPROCESSMODULESPROC) GetProcAddress( hPSAPILib, "EnumProcessModules" );
+ GETMODULEINFORMATIONPROC _fpGetModuleInformation = (GETMODULEINFORMATIONPROC) GetProcAddress( hPSAPILib, "GetModuleInformation" );
+ GETMODULEBASENAMEAPROC _fpGetModuleBaseNameA = (GETMODULEBASENAMEAPROC) GetProcAddress( hPSAPILib, "GetModuleBaseNameA" );
+ GETMODULEFILENAMEEXAPROC _fpGetModuleFileNameExA = (GETMODULEFILENAMEEXAPROC) GetProcAddress( hPSAPILib, "GetModuleFileNameExA" );
+
+ HANDLE hProcess = GetCurrentProcess();
+ HMODULE hMods[1024];
+ DWORD cbNeeded;
+ if( _fpEnumProcessModules( hProcess, hMods, sizeof(hMods), &cbNeeded ) )
+ {
+ int nMods = cbNeeded / sizeof( HMODULE );
+ int nArrSz = nMods * sizeof( struct ModuleInfo );
+ pModInfos = (struct ModuleInfo*) malloc( nArrSz );
+ memset( pModInfos, 0, nArrSz );
+
+ for ( int i = 0; i < nMods; i++ )
+ {
+ pModInfos[i].pNext = 0;
+ if ( i )
+ pModInfos[i-1].pNext = &pModInfos[i];
+
+ _fpGetModuleBaseNameA( hProcess, hMods[i], pModInfos[i].szModBaseName, sizeof( pModInfos[i].szModBaseName ) );
+ _fpGetModuleFileNameExA( hProcess, hMods[i], pModInfos[i].szModFileName, sizeof( pModInfos[i].szModFileName ) );
+
+ MODULEINFO aInf;
+ if ( _fpGetModuleInformation( hProcess, hMods[i], &aInf, sizeof( aInf ) ) )
+ {
+ pModInfos[i].nBaseAddress = (unsigned long) aInf.lpBaseOfDll;
+ pModInfos[i].nSize = aInf.SizeOfImage;
+ // pModInfos[i].nEntryPoint = (unsigned long) aInf.EntryPoint;
+ }
+ }
+ }
+ FreeLibrary( hPSAPILib );
+ }
+ }
+ else if ( aOSVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
+ {
+ HINSTANCE hToolHelpLib = LoadLibrary( "KERNEL32.DLL" );
+ if( hToolHelpLib )
+ {
+ CREATESNAPSHOTPROC _fpCreateSnapshot = (CREATESNAPSHOTPROC) GetProcAddress( hToolHelpLib, "CreateToolhelp32Snapshot" );
+ MODULE32FIRSTPROC _fpModule32First = (MODULE32FIRSTPROC) GetProcAddress( hToolHelpLib, "Module32First" );
+ MODULE32NEXTPROC _fpModule32Next = (MODULE32NEXTPROC) GetProcAddress( hToolHelpLib, "Module32Next" );
+
+ HANDLE hSnap = _fpCreateSnapshot( TH32CS_SNAPMODULE, 0 );
+ if ( hSnap )
+ {
+ MODULEENTRY32 aMod32Entry;
+ ZeroMemory( &aMod32Entry, sizeof( MODULEENTRY32 ) );
+ aMod32Entry.dwSize = sizeof( MODULEENTRY32 );
+ int nMods = 0;
+ BOOL bMod = _fpModule32First( hSnap, &aMod32Entry );
+ while ( bMod )
+ {
+ nMods++;
+ bMod = _fpModule32Next( hSnap, &aMod32Entry );
+ }
+
+ int nArrSz = nMods * sizeof( struct ModuleInfo );
+ pModInfos = (struct ModuleInfo*) malloc( nArrSz );
+ memset( pModInfos, 0, nArrSz );
+
+ int nMod = 0;
+ bMod = _fpModule32First( hSnap, &aMod32Entry );
+ while ( bMod )
+ {
+ pModInfos[nMod].pNext = 0;
+ if ( nMod )
+ pModInfos[nMod-1].pNext = &pModInfos[nMod];
+
+ strcpy( pModInfos[nMod].szModBaseName, aMod32Entry.szModule );
+ strcpy( pModInfos[nMod].szModFileName, aMod32Entry.szExePath );
+ pModInfos[nMod].nBaseAddress = (unsigned long) aMod32Entry.modBaseAddr;
+ pModInfos[nMod].nSize = aMod32Entry.modBaseSize;
+// pModInfos[nMod].nEntryPoint = 0xFFFFFFFF;
+
+ bMod = _fpModule32Next( hSnap, &aMod32Entry );
+ nMod++;
+ }
+
+ CloseHandle( hSnap );
+ }
+
+ FreeLibrary( hToolHelpLib );
+ }
+ }
+ }
+ return pModInfos;
+}
+
+BOOL WNT_GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset )
+{
+ MEMORY_BASIC_INFORMATION mbi;
+
+ if( VirtualQuery( addr, &mbi, sizeof(mbi) ) && mbi.AllocationBase )
+ {
+ DWORD hMod = (DWORD)mbi.AllocationBase;
+
+ if ( !GetModuleFileName( (HMODULE)hMod, szModule, len ) )
+ return FALSE;
+
+ // Point to the DOS header in memory
+ PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
+
+ // From the DOS header, find the NT (PE) header
+ PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew);
+
+ PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
+
+ DWORD rva = (DWORD)addr - hMod; // RVA is offset from module load address
+
+ // Iterate through the section table, looking for the one that encompasses
+ // the linear address.
+ for ( unsigned i = 0;
+ i < pNtHdr->FileHeader.NumberOfSections;
+ i++, pSection++ )
+ {
+ DWORD sectionStart = pSection->VirtualAddress;
+ DWORD sectionEnd = sectionStart
+ + max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
+
+ // Is the address in this section???
+ if ( (rva >= sectionStart) && (rva <= sectionEnd) )
+ {
+ // Yes, address is in the section. Calculate section and offset,
+ // and store in the "section" & "offset" params, which were
+ // passed by reference.
+ section = i+1;
+ offset = rva - sectionStart;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+struct ModuleInfo* FindModuleContainingAddress( struct ModuleInfo* pStart, void* pAddr )
+{
+ struct ModuleInfo* pRet = NULL;
+ struct ModuleInfo* pM = pStart;
+ unsigned long nAddr = (unsigned long) pAddr;
+
+ while ( pM && !pRet )
+ {
+ if ( ( nAddr >= pM->nBaseAddress ) &&
+ ( nAddr < ( pM->nBaseAddress + pM->nSize ) ) )
+ {
+ pRet = pM;
+ }
+ else
+ {
+ pM = pM->pNext;
+ }
+ }
+ return pRet;
+}
+
+String _OLD_GetStackInfo()
+{
+ // Try an other way...
+ String aTmpStack;
+ ModuleInfo* pMods = WNT_CreateModuleInfos();
+
+ ULONG* pBP;
+ __asm mov pBP, ebp;
+ char buffer[1024];
+
+ for ( int i = 0; i < 15; i++ )
+ {
+ ULONG nIP = pBP[1];
+ sprintf( buffer, "[%.2u] IP=%.8lx", i, nIP );
+ aTmpStack += buffer;
+
+ ModuleInfo* pI = FindModuleContainingAddress( pMods, (void*)nIP );
+ if ( pI )
+ {
+ sprintf( buffer, " (Rel=%.8lx) [%s, Base=%.8lx, Path=%s]", nIP-pI->nBaseAddress-0x1000, pI->szModBaseName, pI->nBaseAddress, pI->szModFileName );
+ aTmpStack += buffer;
+ }
+
+ if ( !pI || (pBP[0] & 3) || (ULONG)pBP > pBP[0] )
+ {
+ aTmpStack += "\nError!\n";
+ break;
+ }
+
+ aTmpStack += '\n';
+ pBP = (ULONG*) pBP[0];
+ }
+
+ // Modul-Infos zerstoeren...
+ return aTmpStack;
+}
+
+String SalSystem::GetSummarySystemInfos( ULONG nFlags)
+{
+ SystemInfos aSysInfos;
+ HANDLE nCurrentThreadPseudo = GetCurrentThread();
+ HANDLE nCurrentProcessPseudo = GetCurrentProcess();
+ aSysInfos.nCurrentThreadId = GetCurrentThreadId();
+ DuplicateHandle( nCurrentProcessPseudo, nCurrentThreadPseudo, nCurrentProcessPseudo,
+ &aSysInfos.hCurrentThread, PROCESS_ALL_ACCESS, TRUE, 0 );
+ aSysInfos.nCurrentProcessId = GetCurrentProcessId();
+ DuplicateHandle( nCurrentProcessPseudo, nCurrentProcessPseudo, nCurrentProcessPseudo,
+ &aSysInfos.hCurrentProcess, PROCESS_ALL_ACCESS, TRUE, 0 );
+
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_STACK )
+ {
+ DWORD nDebugThreadId;
+ HANDLE hDebugThread = CreateThread(
+ NULL, 16000,
+ (LPTHREAD_START_ROUTINE)DebugThread, &aSysInfos,
+ 0, &nDebugThreadId );
+
+ WaitForSingleObject( hDebugThread, INFINITE );
+ CloseHandle( hDebugThread );
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_MODULES )
+ {
+ aSysInfos.aModules = "<Modules>\n";
+ char buffer[1024];
+ if ( !aSysInfos.pModInfos )
+ aSysInfos.pModInfos = WNT_CreateModuleInfos();
+ struct ModuleInfo* pM = aSysInfos.pModInfos;
+ while ( pM )
+ {
+ aSysInfos.aModules += " <Module name=\"";
+ aSysInfos.aModules += pM->szModBaseName;
+ aSysInfos.aModules += "\" path=\"";
+ aSysInfos.aModules += pM->szModFileName;
+ aSysInfos.aModules += "\" >\n";
+ aSysInfos.aModules += " <ModuleInfo name=\"BASE\" value=\"";
+ sprintf( buffer, "%.8lx", pM->nBaseAddress );
+ aSysInfos.aModules += buffer;
+ aSysInfos.aModules += "\" />\n";
+ aSysInfos.aModules += " <ModuleInfo name=\"Size\" value=\"";
+ aSysInfos.aModules += pM->nSize;
+ aSysInfos.aModules += "\" />\n </Module>\n";
+ pM = pM->pNext;
+ }
+ aSysInfos.aModules += "</Modules>";
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_SYSTEMVERSION )
+ {
+ aSysInfos.aSystemVersion = "<System name=\"";
+ OSVERSIONINFO aVersionInfos;
+ memset(&aVersionInfos, 0, sizeof( OSVERSIONINFO ) );
+ aVersionInfos.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+ GetVersionEx( &aVersionInfos );
+ if ( aVersionInfos.dwPlatformId == VER_PLATFORM_WIN32s )
+ aSysInfos.aSystemVersion += "Microsoft Win32s";
+ else if ( aVersionInfos.dwPlatformId == VER_PLATFORM_WIN32_NT )
+ aSysInfos.aSystemVersion += "Microsoft Windows NT";
+ else if ( aVersionInfos.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
+ {
+ if ( !aVersionInfos.dwMinorVersion )
+ aSysInfos.aSystemVersion += "Microsoft Windows 95";
+ else
+ aSysInfos.aSystemVersion += "Microsoft Windows 98";
+ }
+ else
+ aSysInfos.aSystemVersion += "Unknown Windows";
+ aSysInfos.aSystemVersion += "\" version=\"";
+ aSysInfos.aSystemVersion += aVersionInfos.dwMajorVersion;
+ aSysInfos.aSystemVersion += '.';
+ aSysInfos.aSystemVersion += aVersionInfos.dwMinorVersion;
+ aSysInfos.aSystemVersion += "\" build=\"";
+ aSysInfos.aSystemVersion += aVersionInfos.dwBuildNumber&0xFFFF;
+ aSysInfos.aSystemVersion += "\" />";
+
+ // aSysInfos.aSystemVersion += aVersionInfos.szCSDVersion;
+ /*
+ Under both Windows NT and Windows 95, you can get the
+ language information in the FileVersionInfo of User.exe by
+ calling GetFileVersionInfo, and then
+ VerQueryValue (on \\VarFileInfo\\Translation") on the
+ VersionInfo block of the operating system's User.exe.
+ NOTE: This method is the most reliable. It works well under
+ both Windows NT and Windows 95. This method also works for
+ Windows 3.1
+ */
+// DWORD nDefInputLanguage;
+// if ( SystemParametersInfo( SPI_GETDEFAULTINPUTLANG, 0, &nDefInputLanguage, 0 ) )
+// {
+// aSysInfos.aSystemVersion += " default input language = ";
+// aSysInfos.aSystemVersion += nDefInputLanguage;
+// }
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_CPUTYPE )
+ {
+ SYSTEM_INFO aSystemInfo;
+ memset( &aSystemInfo, 0, sizeof( SYSTEM_INFO ) );
+ GetSystemInfo( &aSystemInfo );
+ aSysInfos.aCPUType = "<CPU count=\"";
+ aSysInfos.aCPUType += aSystemInfo.dwNumberOfProcessors;
+ aSysInfos.aCPUType += "\" type=\"";
+ if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
+ aSysInfos.aCPUType += "X86";
+ else if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
+ aSysInfos.aCPUType += "MIPS";
+ else if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
+ aSysInfos.aCPUType += "ALPHA";
+ else if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
+ aSysInfos.aCPUType += "PPC";
+ else
+ aSysInfos.aCPUType += "unknown";
+ aSysInfos.aCPUType += "\"></CPU>";
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_MEMORYINFO )
+ {
+ MEMORYSTATUS aMemStatus;
+ memset( &aMemStatus, 0, sizeof( MEMORYSTATUS ) );
+ GlobalMemoryStatus( &aMemStatus );
+ aSysInfos.aMemoryInfo = "<Memory>\n";
+ aSysInfos.aMemoryInfo += " <MemoryType name=\"Physical\" total=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwTotalPhys+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" free=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwAvailPhys+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" />\n";
+ aSysInfos.aMemoryInfo += " <MemoryType name=\"Swap\" total=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwTotalPageFile+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" free=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwAvailPageFile+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" />\n";
+ aSysInfos.aMemoryInfo += " <MemoryType name=\"Virtual\" total=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwTotalVirtual+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" free=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwAvailVirtual+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" />\n";
+ aSysInfos.aMemoryInfo += "</Memory>";
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_LOCALVOLUMES )
+ {
+ aSysInfos.aLocalVolumes = "<LocalVolumes>\n";
+ char aDriveStrings[4096];
+ GetLogicalDriveStrings( 4096, aDriveStrings );
+ LPTSTR pDriveStr = aDriveStrings;
+ while ( *pDriveStr )
+ {
+ UINT nType = GetDriveType( pDriveStr );
+ if ( nType != DRIVE_REMOTE )
+ {
+ aSysInfos.aLocalVolumes += " <LocalVolume type=\"";
+
+ switch ( nType )
+ {
+ case DRIVE_REMOVABLE: aSysInfos.aLocalVolumes += "Removable"; break;
+ case DRIVE_FIXED: aSysInfos.aLocalVolumes += "Fixed"; break;
+ case DRIVE_REMOTE: aSysInfos.aLocalVolumes += "Remote"; break;
+ case DRIVE_CDROM: aSysInfos.aLocalVolumes += "CD-ROM"; break;
+ case DRIVE_RAMDISK: aSysInfos.aLocalVolumes += "RAM disk"; break;
+ default: aSysInfos.aLocalVolumes += "Unkown";
+ }
+ aSysInfos.aLocalVolumes += "\" path=\"";
+ aSysInfos.aLocalVolumes += pDriveStr;
+ aSysInfos.aLocalVolumes += "\"";
+ if( nType == DRIVE_FIXED )
+ {
+ DWORD nSectorsPerCluster;
+ DWORD nBytesPerSector;
+ DWORD nNumberFreeClusters;
+ DWORD nNumberTotalClusters;
+ if( GetDiskFreeSpace( pDriveStr, &nSectorsPerCluster, &nBytesPerSector, &nNumberFreeClusters, &nNumberTotalClusters ) )
+ {
+ DWORD nUnitsPerCluster = nSectorsPerCluster*nBytesPerSector;
+ DWORD nUnitDivi = 1;
+ String aUnit = "bytes";
+ if( ( nUnitsPerCluster % 1024 ) == 0 )
+ {
+ aUnit = "KB";
+ nUnitsPerCluster /= 1024;
+ }
+ else if( ( nUnitsPerCluster % 512 ) == 0 )
+ {
+ aUnit = "KB";
+ nUnitDivi = 1024;
+ }
+ DWORD nFree = nNumberFreeClusters*nUnitsPerCluster/nUnitDivi;
+ aSysInfos.aLocalVolumes += " free=\"";
+ aSysInfos.aLocalVolumes += nFree;
+ aSysInfos.aLocalVolumes += ' ';
+ aSysInfos.aLocalVolumes += aUnit;
+ aSysInfos.aLocalVolumes += "\"";
+ }
+ }
+ aSysInfos.aLocalVolumes += " />\n";
+ }
+ while ( *pDriveStr )
+ pDriveStr++;
+ pDriveStr++;
+ }
+ aSysInfos.aLocalVolumes += "</LocalVolumes>";
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_SYSTEMDIRS )
+ {
+ aSysInfos.aSystemDirs = "<SystemDirs>\n";
+ char buffer[ MAX_PATH ];
+ aSysInfos.aSystemDirs += " <SystemDir envname=\"Windows\" path=\"";
+ if( GetWindowsDirectory( buffer, MAX_PATH ) )
+ aSysInfos.aSystemDirs += buffer;
+ aSysInfos.aSystemDirs += "\" />\n";
+
+ aSysInfos.aSystemDirs += " <SystemDir envname=\"System\" path=\"";
+ if( GetSystemDirectory( buffer, MAX_PATH ) )
+ aSysInfos.aSystemDirs += buffer;
+ aSysInfos.aSystemDirs += "\" />\n";
+
+ aSysInfos.aSystemDirs += " <SystemDir envname=\"Current\" path=\"";
+ if( GetCurrentDirectory( MAX_PATH, buffer ) )
+ aSysInfos.aSystemDirs += buffer;
+ aSysInfos.aSystemDirs += "\" />\n";
+
+ aSysInfos.aSystemDirs += " <SystemDir envname=\"Temp\" path=\"";
+ if( GetTempPath( MAX_PATH, buffer ) )
+ aSysInfos.aSystemDirs += buffer;
+ aSysInfos.aSystemDirs += "\" />\n";
+ aSysInfos.aSystemDirs += "</SystemDirs>";
+
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_MOUSEINFO )
+ {
+ aSysInfos.aMouseInfo = "<Mouse ";
+ int nRet = GetSystemMetrics( SM_CMOUSEBUTTONS );
+ if ( nRet )
+ {
+ aSysInfos.aMouseInfo += "buttons=\"";
+ aSysInfos.aMouseInfo += nRet;
+ aSysInfos.aMouseInfo += "\" description=\"";
+ if( GetSystemMetrics( 75 /*SM_MOUSEWHEELPRESENT - missing in SDK from MSVC4.2 */ ) )
+ aSysInfos.aMouseInfo += "wheel mouse";
+ else
+ aSysInfos.aMouseInfo += "standard mouse";
+ aSysInfos.aMouseInfo += "\"";
+ }
+ else
+ {
+ aSysInfos.aMouseInfo += "description=\"Not installed.\"";
+ }
+ aSysInfos.aMouseInfo += " />";
+ }
+
+ CloseHandle( aSysInfos.hCurrentThread );
+ CloseHandle( aSysInfos.hCurrentProcess );
+
+ String aInfos;
+
+ aInfos += aSysInfos.aSystemVersion;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aCPUType;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aMouseInfo;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aMemoryInfo;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aStack;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aModules;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aLocalVolumes;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aSystemDirs;
+ aInfos += "\n\n";
+
+ return aInfos;
+}
+
+
+
+
+void DebugThread( SystemInfos* pSysInfos )
+{
+ HINSTANCE hImageHelpLib = LoadLibrary( "IMAGEHLP.DLL" );
+ if( hImageHelpLib )
+ {
+ if ( SuspendThread( pSysInfos->hCurrentThread ) != 0xFFFFFFFF )
+ {
+ STACKFRAME aStackFrame;
+ memset( &aStackFrame, 0, sizeof( aStackFrame ) );
+
+ CONTEXT aContext;
+ memset( &aContext, 0, sizeof( aContext ) );
+ aContext.ContextFlags = CONTEXT_FULL;
+ if ( GetThreadContext( pSysInfos->hCurrentThread, &aContext ) )
+ {
+ STACKWALKPROC _fpStackWalk = (STACKWALKPROC) GetProcAddress( hImageHelpLib, "StackWalk" );
+ SYMFUNCTIONTABLEACCESSPROC _fpSymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress( hImageHelpLib, "SymFunctionTableAccess" );
+ SYMGETMODULEBASEPROC _fpSymGetModuleBase = (SYMGETMODULEBASEPROC) GetProcAddress( hImageHelpLib, "SymGetModuleBase" );
+ SYMSETOPTIONSPROC _fpSymSetOptionsProc = (SYMSETOPTIONSPROC) GetProcAddress( hImageHelpLib, "SymGetOptions" );
+ SYMINITIALIZEPROC _fpSymInitializeProc = (SYMINITIALIZEPROC) GetProcAddress( hImageHelpLib, "SymInitialize" );
+ SYMCLEANUPPROC _fpSymCleanup = (SYMCLEANUPPROC) GetProcAddress( hImageHelpLib, "SymCleanup" );
+ UNDECORATESYMBOLNAMEPROC _fpUndecorateSymbolName = (UNDECORATESYMBOLNAMEPROC) GetProcAddress( hImageHelpLib, "UnDecorateSymbolName" );
+ SYMLOADMODULEPROC _fpSymLoadModule = ( SYMLOADMODULEPROC) GetProcAddress( hImageHelpLib, "SymLoadModule" );
+ SYMGETSYMFROMADDR _fpSymGetSymFromAddr = ( SYMGETSYMFROMADDR ) GetProcAddress( hImageHelpLib, "SymGetSymFromAddr" );
+
+ if ( !pSysInfos->pModInfos )
+ pSysInfos->pModInfos = WNT_CreateModuleInfos();
+
+ _fpSymSetOptionsProc( SYMOPT_DEFERRED_LOADS );
+
+ char buffer[1024];
+
+ // Initialize the imagehlp symbol handler
+ BOOL bAutoLoad = FALSE;
+// String aPath = WNT_CreateModulePath( pSysInfos->pModInfos );
+// USHORT nLen = aPath.Len();
+// memcpy( buffer, aPath.GetStr(), nLen );
+// buffer[nLen] = 0;
+// BOOL bSymbols = _fpSymInitializeProc( pSysInfos->hCurrentProcess, NULL, bAutoLoad );
+ // Path funktioniert nicht, also lade ich unten alle von Hand!
+ BOOL bSymbols = _fpSymInitializeProc( pSysInfos->hCurrentProcess, NULL, bAutoLoad );
+
+ // Load symbol modules for the current process
+ if ( bSymbols && !bAutoLoad )
+ {
+ // LoadModuleSymbols( pSysInfos->nCurrentProcessId, pSysInfos->hCurrentProcess );
+ struct ModuleInfo* pM = pSysInfos->pModInfos;
+ char buffer1[1024];
+ char buffer2[1024];
+
+ while ( pM )
+ {
+ strcpy( buffer1, pM->szModFileName );
+ strcpy( buffer2, pM->szModBaseName );
+
+ BOOL bDone = _fpSymLoadModule( pSysInfos->hCurrentProcess, 0, buffer1, buffer2, pM->nBaseAddress, pM->nSize );
+
+ pM = pM->pNext;
+ }
+ }
+
+ // Initialize the STACKFRAME structure for the first call. This is only
+ // necessary for Intel CPUs, and isn't mentioned in the documentation.
+ aStackFrame.AddrPC.Offset = aContext.Eip;
+ aStackFrame.AddrPC.Mode = AddrModeFlat;
+ aStackFrame.AddrStack.Offset = aContext.Esp;
+ aStackFrame.AddrStack.Mode = AddrModeFlat;
+ aStackFrame.AddrFrame.Offset = aContext.Ebp;
+ aStackFrame.AddrFrame.Mode = AddrModeFlat;
+
+
+ pSysInfos->aStack = "<Stack type=\"WIN32\" >\n";
+
+ for ( int nS = 0; nS < 20; nS++ )
+ {
+ SetLastError( 0 );
+ BOOL bStack = _fpStackWalk( IMAGE_FILE_MACHINE_I386,
+ pSysInfos->hCurrentProcess,
+ pSysInfos->hCurrentThread,
+ &aStackFrame,
+ &aContext,
+ NULL, // ReadProcessMemory,
+ _fpSymFunctionTableAccess,
+ _fpSymGetModuleBase,
+ NULL );
+
+ if ( !bStack || !aStackFrame.AddrReturn.Offset || !aStackFrame.AddrFrame.Offset )
+ break;
+
+ pSysInfos->aStack += " <StackInfo pos=\"";
+ pSysInfos->aStack += (USHORT)nS;
+ pSysInfos->aStack += "\" ip=\"";
+ ULONG nIP = aStackFrame.AddrReturn.Offset;
+ sprintf( buffer, "%.8lx", nIP );
+ pSysInfos->aStack += buffer;
+ pSysInfos->aStack += "\"";
+
+ TCHAR aModuleFileName[MAX_PATH];
+ DWORD section, offset;
+ if ( WNT_GetLogicalAddress( (void*)nIP, aModuleFileName, MAX_PATH, section, offset ) )
+ {
+ pSysInfos->aStack += " rel=\"";
+ sprintf( buffer, "%.8lx", offset );
+ pSysInfos->aStack += buffer;
+ pSysInfos->aStack += "\" file=\"";
+ char* pModName = strrchr( aModuleFileName, '\\' );
+ pSysInfos->aStack += pModName ? (pModName+1) : aModuleFileName;
+ pSysInfos->aStack += "\"";
+ }
+ else
+ {
+ pSysInfos->aStack += " rel=\"ERROR\"";
+ break;
+ }
+
+ if ( bSymbols )
+ {
+
+ BYTE symbolBuffer[ sizeof(IMAGEHLP_SYMBOL) + 512 ];
+ PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)symbolBuffer;
+ memset( symbolBuffer, 0, sizeof(symbolBuffer) );
+ pSymbol->SizeOfStruct = sizeof(symbolBuffer);
+ pSymbol->MaxNameLength = sizeof(symbolBuffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
+
+ DWORD symDisplacement = 0; // Displacement of the input address,
+ // relative to the start of the symbol
+
+ if ( _fpSymGetSymFromAddr( pSysInfos->hCurrentProcess, aStackFrame.AddrReturn.Offset,
+ &symDisplacement, pSymbol ) )
+ {
+ pSysInfos->aStack += " ordinal=\"";
+ _fpUndecorateSymbolName( pSymbol->Name, buffer, 1024, UNDNAME_NAME_ONLY );
+ pSysInfos->aStack += buffer;
+ pSysInfos->aStack += "\"";
+ // aStackLine += '<';
+ // _fpUndecorateSymbolName( pSymbol->Name, buffer, 1024, UNDNAME_COMPLETE );
+ // aStackLine += buffer;
+ // aStackLine += '>';
+ }
+ else // No symbol found. Print out the logical address instead.
+ {
+ pSysInfos->aStack += " ordinal=\"???\"";
+ }
+ }
+
+ pSysInfos->aStack += " />\n";
+ }
+ pSysInfos->aStack += "</Stack>";
+ _fpSymCleanup( pSysInfos->hCurrentProcess );
+ }
+ ResumeThread( pSysInfos->hCurrentThread );
+ }
+ FreeLibrary( hImageHelpLib );
+ }
+}
+
+#endif
diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx
new file mode 100644
index 000000000000..bafb98e35bfa
--- /dev/null
+++ b/vcl/win/source/app/salinst.cxx
@@ -0,0 +1,897 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <tools/svwin.h>
+#ifdef WNT
+#include <process.h>
+#endif
+
+#define _SV_SALINST_CXX
+
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+#ifndef _SV_SALSOUND_HXX
+#include <salsound.hxx>
+#endif
+#ifndef _SV_SALATYPE_HXX
+#include <salatype.hxx>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+
+// =======================================================================
+
+void SalAbort( const XubString& rErrorText )
+{
+ ImplFreeSalGDI();
+
+ if ( !rErrorText.Len() )
+ FatalAppExit( 0, "Application Error" );
+ else
+ {
+ ByteString aErrorText( ImplSalGetWinAnsiString( rErrorText ) );
+ FatalAppExit( 0, aErrorText.GetBuffer() );
+ }
+}
+
+// =======================================================================
+
+LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+
+// =======================================================================
+
+class SalYieldMutex : public NAMESPACE_VOS(OMutex)
+{
+public: // for ImplSalYield()
+ SalInstanceData* mpInstData;
+ ULONG mnCount;
+ DWORD mnThreadId;
+
+public:
+ SalYieldMutex( SalInstanceData* pInstData );
+
+ virtual void SAL_CALL acquire();
+ virtual void SAL_CALL release();
+ virtual sal_Bool SAL_CALL tryToAcquire();
+
+ ULONG GetAcquireCount( ULONG nThreadId );
+};
+
+// -----------------------------------------------------------------------
+
+SalYieldMutex::SalYieldMutex( SalInstanceData* pInstData )
+{
+ mpInstData = pInstData;
+ mnCount = 0;
+ mnThreadId = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SAL_CALL SalYieldMutex::acquire()
+{
+ OMutex::acquire();
+ mnCount++;
+ mnThreadId = GetCurrentThreadId();
+}
+
+// -----------------------------------------------------------------------
+
+void SAL_CALL SalYieldMutex::release()
+{
+ DWORD nThreadId = GetCurrentThreadId();
+ if ( mnThreadId != nThreadId )
+ OMutex::release();
+ else
+ {
+ // If we don't call these message, the Output from the
+ // Java clients doesn't come in the right order
+ GdiFlush();
+
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mnAppThreadId != nThreadId )
+ {
+ if ( mnCount == 1 )
+ {
+ mpInstData->mpSalWaitMutex->acquire();
+ if ( mpInstData->mnYieldWaitCount )
+ ImplPostMessage( mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
+ mnThreadId = 0;
+ mnCount--;
+ OMutex::release();
+ mpInstData->mpSalWaitMutex->release();
+ }
+ else
+ {
+ mnCount--;
+ OMutex::release();
+ }
+ }
+ else
+ {
+ if ( mnCount == 1 )
+ mnThreadId = 0;
+ mnCount--;
+ OMutex::release();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SAL_CALL SalYieldMutex::tryToAcquire()
+{
+ if( OMutex::tryToAcquire() )
+ {
+ mnCount++;
+ mnThreadId = GetCurrentThreadId();
+ return True;
+ }
+ else
+ return False;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalYieldMutex::GetAcquireCount( ULONG nThreadId )
+{
+ if ( nThreadId == mnThreadId )
+ return mnCount;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexAcquireWithWait()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( !pInst )
+ return;
+
+ // If we are the main thread, then we must wait with wait, because
+ // in if we don't reschedule, then we create deadlocks if a Windows
+ // Function is called from another thread. If we arn't the main thread,
+ // than we call qcquire directly.
+ DWORD nThreadId = GetCurrentThreadId();
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mnAppThreadId == nThreadId )
+ {
+ // Wenn wir den Mutex nicht bekommen, muessen wir solange
+ // warten, bis wir Ihn bekommen
+ BOOL bAcquire = FALSE;
+ do
+ {
+ if ( pInst->maInstData.mpSalYieldMutex->tryToAcquire() )
+ bAcquire = TRUE;
+ else
+ {
+ pInst->maInstData.mpSalWaitMutex->acquire();
+ if ( pInst->maInstData.mpSalYieldMutex->tryToAcquire() )
+ {
+ bAcquire = TRUE;
+ pInst->maInstData.mpSalWaitMutex->release();
+ }
+ else
+ {
+ pInst->maInstData.mnYieldWaitCount++;
+ pInst->maInstData.mpSalWaitMutex->release();
+ MSG aTmpMsg;
+ ImplGetMessage( &aTmpMsg, pInst->maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD );
+ pInst->maInstData.mnYieldWaitCount--;
+ if ( pInst->maInstData.mnYieldWaitCount )
+ ImplPostMessage( pInst->maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
+ }
+ }
+ }
+ while ( !bAcquire );
+ }
+ else
+ pInst->maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplSalYieldMutexTryToAcquire()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst )
+ return pInst->maInstData.mpSalYieldMutex->tryToAcquire();
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexAcquire()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst )
+ pInst->maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexRelease()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst )
+ pInst->maInstData.mpSalYieldMutex->release();
+}
+
+// -----------------------------------------------------------------------
+
+ULONG ImplSalReleaseYieldMutex()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( !pInst )
+ return 0;
+
+ SalYieldMutex* pYieldMutex = pInst->maInstData.mpSalYieldMutex;
+ ULONG nCount = pYieldMutex->GetAcquireCount( GetCurrentThreadId() );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+
+ return nCount;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalAcquireYieldMutex( ULONG nCount )
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( !pInst )
+ return;
+
+ SalYieldMutex* pYieldMutex = pInst->maInstData.mpSalYieldMutex;
+ while ( nCount )
+ {
+ pYieldMutex->acquire();
+ nCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+
+void ImplDbgTestSolarMutex()
+{
+ SalData* pSalData = GetSalData();
+ DWORD nCurThreadId = GetCurrentThreadId();
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" );
+ }
+ }
+ }
+ else
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked in the main thread" );
+ }
+ }
+ }
+}
+
+#endif
+
+// =======================================================================
+
+static void InitSalShlData()
+{
+ aSalShlData.mnVKAdd = LOWORD( VkKeyScan( '+' ) );
+ aSalShlData.mnVKSubtract = LOWORD( VkKeyScan( '-' ) );
+ aSalShlData.mnVKMultiply = LOWORD( VkKeyScan( '*' ) );
+ aSalShlData.mnVKDivide = LOWORD( VkKeyScan( '/' ) );
+ aSalShlData.mnVKPoint = LOWORD( VkKeyScan( '.' ) );
+ aSalShlData.mnVKComma = LOWORD( VkKeyScan( ',' ) );
+ aSalShlData.mnVKLess = LOWORD( VkKeyScan( '<' ) );
+ aSalShlData.mnVKGreater = LOWORD( VkKeyScan( '>' ) );
+ aSalShlData.mnVKEqual = LOWORD( VkKeyScan( '=' ) );
+}
+
+// =======================================================================
+
+void InitSalData()
+{
+ SalData* pSalData = new SalData;
+ memset( pSalData, 0, sizeof( SalData ) );
+ SetSalData( pSalData );
+ CoInitialize(0);
+}
+
+// -----------------------------------------------------------------------
+
+void DeInitSalData()
+{
+ CoUninitialize();
+ SalData* pSalData = GetSalData();
+ delete pSalData;
+ SetSalData( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void SetFilterCallback( void* pCallback, void* pInst )
+{
+ SalData* pSalData = GetSalData();
+
+ pSalData->mpFirstInstance->maInstData.mpFilterCallback = pCallback;
+ pSalData->mpFirstInstance->maInstData.mpFilterInst = pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance* CreateSalInstance()
+{
+ SalData* pSalData = GetSalData();
+
+ // determine the windows version
+ WORD nVer = (WORD)GetVersion();
+ aSalShlData.mnVersion = (((WORD)LOBYTE(nVer)) * 100) + HIBYTE(nVer);
+ if ( aSalShlData.mnVersion >= W95_VERSION )
+ aSalShlData.mbW40 = 1;
+ OSVERSIONINFO aVerInfo;
+ aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
+ if ( GetVersionEx( &aVerInfo ) )
+ {
+ if ( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
+ aSalShlData.mbWNT = 1;
+ }
+
+ pSalData->mnAppThreadId = GetCurrentThreadId();
+
+ // register frame class
+ if ( !pSalData->mhPrevInst )
+ {
+ if ( aSalShlData.mbWNT )
+ {
+ WNDCLASSEXW aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = CS_OWNDC;
+ aWndClassEx.lpfnWndProc = SalFrameWndProcW;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hCursor = 0;
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEW;
+ ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm );
+ if ( !RegisterClassExW( &aWndClassEx ) )
+ return NULL;
+ aWndClassEx.style |= CS_SAVEBITS;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAME_SBW;
+ if ( !RegisterClassExW( &aWndClassEx ) )
+ return NULL;
+
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalComWndProcW;
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEW;
+ if ( !RegisterClassExW( &aWndClassEx ) )
+ return NULL;
+ }
+ else
+ {
+ WNDCLASSEXA aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = CS_OWNDC;
+ aWndClassEx.lpfnWndProc = SalFrameWndProcA;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hCursor = 0;
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEA;
+ ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm );
+ if ( !RegisterClassExA( &aWndClassEx ) )
+ return NULL;
+ aWndClassEx.style |= CS_SAVEBITS;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAME_SBA;
+ if ( !RegisterClassExA( &aWndClassEx ) )
+ return NULL;
+
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalComWndProcA;
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEA;
+ if ( !RegisterClassExA( &aWndClassEx ) )
+ return NULL;
+ }
+ }
+
+ HWND hComWnd;
+ if ( aSalShlData.mbWNT )
+ {
+ hComWnd = CreateWindowExW( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEW,
+ L"", WS_POPUP, 0, 0, 0, 0, 0, 0,
+ pSalData->mhInst, NULL );
+ }
+ else
+ {
+ hComWnd = CreateWindowExA( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEA,
+ "", WS_POPUP, 0, 0, 0, 0, 0, 0,
+ pSalData->mhInst, NULL );
+ }
+ if ( !hComWnd )
+ return NULL;
+
+ SalInstance* pInst = new SalInstance;
+
+ // init shl data
+ InitSalShlData();
+
+ // init instance (only one instance in this version !!!)
+ pSalData->mpFirstInstance = pInst;
+ pInst->maInstData.mhInst = pSalData->mhInst;
+ pInst->maInstData.mhComWnd = hComWnd;
+
+ // init static GDI Data
+ ImplInitSalGDI();
+
+ return pInst;
+}
+
+// -----------------------------------------------------------------------
+
+void DestroySalInstance( SalInstance* pInst )
+{
+ SalData* pSalData = GetSalData();
+
+ // (only one instance in this version !!!)
+
+ ImplFreeSalGDI();
+
+ // reset instance
+ if ( pSalData->mpFirstInstance == pInst )
+ pSalData->mpFirstInstance = NULL;
+
+ delete pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::SalInstance()
+{
+ maInstData.mhComWnd = 0;
+ maInstData.mpFilterCallback = NULL;
+ maInstData.mpFilterInst = NULL;
+ maInstData.mpSalYieldMutex = new SalYieldMutex( &maInstData );
+ maInstData.mpSalWaitMutex = new NAMESPACE_VOS(OMutex);
+ maInstData.mnYieldWaitCount = 0;
+ maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::~SalInstance()
+{
+ maInstData.mpSalYieldMutex->release();
+ delete maInstData.mpSalYieldMutex;
+ delete maInstData.mpSalWaitMutex;
+ DestroyWindow( maInstData.mhComWnd );
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef _VOS_NO_NAMESPACE
+IMutex* SalInstance::GetYieldMutex()
+#else
+vos::IMutex* SalInstance::GetYieldMutex()
+#endif
+{
+ return maInstData.mpSalYieldMutex;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInstance::ReleaseYieldMutex()
+{
+ return ImplSalReleaseYieldMutex();
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::AcquireYieldMutex( ULONG nCount )
+{
+ ImplSalAcquireYieldMutex( nCount );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalDispatchMessage( MSG* pMsg )
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstObject )
+ {
+ if ( ImplSalPreDispatchMsg( pMsg ) )
+ return;
+ }
+ LRESULT lResult = ImplDispatchMessage( pMsg );
+ if ( pSalData->mpFirstObject )
+ ImplSalPostDispatchMsg( pMsg, lResult );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYield( BOOL bWait )
+{
+ MSG aMsg;
+
+ if ( bWait )
+ {
+ if ( ImplGetMessage( &aMsg, 0, 0, 0 ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplSalDispatchMessage( &aMsg );
+ }
+ }
+ else
+ {
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplSalDispatchMessage( &aMsg );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::Yield( BOOL bWait )
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ SalData* pSalData = GetSalData();
+ DWORD nCurThreadId = GetCurrentThreadId();
+ ULONG nCount = pYieldMutex->GetAcquireCount( nCurThreadId );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ ImplSendMessage( maInstData.mhComWnd, SAL_MSG_THREADYIELD, (WPARAM)bWait, (LPARAM)0 );
+ n = nCount;
+ while ( n )
+ {
+ pYieldMutex->acquire();
+ n--;
+ }
+ }
+ else
+ {
+ ImplSalYield( bWait );
+
+ n = nCount;
+ while ( n )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ n--;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalComWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ LRESULT nRet = 0;
+
+ switch ( nMsg )
+ {
+ case SAL_MSG_PRINTABORTJOB:
+ ImplSalPrinterAbortJobAsync( (HDC)wParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_THREADYIELD:
+ ImplSalYield( (BOOL)wParam );
+ rDef = FALSE;
+ break;
+ // If we get this message, because another GetMessage() call
+ // has recieved this message, we must post this message to
+ // us again, because in the other case we wait forever.
+ case SAL_MSG_RELEASEWAITYIELD:
+ {
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst && pInst->maInstData.mnYieldWaitCount )
+ ImplPostMessage( hWnd, SAL_MSG_RELEASEWAITYIELD, wParam, lParam );
+ }
+ rDef = FALSE;
+ break;
+ case SAL_MSG_STARTTIMER:
+ ImplSalStartTimer( (ULONG) lParam, FALSE );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_CREATEFRAME:
+ nRet = (LRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, (HWND)lParam, (ULONG)wParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_DESTROYFRAME:
+ delete (SalFrame*)lParam;
+ rDef = FALSE;
+ break;
+ case SAL_MSG_CREATEOBJECT:
+ nRet = (LRESULT)ImplSalCreateObject( GetSalData()->mpFirstInstance, (SalFrame*)lParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_DESTROYOBJECT:
+ delete (SalObject*)lParam;
+ rDef = FALSE;
+ break;
+ case SAL_MSG_CREATESOUND:
+ nRet = ((SalSound*)lParam)->ImplCreate();
+ rDef = FALSE;
+ break;
+ case SAL_MSG_DESTROYSOUND:
+ ((SalSound*)lParam)->ImplDestroy();
+ rDef = FALSE;
+ break;
+ }
+
+ return nRet;
+}
+
+LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ {
+ if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ }
+ return nRet;
+}
+
+LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ {
+ if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInstance::AnyInput( USHORT nType )
+{
+ MSG aMsg;
+
+ if ( (nType & (INPUT_ANY)) == (INPUT_ANY) )
+ {
+ // Any Input
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+ else
+ {
+ if ( nType & INPUT_MOUSE )
+ {
+ // Test auf Mouseinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_MOUSEFIRST, WM_MOUSELAST,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_KEYBOARD )
+ {
+ // Test auf Keyinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_KEYDOWN, WM_KEYDOWN,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ {
+ if ( (aMsg.wParam == VK_SHIFT) ||
+ (aMsg.wParam == VK_CONTROL) ||
+ (aMsg.wParam == VK_MENU) )
+ return FALSE;
+ else
+ return TRUE;
+ }
+ }
+
+ if ( nType & INPUT_PAINT )
+ {
+ // Test auf Paintinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_PAINT, WM_PAINT,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_TIMER )
+ {
+ // Test auf Timerinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_TIMER, WM_TIMER,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_OTHER )
+ {
+ // Test auf sonstigen Input
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::Start( ULONG nMS )
+{
+ // Um auf Main-Thread umzuschalten
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstInstance )
+ {
+ if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
+ ImplPostMessage( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
+ else
+ ImplSendMessage( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
+ }
+ else
+ ImplSalStartTimer( nMS, FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* SalInstance::CreateChildFrame( SystemParentData* pSystemParentData, ULONG nSalFrameStyle )
+{
+ // Um auf Main-Thread umzuschalten
+ return (SalFrame*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)pSystemParentData->hWnd );
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* SalInstance::CreateFrame( SalFrame* pParent, ULONG nSalFrameStyle )
+{
+ // Um auf Main-Thread umzuschalten
+ HWND hWndParent;
+ if ( pParent )
+ hWndParent = pParent->maFrameData.mhWnd;
+ else
+ hWndParent = 0;
+ return (SalFrame*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)hWndParent );
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyFrame( SalFrame* pFrame )
+{
+ ImplSendMessage( maInstData.mhComWnd, SAL_MSG_DESTROYFRAME, 0, (LPARAM)pFrame );
+}
+
+// -----------------------------------------------------------------------
+
+SalObject* SalInstance::CreateObject( SalFrame* pParent )
+{
+ // Um auf Main-Thread umzuschalten
+ return (SalObject*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEOBJECT, 0, (LPARAM)pParent );
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyObject( SalObject* pObject )
+{
+ ImplSendMessage( maInstData.mhComWnd, SAL_MSG_DESTROYOBJECT, 0, (LPARAM)pObject );
+}
diff --git a/vcl/win/source/app/salshl.cxx b/vcl/win/source/app/salshl.cxx
new file mode 100644
index 000000000000..3c026c053906
--- /dev/null
+++ b/vcl/win/source/app/salshl.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * $RCSfile: salshl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALSHL_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// =======================================================================
+
+SalShlData aSalShlData;
+
+// =======================================================================
+
+#ifdef WIN
+
+extern "C"
+{
+
+int CALLBACK LibMain( HINSTANCE hInst, WORD, WORD nHeap, LPSTR )
+{
+ if ( nHeap )
+ UnlockData( 0 );
+
+ aSalShlData.mhInst = hInst;
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int CALLBACK WEP( int )
+{
+ return 1;
+}
+
+}
+
+#endif
+
+// =======================================================================
+
+#ifdef WNT
+
+extern "C"
+{
+
+#ifdef ICC
+int _CRT_init(void);
+#else
+WIN_BOOL WINAPI _CRT_INIT( HINSTANCE hInst, DWORD nReason, LPVOID pReserved );
+#endif
+
+WIN_BOOL WINAPI LibMain( HINSTANCE hInst, DWORD nReason, LPVOID pReserved )
+{
+ // Unsere DLL-Initialisierung
+ if ( nReason == DLL_PROCESS_ATTACH )
+ aSalShlData.mhInst = hInst;
+
+#if !defined ( __BORLANDC__ )
+#ifdef ICC
+ if ( _CRT_init() == -1 )
+#else
+ if ( !_CRT_INIT( hInst, nReason, pReserved ) )
+#endif
+ return 0;
+#endif
+
+ return 1;
+}
+
+}
+
+#endif
+
+// =======================================================================
+
+HCURSOR ImplLoadSalCursor( int nId )
+{
+ DBG_ASSERT( aSalShlData.mhInst, "no DLL instance handle" );
+
+ HCURSOR hCursor = LoadCursor( aSalShlData.mhInst, MAKEINTRESOURCE( nId ) );
+
+ DBG_ASSERT( hCursor, "cursor not found in sal resource" );
+
+ return hCursor;
+}
+
+// -----------------------------------------------------------------------
+
+HBITMAP ImplLoadSalBitmap( int nId )
+{
+ DBG_ASSERT( aSalShlData.mhInst, "no DLL instance handle" );
+
+ HBITMAP hBitmap = LoadBitmap( aSalShlData.mhInst, MAKEINTRESOURCE( nId ) );
+
+ DBG_ASSERT( hBitmap, "bitmap not found in sal resource" );
+
+ return hBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplLoadSalIcon( int nId, HICON& rIcon, HICON& rSmallIcon )
+{
+ DBG_ASSERT( aSalShlData.mhInst, "no DLL instance handle" );
+
+ // Try at first to load the icons from the application exe file
+ SalData* pSalData = GetSalData();
+ rIcon = LoadIcon( pSalData->mhInst, MAKEINTRESOURCE( nId ) );
+ if ( !rIcon )
+ {
+ // If the application don't provide these icons, then we try
+ // to load the icon from the VCL resource
+ rIcon = LoadIcon( aSalShlData.mhInst, MAKEINTRESOURCE( nId ) );
+ if ( rIcon )
+ {
+ rSmallIcon = (HICON)LoadImage( aSalShlData.mhInst, MAKEINTRESOURCE( nId ),
+ IMAGE_ICON, 16, 16, 0 );
+ }
+ else
+ rSmallIcon = 0;
+ }
+ else
+ {
+ rSmallIcon = (HICON)LoadImage( pSalData->mhInst, MAKEINTRESOURCE( nId ),
+ IMAGE_ICON, 16, 16, 0 );
+ }
+
+ return (rSmallIcon != 0);
+}
diff --git a/vcl/win/source/app/saltimer.cxx b/vcl/win/source/app/saltimer.cxx
new file mode 100644
index 000000000000..b051c72110bf
--- /dev/null
+++ b/vcl/win/source/app/saltimer.cxx
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *
+ * $RCSfile: saltimer.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALTIMER_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+
+// =======================================================================
+
+// Maximale Periode
+#define MAX_SYSPERIOD 65533
+
+// =======================================================================
+
+void ImplSalStartTimer( ULONG nMS, BOOL bMutex )
+{
+ SalData* pSalData = GetSalData();
+
+ // Remenber the time of the timer
+ pSalData->mnTimerMS = nMS;
+ if ( !bMutex )
+ pSalData->mnTimerOrgMS = nMS;
+
+ // Periode darf nicht zu gross sein, da Windows mit USHORT arbeitet
+ if ( nMS > MAX_SYSPERIOD )
+ nMS = MAX_SYSPERIOD;
+
+ // Gibt es einen Timer, dann zerstoren
+ if ( pSalData->mnTimerId )
+ KillTimer( 0, pSalData->mnTimerId );
+
+ // Make a new timer with new period
+ pSalData->mnTimerId = SetTimer( 0, 0, (UINT)nMS, SalTimerProc );
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::Stop()
+{
+ SalData* pSalData = GetSalData();
+
+ // If we have a timer, than
+ if ( pSalData->mnTimerId )
+ {
+ KillTimer( 0, pSalData->mnTimerId );
+ pSalData->mnTimerId = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::SetCallback( SALTIMERPROC pProc )
+{
+ SalData* pSalData = GetSalData();
+ pSalData->mpTimerProc = pProc;
+}
+
+// -----------------------------------------------------------------------
+
+void CALLBACK SalTimerProc( HWND, UINT, UINT, DWORD )
+{
+ SalData* pSalData = GetSalData();
+
+ // Test for MouseLeave
+ SalTestMouseLeave();
+
+ if ( pSalData->mpTimerProc )
+ {
+ // Try to aquire the mutex. If we don't get the mutex then we
+ // try this a short time later again.
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSalData->mpTimerProc();
+ ImplSalYieldMutexRelease();
+
+ // Run the timer in the correct time, if we start this
+ // with a small timeout, because we don't get the mutex
+ if ( pSalData->mnTimerId &&
+ (pSalData->mnTimerMS != pSalData->mnTimerOrgMS) )
+ ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE );
+ }
+ else
+ ImplSalStartTimer( 10, TRUE );
+ }
+}
diff --git a/vcl/win/source/gdi/MAKEFILE.MK b/vcl/win/source/gdi/MAKEFILE.MK
new file mode 100644
index 000000000000..c63a3cdd19f4
--- /dev/null
+++ b/vcl/win/source/gdi/MAKEFILE.MK
@@ -0,0 +1,52 @@
+#*************************************************************************
+#*
+#* $Workfile: makefile. $
+#*
+#* Ersterstellung TH 01.04.97
+#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:49 $
+#* $Revision: 1.1.1.1 $
+#*
+#* $Logfile: T:/sv2/win/source/gdi/makefile.__v $
+#*
+#* Copyright (c) 1990 - 1997, STAR DIVISION
+#*
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salgdi
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/salgdi.obj \
+ $(SLO)$/salgdi2.obj \
+ $(SLO)$/salgdi3.obj \
+ $(SLO)$/salvd.obj \
+ $(SLO)$/salprn.obj \
+ $(SLO)$/salbmp.obj \
+ $(SLO)$/salogl.obj
+
+.IF "$(GUI)" == "WNT"
+SLOFILES+=$(SLO)$/wntgdi.obj
+.ENDIF
+
+.IF "$(UPDATER)"=="YES"
+OBJFILES= $(OBJ)$/salgdi.obj \
+ $(OBJ)$/salgdi2.obj \
+ $(OBJ)$/salgdi3.obj \
+ $(OBJ)$/salvd.obj \
+ $(OBJ)$/salprn.obj \
+ $(OBJ)$/salbmp.obj \
+ $(OBJ)$/salogl.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/win/source/gdi/salbmp.cxx b/vcl/win/source/gdi/salbmp.cxx
new file mode 100644
index 000000000000..ec0f9914b5ee
--- /dev/null
+++ b/vcl/win/source/gdi/salbmp.cxx
@@ -0,0 +1,668 @@
+/*************************************************************************
+ *
+ * $RCSfile: salbmp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALBMP_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#include <string.h>
+
+#ifdef WIN
+#define BI_BITFIELDS 3
+#endif
+
+// -----------
+// - Inlines -
+// -----------
+
+inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex )
+{
+ BYTE& rByte = pScanline[ nX >> 1 ];
+
+ ( nX & 1 ) ? ( rByte &= 0xf0, rByte |= ( cIndex & 0x0f ) ) :
+ ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) );
+}
+
+// -------------
+// - SalBitmap -
+// -------------
+
+SalBitmap::SalBitmap() :
+ mhDIB ( 0 ),
+ mhDDB ( 0 ),
+ mnBitCount ( 0 )
+{
+}
+
+// ------------------------------------------------------------------
+
+SalBitmap::~SalBitmap()
+{
+ Destroy();
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( HANDLE hBitmap, BOOL bDIB, BOOL bCopyHandle )
+{
+ BOOL bRet = TRUE;
+
+ if( bDIB )
+ mhDIB = (HGLOBAL) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, TRUE ) : hBitmap );
+ else
+ mhDDB = (HBITMAP) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, FALSE ) : hBitmap );
+
+ if( mhDIB )
+ {
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) GlobalLock( mhDIB );
+
+ maSize = Size( pBIH->biWidth, pBIH->biHeight );
+ mnBitCount = pBIH->biBitCount;
+
+ if( mnBitCount )
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 : ( mnBitCount <= 4 ) ? 4 : ( mnBitCount <= 8 ) ? 8 : 24;
+
+ GlobalUnlock( mhDIB );
+ }
+ else if( mhDDB )
+ {
+ BITMAP aDDBInfo;
+
+ if( WIN_GetObject( mhDDB, sizeof( BITMAP ), &aDDBInfo ) )
+ {
+ maSize = Size( aDDBInfo.bmWidth, aDDBInfo.bmHeight );
+ mnBitCount = aDDBInfo.bmPlanes * aDDBInfo.bmBitsPixel;
+
+ if( mnBitCount )
+ {
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 :
+ ( mnBitCount <= 4 ) ? 4 :
+ ( mnBitCount <= 8 ) ? 8 : 24;
+ }
+ }
+ else
+ {
+ mhDDB = 0;
+ bRet = FALSE;
+ }
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal )
+{
+ BOOL bRet = FALSE;
+
+ mhDIB = ImplCreateDIB( rSize, nBitCount, rPal );
+
+ if( mhDIB )
+ {
+ maSize = rSize;
+ mnBitCount = nBitCount;
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBitmap )
+{
+ BOOL bRet = FALSE;
+
+ if ( rSalBitmap.mhDIB || rSalBitmap.mhDDB )
+ {
+ HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB,
+ rSalBitmap.mhDIB != 0 );
+
+ if ( hNewHdl )
+ {
+ if( rSalBitmap.mhDIB )
+ mhDIB = (HGLOBAL) hNewHdl;
+ else if( rSalBitmap.mhDDB )
+ mhDDB = (HBITMAP) hNewHdl;
+
+ maSize = rSalBitmap.maSize;
+ mnBitCount = rSalBitmap.mnBitCount;
+
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
+{
+ BOOL bRet = FALSE;
+
+ if( rSalBmp.mhDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( rSalBmp.mhDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+ HDC hDC = pGraphics->maGraphicsData.mhDC;
+ HBITMAP hNewDDB;
+ BITMAP aDDBInfo;
+ PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
+ ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGBQUAD );
+
+ if( pBIH->biBitCount == 1 )
+ {
+ hNewDDB = CreateBitmap( pBIH->biWidth, pBIH->biHeight, 1, 1, NULL );
+
+ if( hNewDDB )
+ SetDIBits( hDC, hNewDDB, 0, pBIH->biHeight, pBits, pBI, DIB_RGB_COLORS );
+ }
+ else
+ hNewDDB = CreateDIBitmap( hDC, (PBITMAPINFOHEADER) pBI, CBM_INIT, pBits, pBI, DIB_RGB_COLORS );
+
+ GlobalUnlock( rSalBmp.mhDIB );
+
+ if( hNewDDB && WIN_GetObject( hNewDDB, sizeof( BITMAP ), &aDDBInfo ) )
+ {
+ mhDDB = hNewDDB;
+ maSize = Size( aDDBInfo.bmWidth, aDDBInfo.bmHeight );
+ mnBitCount = aDDBInfo.bmPlanes * aDDBInfo.bmBitsPixel;
+
+ if( mnBitCount )
+ {
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 :
+ ( mnBitCount <= 4 ) ? 4 :
+ ( mnBitCount <= 8 ) ? 8 : 24;
+ }
+
+ bRet = TRUE;
+ }
+ else if( hNewDDB )
+ DeleteObject( hNewDDB );
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, USHORT nNewBitCount )
+{
+ BOOL bRet = FALSE;
+
+ if( rSalBmp.mhDDB )
+ {
+ mhDIB = ImplCreateDIB( rSalBmp.maSize, nNewBitCount, BitmapPalette() );
+
+ if( mhDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
+ const int nLines = (int) rSalBmp.maSize.Height();
+ HDC hDC = GetDC( 0 );
+ PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
+ ImplGetDIBColorCount( mhDIB ) * sizeof( RGBQUAD );
+ SalData* pSalData = GetSalData();
+ HPALETTE hOldPal = 0;
+
+ if ( pSalData->mhDitherPal )
+ {
+ hOldPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( hDC );
+ }
+
+ if( GetDIBits( hDC, rSalBmp.mhDDB, 0, nLines, pBits, pBI, DIB_RGB_COLORS ) == nLines )
+ {
+ GlobalUnlock( mhDIB );
+ maSize = rSalBmp.maSize;
+ mnBitCount = nNewBitCount;
+ bRet = TRUE;
+ }
+ else
+ {
+ GlobalUnlock( mhDIB );
+ GlobalFree( mhDIB );
+ mhDIB = 0;
+ }
+
+ if( hOldPal )
+ SelectPalette( hDC, hOldPal, TRUE );
+
+ ReleaseDC( 0, hDC );
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::Destroy()
+{
+ if( mhDIB )
+ GlobalFree( mhDIB );
+ else if( mhDDB )
+ DeleteObject( mhDDB );
+
+ maSize = Size();
+ mnBitCount = 0;
+}
+
+// ------------------------------------------------------------------
+
+USHORT SalBitmap::ImplGetDIBColorCount( HGLOBAL hDIB )
+{
+ USHORT nColors = 0;
+
+ if( hDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+
+ if ( pBIH->biSize != sizeof( BITMAPCOREHEADER ) )
+ {
+ if( pBIH->biBitCount <= 8 )
+ {
+ if ( pBIH->biClrUsed )
+ nColors = (USHORT) pBIH->biClrUsed;
+ else
+ nColors = 1 << pBIH->biBitCount;
+ }
+ }
+ else if( ( (PBITMAPCOREHEADER) pBI )->bcBitCount <= 8 )
+ nColors = 1 << ( (PBITMAPCOREHEADER) pBI )->bcBitCount;
+
+ GlobalUnlock( hDIB );
+ }
+
+ return nColors;
+}
+
+// ------------------------------------------------------------------
+
+HGLOBAL SalBitmap::ImplCreateDIB( const Size& rSize, USHORT nBits, const BitmapPalette& rPal )
+{
+ DBG_ASSERT( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24, "Unsupported BitCount!" );
+
+ HGLOBAL hDIB = 0;
+
+ if ( rSize.Width() && rSize.Height() && ( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24 ) )
+ {
+ const ULONG nImageSize = AlignedWidth4Bytes( nBits * rSize.Width() ) * rSize.Height();
+ const USHORT nColors = ( nBits <= 8 ) ? ( 1 << nBits ) : 0;
+
+ hDIB = GlobalAlloc( GHND, sizeof( BITMAPINFOHEADER ) + nColors * sizeof( RGBQUAD ) + nImageSize );
+
+ if( hDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+
+ pBIH->biSize = sizeof( BITMAPINFOHEADER );
+ pBIH->biWidth = rSize.Width();
+ pBIH->biHeight = rSize.Height();
+ pBIH->biPlanes = 1;
+ pBIH->biBitCount = nBits;
+ pBIH->biCompression = BI_RGB;
+ pBIH->biSizeImage = nImageSize;
+ pBIH->biXPelsPerMeter = 0;
+ pBIH->biYPelsPerMeter = 0;
+ pBIH->biClrUsed = 0;
+ pBIH->biClrImportant = 0;
+
+ if ( nColors )
+ {
+ const USHORT nMinCount = Min( nColors, rPal.GetEntryCount() );
+
+ if( nMinCount )
+ HMEMCPY( pBI->bmiColors, rPal.ImplGetColorBuffer(), nMinCount * sizeof( RGBQUAD ) );
+ }
+
+ GlobalUnlock( hDIB );
+ }
+ }
+
+ return hDIB;
+}
+
+// ------------------------------------------------------------------
+
+HANDLE SalBitmap::ImplCopyDIBOrDDB( HANDLE hHdl, BOOL bDIB )
+{
+ HANDLE hCopy = 0;
+
+ if ( bDIB && hHdl )
+ {
+ const ULONG nSize = GlobalSize( hHdl );
+
+ if ( hCopy = GlobalAlloc( GHND, nSize ) )
+ {
+ HMEMCPY( (LPSTR) GlobalLock( hCopy ), (LPSTR) GlobalLock( hHdl ), nSize );
+
+ GlobalUnlock( hCopy );
+ GlobalUnlock( hHdl );
+ }
+ }
+ else if ( hHdl )
+ {
+ BITMAP aBmp;
+
+ // Source-Bitmap nach Groesse befragen
+ WIN_GetObject( hHdl, sizeof( BITMAP ), (LPSTR) &aBmp );
+
+ // Destination-Bitmap erzeugen
+ if ( hCopy = CreateBitmapIndirect( &aBmp ) )
+ {
+ HDC hBmpDC = CreateCompatibleDC( 0 );
+ HBITMAP hBmpOld = (HBITMAP) SelectObject( hBmpDC, hHdl );
+ HDC hCopyDC = CreateCompatibleDC( hBmpDC );
+ HBITMAP hCopyOld = (HBITMAP) SelectObject( hCopyDC, hCopy );
+
+ BitBlt( hCopyDC, 0, 0, aBmp.bmWidth, aBmp.bmHeight, hBmpDC, 0, 0, SRCCOPY );
+
+ SelectObject( hCopyDC, hCopyOld );
+ DeleteDC( hCopyDC );
+
+ SelectObject( hBmpDC, hBmpOld );
+ DeleteDC( hBmpDC );
+ }
+ }
+
+ return hCopy;
+}
+
+// ------------------------------------------------------------------
+
+BitmapBuffer* SalBitmap::AcquireBuffer( BOOL bReadOnly )
+{
+ BitmapBuffer* pBuffer = NULL;
+
+ if( mhDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+
+ if( ( pBIH->biCompression == BI_RLE4 ) || ( pBIH->biCompression == BI_RLE8 ) )
+ {
+ Size aSizePix( pBIH->biWidth, pBIH->biHeight );
+ HGLOBAL hNewDIB = ImplCreateDIB( aSizePix, pBIH->biBitCount, BitmapPalette() );
+
+ if( hNewDIB )
+ {
+ PBITMAPINFO pNewBI = (PBITMAPINFO) GlobalLock( hNewDIB );
+ PBITMAPINFOHEADER pNewBIH = (PBITMAPINFOHEADER) pNewBI;
+ const USHORT nColorCount = ImplGetDIBColorCount( hNewDIB );
+ const ULONG nOffset = *(DWORD*) pBI + nColorCount * sizeof( RGBQUAD );
+ BYTE* pOldBits = (PBYTE) pBI + nOffset;
+ BYTE* pNewBits = (PBYTE) pNewBI + nOffset;
+
+ HMEMCPY( pNewBI, pBI, nOffset );
+ pNewBIH->biCompression = 0;
+ ImplDecodeRLEBuffer( pOldBits, pNewBits, aSizePix, pBIH->biCompression == BI_RLE4 );
+
+ GlobalUnlock( mhDIB );
+ GlobalFree( mhDIB );
+ mhDIB = hNewDIB;
+ pBI = pNewBI;
+ pBIH = pNewBIH;
+ }
+ }
+
+ if( pBIH->biPlanes == 1 )
+ {
+ pBuffer = new BitmapBuffer;
+
+ pBuffer->mnFormat = BMP_FORMAT_BOTTOM_UP |
+ ( pBIH->biBitCount == 1 ? BMP_FORMAT_1BIT_MSB_PAL :
+ pBIH->biBitCount == 4 ? BMP_FORMAT_4BIT_MSN_PAL :
+ pBIH->biBitCount == 8 ? BMP_FORMAT_8BIT_PAL :
+ pBIH->biBitCount == 16 ? BMP_FORMAT_16BIT_TC_MASK :
+ pBIH->biBitCount == 24 ? BMP_FORMAT_24BIT_TC_BGR :
+ pBIH->biBitCount == 32 ? BMP_FORMAT_32BIT_TC_MASK : 0UL );
+
+ if( BMP_SCANLINE_FORMAT( pBuffer->mnFormat ) )
+ {
+ pBuffer->mnWidth = maSize.Width();
+ pBuffer->mnHeight = maSize.Height();
+ pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->biBitCount );
+ pBuffer->mnBitCount = (USHORT) pBIH->biBitCount;
+
+ if( pBuffer->mnBitCount <= 8 )
+ {
+ const USHORT nPalCount = ImplGetDIBColorCount( mhDIB );
+
+ pBuffer->maPalette.SetEntryCount( nPalCount );
+ HMEMCPY( pBuffer->maPalette.ImplGetColorBuffer(), pBI->bmiColors, nPalCount * sizeof( RGBQUAD ) );
+ pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI + nPalCount * sizeof( RGBQUAD );
+ }
+ else if( ( pBIH->biBitCount == 16 ) || ( pBIH->biBitCount == 32 ) )
+ {
+ ULONG nOffset = 0UL;
+
+ if( pBIH->biCompression == BI_BITFIELDS )
+ {
+ nOffset = 3 * sizeof( RGBQUAD );
+ pBuffer->maColorMask = ColorMask( *(UINT32*) &pBI->bmiColors[ 0 ],
+ *(UINT32*) &pBI->bmiColors[ 1 ],
+ *(UINT32*) &pBI->bmiColors[ 2 ] );
+ }
+ else if( pBIH->biCompression == 16 )
+ pBuffer->maColorMask = ColorMask( 0x00007c00UL, 0x000003e0UL, 0x0000001fUL );
+ else
+ pBuffer->maColorMask = ColorMask( 0x00ff0000UL, 0x0000ff00UL, 0x000000ffUL );
+
+ pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI + nOffset;
+ }
+ else
+ pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI;
+ }
+ else
+ {
+ GlobalUnlock( mhDIB );
+ delete pBuffer;
+ pBuffer = NULL;
+ }
+ }
+ else
+ GlobalUnlock( mhDIB );
+ }
+
+ return pBuffer;
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BOOL bReadOnly )
+{
+ if( pBuffer )
+ {
+ if( mhDIB )
+ {
+ if( !bReadOnly && !!pBuffer->maPalette )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
+ const USHORT nCount = pBuffer->maPalette.GetEntryCount();
+
+ HMEMCPY( pBI->bmiColors, pBuffer->maPalette.ImplGetColorBuffer(), nCount * sizeof( RGBQUAD ) );
+ GlobalUnlock( mhDIB );
+ }
+
+ GlobalUnlock( mhDIB );
+ }
+
+ delete pBuffer;
+ }
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::ImplDecodeRLEBuffer( const BYTE* pSrcBuf, BYTE* pDstBuf,
+ const Size& rSizePixel, BOOL bRLE4 )
+{
+ HPBYTE pRLE = (HPBYTE) pSrcBuf;
+ HPBYTE pDIB = (HPBYTE) pDstBuf;
+ HPBYTE pRow = (HPBYTE) pDstBuf;
+ ULONG nWidthAl = AlignedWidth4Bytes( rSizePixel.Width() * ( bRLE4 ? 4UL : 8UL ) );
+ HPBYTE pLast = pDIB + rSizePixel.Height() * nWidthAl - 1;
+ ULONG nCountByte;
+ ULONG nRunByte;
+ ULONG nX = 0;
+ ULONG i;
+ BYTE cTmp;
+ BOOL bEndDecoding = FALSE;
+
+ if( pRLE && pDIB )
+ {
+ do
+ {
+ if( !( nCountByte = *pRLE++ ) )
+ {
+ nRunByte = *pRLE++;
+
+ if( nRunByte > 2UL )
+ {
+ if( bRLE4 )
+ {
+ nCountByte = nRunByte >> 1UL;
+
+ for( i = 0; i < nCountByte; i++ )
+ {
+ cTmp = *pRLE++;
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
+ }
+
+ if( nRunByte & 1 )
+ ImplSetPixel4( pDIB, nX++, *pRLE++ >> 4 );
+
+ if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
+ pRLE++;
+ }
+ else
+ {
+ HMEMCPY( &pDIB[ nX ], pRLE, nRunByte );
+ pRLE += nRunByte;
+ nX += nRunByte;
+
+ if( nRunByte & 1 )
+ pRLE++;
+ }
+ }
+ else if( !nRunByte )
+ {
+ pDIB = ( pRow += nWidthAl );
+ nX = 0UL;
+ }
+ else if( nRunByte == 1 )
+ bEndDecoding = TRUE;
+ else
+ {
+ nX += *pRLE++;
+ pDIB = ( pRow += ( *pRLE++ ) * nWidthAl );
+ }
+ }
+ else
+ {
+ cTmp = *pRLE++;
+
+ if( bRLE4 )
+ {
+ nRunByte = nCountByte >> 1;
+
+ for( i = 0; i < nRunByte; i++ )
+ {
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
+ }
+
+ if( nCountByte & 1 )
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ }
+ else
+ {
+ for( i = 0; i < nCountByte; i++ )
+ pDIB[ nX++ ] = cTmp;
+ }
+ }
+ }
+ while( !bEndDecoding && ( pDIB <= pLast ) );
+ }
+}
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
new file mode 100644
index 000000000000..f8f5892add4e
--- /dev/null
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -0,0 +1,1449 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+#define _SV_SALGDI_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// =======================================================================
+
+#define DITHER_PAL_DELTA 51
+#define DITHER_PAL_STEPS 6
+#define DITHER_PAL_COUNT (DITHER_PAL_STEPS*DITHER_PAL_STEPS*DITHER_PAL_STEPS)
+#define DITHER_MAX_SYSCOLOR 16
+#define DITHER_EXTRA_COLORS 1
+#define DMAP( _def_nVal, _def_nThres ) ((pDitherDiff[_def_nVal]>(_def_nThres))?pDitherHigh[_def_nVal]:pDitherLow[_def_nVal])
+
+// =======================================================================
+
+struct SysColorEntry
+{
+ DWORD nRGB;
+ SysColorEntry* pNext;
+};
+
+// =======================================================================
+
+static SysColorEntry* pFirstSysColor = NULL;
+static SysColorEntry* pActSysColor = NULL;
+
+// -----------------------------------------------------------------------------
+
+// Blue7
+static PALETTEENTRY aImplExtraColor1 =
+{
+ 0, 184, 255, 0
+};
+
+// -----------------------------------------------------------------------------
+
+static PALETTEENTRY aImplSalSysPalEntryAry[ DITHER_MAX_SYSCOLOR ] =
+{
+{ 0, 0, 0, 0 },
+{ 0, 0, 0x80, 0 },
+{ 0, 0x80, 0, 0 },
+{ 0, 0x80, 0x80, 0 },
+{ 0x80, 0, 0, 0 },
+{ 0x80, 0, 0x80, 0 },
+{ 0x80, 0x80, 0, 0 },
+{ 0x80, 0x80, 0x80, 0 },
+{ 0xC0, 0xC0, 0xC0, 0 },
+{ 0, 0, 0xFF, 0 },
+{ 0, 0xFF, 0, 0 },
+{ 0, 0xFF, 0xFF, 0 },
+{ 0xFF, 0, 0, 0 },
+{ 0xFF, 0, 0xFF, 0 },
+{ 0xFF, 0xFF, 0, 0 },
+{ 0xFF, 0xFF, 0xFF, 0 }
+};
+
+// -----------------------------------------------------------------------------
+
+static BYTE aOrdDither8Bit[8][8] =
+{
+ 0, 38, 9, 48, 2, 40, 12, 50,
+ 25, 12, 35, 22, 28, 15, 37, 24,
+ 6, 44, 3, 41, 8, 47, 5, 44,
+ 32, 19, 28, 16, 34, 21, 31, 18,
+ 1, 40, 11, 49, 0, 39, 10, 48,
+ 27, 14, 36, 24, 26, 13, 36, 23,
+ 8, 46, 4, 43, 7, 45, 4, 42,
+ 33, 20, 30, 17, 32, 20, 29, 16
+};
+
+// -----------------------------------------------------------------------------
+
+static BYTE aOrdDither16Bit[8][8] =
+{
+ 0, 6, 1, 7, 0, 6, 1, 7,
+ 4, 2, 5, 3, 4, 2, 5, 3,
+ 1, 7, 0, 6, 1, 7, 0, 6,
+ 5, 3, 4, 2, 5, 3, 4, 2,
+ 0, 6, 1, 7, 0, 6, 1, 7,
+ 4, 2, 5, 3, 4, 2, 5, 3,
+ 1, 7, 0, 6, 1, 7, 0, 6,
+ 5, 3, 4, 2, 5, 3, 4, 2
+};
+
+// =======================================================================
+
+// Pens muessen wir mit 1 Pixel-Breite erzeugen, da ansonsten die S3-Karte
+// viele Paintprobleme hat, wenn Polygone/PolyLines gezeichnet werden und
+// eine komplexe ClipRegion gesetzt ist
+#define GSL_PEN_WIDTH 1
+
+// =======================================================================
+
+#define SAL_POLYPOLYCOUNT_STACKBUF 8
+#define SAL_POLYPOLYPOINTS_STACKBUF 64
+
+// =======================================================================
+
+void ImplInitSalGDI()
+{
+ SalData* pSalData = GetSalData();
+
+ // init stock brushes
+ pSalData->maStockPenColorAry[0] = PALETTERGB( 0, 0, 0 );
+ pSalData->maStockPenColorAry[1] = PALETTERGB( 0xFF, 0xFF, 0xFF );
+ pSalData->maStockPenColorAry[2] = PALETTERGB( 0xC0, 0xC0, 0xC0 );
+ pSalData->maStockPenColorAry[3] = PALETTERGB( 0x80, 0x80, 0x80 );
+ pSalData->mhStockPenAry[0] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[0] );
+ pSalData->mhStockPenAry[1] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[1] );
+ pSalData->mhStockPenAry[2] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[2] );
+ pSalData->mhStockPenAry[3] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[3] );
+ pSalData->mnStockPenCount = 4;
+
+ pSalData->maStockBrushColorAry[0] = PALETTERGB( 0, 0, 0 );
+ pSalData->maStockBrushColorAry[1] = PALETTERGB( 0xFF, 0xFF, 0xFF );
+ pSalData->maStockBrushColorAry[2] = PALETTERGB( 0xC0, 0xC0, 0xC0 );
+ pSalData->maStockBrushColorAry[3] = PALETTERGB( 0x80, 0x80, 0x80 );
+ pSalData->mhStockBrushAry[0] = CreateSolidBrush( pSalData->maStockBrushColorAry[0] );
+ pSalData->mhStockBrushAry[1] = CreateSolidBrush( pSalData->maStockBrushColorAry[1] );
+ pSalData->mhStockBrushAry[2] = CreateSolidBrush( pSalData->maStockBrushColorAry[2] );
+ pSalData->mhStockBrushAry[3] = CreateSolidBrush( pSalData->maStockBrushColorAry[3] );
+ pSalData->mnStockBrushCount = 4;
+
+ // DC-Cache aufbauen
+ pSalData->mpHDCCache = new HDCCache[ CACHESIZE_HDC ];
+ memset( pSalData->mpHDCCache, 0, CACHESIZE_HDC * sizeof( HDCCache ) );
+
+ // Nur bei 256 Farben Displays, die Paletten unterstuetzen
+ HDC hDC = GetDC( 0 );
+ int nBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
+ int nPlanes = GetDeviceCaps( hDC, PLANES );
+ int nRasterCaps = GetDeviceCaps( hDC, RASTERCAPS );
+ int nBitCount = nBitsPixel * nPlanes;
+
+ if ( (nBitCount > 8) && (nBitCount < 24) )
+ {
+ // test, if we have to dither
+ HDC hMemDC = ::CreateCompatibleDC( hDC );
+ HBITMAP hMemBmp = ::CreateCompatibleBitmap( hDC, 8, 8 );
+ HBITMAP hBmpOld = (HBITMAP) ::SelectObject( hMemDC, hMemBmp );
+ HBRUSH hMemBrush = ::CreateSolidBrush( PALETTERGB( 175, 171, 169 ) );
+ HBRUSH hBrushOld = (HBRUSH) ::SelectObject( hMemDC, hMemBrush );
+ BOOL bDither16 = TRUE;
+
+ ::PatBlt( hMemDC, 0, 0, 8, 8, PATCOPY );
+ const COLORREF aCol( ::GetPixel( hMemDC, 0, 0 ) );
+
+ for( int nY = 0; ( nY < 8 ) && bDither16; nY++ )
+ for( int nX = 0; ( nX < 8 ) && bDither16; nX++ )
+ if( ::GetPixel( hMemDC, nX, nY ) != aCol )
+ bDither16 = FALSE;
+
+ ::SelectObject( hMemDC, hBrushOld ), ::DeleteObject( hMemBrush );
+ ::SelectObject( hMemDC, hBmpOld ), ::DeleteObject( hMemBmp );
+ ::DeleteDC( hMemDC );
+
+ if( bDither16 )
+ {
+ // create DIBPattern for 16Bit dithering
+ long n;
+
+ pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, sizeof( BITMAPINFOHEADER ) + 192 );
+ pSalData->mpDitherDIB = (BYTE*) GlobalLock( pSalData->mhDitherDIB );
+ pSalData->mpDitherDiff = new long[ 256 ];
+ pSalData->mpDitherLow = new BYTE[ 256 ];
+ pSalData->mpDitherHigh = new BYTE[ 256 ];
+ pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER );
+ memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) );
+
+ BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) pSalData->mpDitherDIB;
+
+ pBIH->biSize = sizeof( BITMAPINFOHEADER );
+ pBIH->biWidth = 8;
+ pBIH->biHeight = 8;
+ pBIH->biPlanes = 1;
+ pBIH->biBitCount = 24;
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherDiff[ n ] = n - ( n & 248L );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherLow[ n ] = (BYTE) ( n & 248 );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherHigh[ n ] = (BYTE) Min( pSalData->mpDitherLow[ n ] + 8L, 255L );
+ }
+ }
+ else if ( (nRasterCaps & RC_PALETTE) && (nBitCount == 8) )
+ {
+ BYTE nRed, nGreen, nBlue;
+ BYTE nR, nG, nB;
+ PALETTEENTRY* pPalEntry;
+ LOGPALETTE* pLogPal;
+ const USHORT nDitherPalCount = DITHER_PAL_COUNT;
+ ULONG nTotalCount = DITHER_MAX_SYSCOLOR + nDitherPalCount + DITHER_EXTRA_COLORS;
+
+ // create logical palette
+ pLogPal = (LOGPALETTE*) new char[ sizeof( LOGPALETTE ) + ( nTotalCount * sizeof( PALETTEENTRY ) ) ];
+ pLogPal->palVersion = 0x0300;
+ pLogPal->palNumEntries = (USHORT) nTotalCount;
+ pPalEntry = pLogPal->palPalEntry;
+
+ // Standard colors
+ memcpy( pPalEntry, aImplSalSysPalEntryAry, DITHER_MAX_SYSCOLOR * sizeof( PALETTEENTRY ) );
+ pPalEntry += DITHER_MAX_SYSCOLOR;
+
+ // own palette (6/6/6)
+ for( nB=0, nBlue=0; nB < DITHER_PAL_STEPS; nB++, nBlue += DITHER_PAL_DELTA )
+ {
+ for( nG=0, nGreen=0; nG < DITHER_PAL_STEPS; nG++, nGreen += DITHER_PAL_DELTA )
+ {
+ for( nR=0, nRed=0; nR < DITHER_PAL_STEPS; nR++, nRed += DITHER_PAL_DELTA )
+ {
+ pPalEntry->peRed = nRed;
+ pPalEntry->peGreen = nGreen;
+ pPalEntry->peBlue = nBlue;
+ pPalEntry->peFlags = 0;
+ pPalEntry++;
+ }
+ }
+ }
+
+ // insert special 'Blue' as standard drawing color
+ *pPalEntry++ = aImplExtraColor1;
+
+ // create palette
+ pSalData->mhDitherPal = CreatePalette( pLogPal );
+ delete[] (char*) pLogPal;
+
+ if( pSalData->mhDitherPal )
+ {
+ // create DIBPattern for 8Bit dithering
+ long nSize = sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) ) + 64;
+ long n;
+
+ pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, nSize );
+ pSalData->mpDitherDIB = (BYTE*) GlobalLock( pSalData->mhDitherDIB );
+ pSalData->mpDitherDiff = new long[ 256 ];
+ pSalData->mpDitherLow = new BYTE[ 256 ];
+ pSalData->mpDitherHigh = new BYTE[ 256 ];
+ pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) );
+ memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) );
+
+ BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) pSalData->mpDitherDIB;
+ short* pColors = (short*) ( pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) );
+
+ pBIH->biSize = sizeof( BITMAPINFOHEADER );
+ pBIH->biWidth = 8;
+ pBIH->biHeight = 8;
+ pBIH->biPlanes = 1;
+ pBIH->biBitCount = 8;
+
+ for( n = 0; n < nDitherPalCount; n++ )
+ pColors[ n ] = (short)( n + DITHER_MAX_SYSCOLOR );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherDiff[ n ] = n % 51L;
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherLow[ n ] = (BYTE) ( n / 51L );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherHigh[ n ] = Min( pSalData->mpDitherLow[ n ] + 1, 5 );
+ }
+
+ // get system color entries
+ ImplUpdateSysColorEntries();
+ }
+
+ ReleaseDC( 0, hDC );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFreeSalGDI()
+{
+ SalData* pSalData = GetSalData();
+ USHORT i;
+
+ // destroy stock objects
+ for ( i = 0; i < pSalData->mnStockPenCount; i++ )
+ DeletePen( pSalData->mhStockPenAry[i] );
+ for ( i = 0; i < pSalData->mnStockBrushCount; i++ )
+ DeleteBrush( pSalData->mhStockBrushAry[i] );
+
+ // 50% Brush loeschen
+ if ( pSalData->mh50Brush )
+ {
+ DeleteBrush( pSalData->mh50Brush );
+ pSalData->mh50Brush = 0;
+ }
+
+ // 50% Bitmap loeschen
+ if ( pSalData->mh50Bmp )
+ {
+ DeleteBitmap( pSalData->mh50Bmp );
+ pSalData->mh50Bmp = 0;
+ }
+
+ ImplClearHDCCache( pSalData );
+ delete[] pSalData->mpHDCCache;
+
+ // Ditherpalette loeschen, wenn vorhanden
+ if ( pSalData->mhDitherPal )
+ {
+ DeleteObject( pSalData->mhDitherPal );
+ pSalData->mhDitherPal = 0;
+ }
+
+ // delete buffers for dithering DIB patterns, if neccessary
+ if ( pSalData->mhDitherDIB )
+ {
+ GlobalUnlock( pSalData->mhDitherDIB );
+ GlobalFree( pSalData->mhDitherDIB );
+ pSalData->mhDitherDIB = 0;
+ delete[] pSalData->mpDitherDiff;
+ delete[] pSalData->mpDitherLow;
+ delete[] pSalData->mpDitherHigh;
+ }
+
+ // delete SysColorList
+ SysColorEntry* pEntry = pFirstSysColor;
+ while( pEntry )
+ {
+ SysColorEntry* pTmp = pEntry->pNext;
+ delete pEntry;
+ pEntry = pTmp;
+ }
+ pFirstSysColor = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue )
+{
+ // dither color?
+ if ( !(nRed % DITHER_PAL_DELTA) && !(nGreen % DITHER_PAL_DELTA) && !(nBlue % DITHER_PAL_DELTA) )
+ return TRUE;
+
+ PALETTEENTRY* pPalEntry = aImplSalSysPalEntryAry;
+
+ // standard palette color?
+ for ( USHORT i = 0; i < DITHER_MAX_SYSCOLOR; i++, pPalEntry++ )
+ {
+ if( pPalEntry->peRed == nRed && pPalEntry->peGreen == nGreen && pPalEntry->peBlue == nBlue )
+ return TRUE;
+ }
+
+ // extra color?
+ if ( aImplExtraColor1.peRed == nRed &&
+ aImplExtraColor1.peGreen == nGreen &&
+ aImplExtraColor1.peBlue == nBlue )
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// =======================================================================
+
+int ImplIsSysColorEntry( SalColor nSalColor )
+{
+ SysColorEntry* pEntry = pFirstSysColor;
+ const DWORD nTestRGB = (DWORD)RGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ while ( pEntry )
+ {
+ if ( pEntry->nRGB == nTestRGB )
+ return TRUE;
+ pEntry = pEntry->pNext;
+ }
+
+ return FALSE;
+}
+
+// =======================================================================
+
+static void ImplInsertSysColorEntry( int nSysIndex )
+{
+ const DWORD nRGB = GetSysColor( nSysIndex );
+
+ if ( !ImplIsPaletteEntry( GetRValue( nRGB ), GetGValue( nRGB ), GetBValue( nRGB ) ) )
+ {
+ if ( !pFirstSysColor )
+ {
+ pActSysColor = pFirstSysColor = new SysColorEntry;
+ pFirstSysColor->nRGB = nRGB;
+ pFirstSysColor->pNext = NULL;
+ }
+ else
+ {
+ pActSysColor = pActSysColor->pNext = new SysColorEntry;
+ pActSysColor->nRGB = nRGB;
+ pActSysColor->pNext = NULL;
+ }
+ }
+}
+
+// =======================================================================
+
+void ImplUpdateSysColorEntries()
+{
+ // delete old SysColorList
+ SysColorEntry* pEntry = pFirstSysColor;
+ while( pEntry )
+ {
+ SysColorEntry* pTmp = pEntry->pNext;
+ delete pEntry;
+ pEntry = pTmp;
+ }
+ pActSysColor = pFirstSysColor = NULL;
+
+ // create new sys color list
+ ImplInsertSysColorEntry( COLOR_ACTIVEBORDER );
+ ImplInsertSysColorEntry( COLOR_INACTIVEBORDER );
+ if( aSalShlData.mnVersion >= 410 )
+ {
+ ImplInsertSysColorEntry( COLOR_GRADIENTACTIVECAPTION );
+ ImplInsertSysColorEntry( COLOR_GRADIENTINACTIVECAPTION );
+ }
+ ImplInsertSysColorEntry( COLOR_3DFACE );
+ ImplInsertSysColorEntry( COLOR_3DHILIGHT );
+ ImplInsertSysColorEntry( COLOR_3DLIGHT );
+ ImplInsertSysColorEntry( COLOR_3DSHADOW );
+ ImplInsertSysColorEntry( COLOR_3DDKSHADOW );
+ ImplInsertSysColorEntry( COLOR_INFOBK );
+ ImplInsertSysColorEntry( COLOR_INFOTEXT );
+ ImplInsertSysColorEntry( COLOR_BTNTEXT );
+ ImplInsertSysColorEntry( COLOR_WINDOW );
+ ImplInsertSysColorEntry( COLOR_WINDOWTEXT );
+ ImplInsertSysColorEntry( COLOR_HIGHLIGHT );
+ ImplInsertSysColorEntry( COLOR_HIGHLIGHTTEXT );
+ ImplInsertSysColorEntry( COLOR_MENU );
+ ImplInsertSysColorEntry( COLOR_MENUTEXT );
+ ImplInsertSysColorEntry( COLOR_ACTIVECAPTION );
+ ImplInsertSysColorEntry( COLOR_CAPTIONTEXT );
+ ImplInsertSysColorEntry( COLOR_INACTIVECAPTION );
+ ImplInsertSysColorEntry( COLOR_INACTIVECAPTIONTEXT );
+}
+
+// -----------------------------------------------------------------------
+
+static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
+{
+ SalColor nSalColor;
+ if ( nROPColor == SAL_ROP_0 )
+ nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
+ else
+ nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
+ return nSalColor;
+}
+
+// =======================================================================
+
+void ImplSalInitGraphics( SalGraphicsData* pData )
+{
+ // Beim Printer berechnen wir die minimale Linienstaerke
+ if ( pData->mbPrinter )
+ {
+ int nDPIX = GetDeviceCaps( pData->mhDC, LOGPIXELSX );
+ if ( nDPIX <= 300 )
+ pData->mnPenWidth = 0;
+ else
+ pData->mnPenWidth = nDPIX/300;
+ }
+
+ ::SetTextAlign( pData->mhDC, TA_BASELINE | TA_LEFT | TA_NOUPDATECP );
+ ::SetBkMode( pData->mhDC, TRANSPARENT );
+ ::SetROP2( pData->mhDC, R2_COPYPEN );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalDeInitGraphics( SalGraphicsData* pData )
+{
+ // Default Objekte selektieren
+ if ( pData->mhDefPen )
+ SelectPen( pData->mhDC, pData->mhDefPen );
+ if ( pData->mhDefBrush )
+ SelectBrush( pData->mhDC, pData->mhDefBrush );
+ if ( pData->mhDefFont )
+ SelectFont( pData->mhDC, pData->mhDefFont );
+}
+
+// =======================================================================
+
+HDC ImplGetCachedDC( ULONG nID, HBITMAP hBmp )
+{
+ SalData* pSalData = GetSalData();
+ HDCCache* pC = &pSalData->mpHDCCache[ nID ];
+
+ if( !pC->mhDC )
+ {
+ HDC hDC = GetDC( 0 );
+
+ // neuen DC mit DefaultBitmap anlegen
+ pC->mhDC = CreateCompatibleDC( hDC );
+
+ if( pSalData->mhDitherPal )
+ {
+ pC->mhDefPal = SelectPalette( pC->mhDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( pC->mhDC );
+ }
+
+ pC->mhSelBmp = CreateCompatibleBitmap( hDC, CACHED_HDC_DEFEXT, CACHED_HDC_DEFEXT );
+ pC->mhDefBmp = (HBITMAP) SelectObject( pC->mhDC, pC->mhSelBmp );
+
+ ReleaseDC( 0, hDC );
+ }
+
+ if ( hBmp )
+ SelectObject( pC->mhDC, pC->mhActBmp = hBmp );
+ else
+ pC->mhActBmp = 0;
+
+ return pC->mhDC;
+}
+
+// =======================================================================
+
+void ImplReleaseCachedDC( ULONG nID )
+{
+ SalData* pSalData = GetSalData();
+ HDCCache* pC = &pSalData->mpHDCCache[ nID ];
+
+ if ( pC->mhActBmp )
+ SelectObject( pC->mhDC, pC->mhSelBmp );
+}
+
+// =======================================================================
+
+void ImplClearHDCCache( SalData* pData )
+{
+ for( ULONG i = 0; i < CACHESIZE_HDC; i++ )
+ {
+ HDCCache* pC = &pData->mpHDCCache[ i ];
+
+ if( pC->mhDC )
+ {
+ SelectObject( pC->mhDC, pC->mhDefBmp );
+
+ if( pC->mhDefPal )
+ SelectPalette( pC->mhDC, pC->mhDefPal, TRUE );
+
+ DeleteDC( pC->mhDC );
+ DeleteObject( pC->mhSelBmp );
+ }
+ }
+}
+
+// =======================================================================
+
+SalGraphics::SalGraphics()
+{
+ maGraphicsData.mhDC = 0;
+ maGraphicsData.mhPen = 0;
+ maGraphicsData.mhBrush = 0;
+ maGraphicsData.mhFont = 0;
+ maGraphicsData.mhRegion = 0;
+ maGraphicsData.mhDefPen = 0;
+ maGraphicsData.mhDefBrush = 0;
+ maGraphicsData.mhDefFont = 0;
+ maGraphicsData.mhDefPal = 0;
+ maGraphicsData.mpStdClipRgnData = NULL;
+ maGraphicsData.mpLogFont = NULL;
+ maGraphicsData.mpFontCharSets = NULL;
+ maGraphicsData.mnFontCharSetCount = 0;
+ maGraphicsData.mpFontKernPairs = NULL;
+ maGraphicsData.mnFontKernPairCount = 0;
+ maGraphicsData.mbFontKernInit = FALSE;
+ maGraphicsData.mnFontOverhang = 0;
+ maGraphicsData.mbXORMode = FALSE;
+ maGraphicsData.mnPenWidth = GSL_PEN_WIDTH;
+ maGraphicsData.mbCalcOverhang = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics::~SalGraphics()
+{
+ // Objekte zerstoeren
+ if ( maGraphicsData.mhPen )
+ {
+ if ( !maGraphicsData.mbStockPen )
+ DeletePen( maGraphicsData.mhPen );
+ }
+ if ( maGraphicsData.mhBrush )
+ {
+ if ( !maGraphicsData.mbStockBrush )
+ DeleteBrush( maGraphicsData.mhBrush );
+ }
+ if ( maGraphicsData.mhFont )
+ DeleteFont( maGraphicsData.mhFont );
+
+ if ( maGraphicsData.mhRegion )
+ {
+ DeleteRegion( maGraphicsData.mhRegion );
+ maGraphicsData.mhRegion = 0;
+ }
+
+ // Cache-Daten zerstoeren
+ if ( maGraphicsData.mpStdClipRgnData )
+ delete maGraphicsData.mpStdClipRgnData;
+
+ if ( maGraphicsData.mpLogFont )
+ delete maGraphicsData.mpLogFont;
+
+ if ( maGraphicsData.mpFontCharSets )
+ delete maGraphicsData.mpFontCharSets;
+
+ if ( maGraphicsData.mpFontKernPairs )
+ delete maGraphicsData.mpFontKernPairs;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetResolution( long& rDPIX, long& rDPIY )
+{
+ rDPIX = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSX );
+ rDPIY = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSY );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetScreenFontResolution( long& rDPIX, long& rDPIY )
+{
+ rDPIX = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSX );
+ rDPIY = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSY );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalGraphics::GetBitCount()
+{
+ return (USHORT)GetDeviceCaps( maGraphicsData.mhDC, BITSPIXEL );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::ResetClipRegion()
+{
+ if ( maGraphicsData.mhRegion )
+ {
+ DeleteRegion( maGraphicsData.mhRegion );
+ maGraphicsData.mhRegion = 0;
+ }
+
+ SelectClipRgn( maGraphicsData.mhDC, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::BeginSetClipRegion( ULONG nRectCount )
+{
+ if ( maGraphicsData.mhRegion )
+ {
+ DeleteRegion( maGraphicsData.mhRegion );
+ maGraphicsData.mhRegion = 0;
+ }
+
+ ULONG nRectBufSize = sizeof(RECT)*nRectCount;
+ if ( nRectCount < SAL_CLIPRECT_COUNT )
+ {
+ if ( !maGraphicsData.mpStdClipRgnData )
+ maGraphicsData.mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
+ maGraphicsData.mpClipRgnData = maGraphicsData.mpStdClipRgnData;
+ }
+ else
+ maGraphicsData.mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
+ maGraphicsData.mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
+ maGraphicsData.mpClipRgnData->rdh.iType = RDH_RECTANGLES;
+ maGraphicsData.mpClipRgnData->rdh.nCount = nRectCount;
+ maGraphicsData.mpClipRgnData->rdh.nRgnSize = nRectBufSize;
+ SetRectEmpty( &(maGraphicsData.mpClipRgnData->rdh.rcBound) );
+ maGraphicsData.mpNextClipRect = (RECT*)(&(maGraphicsData.mpClipRgnData->Buffer));
+ maGraphicsData.mbFirstClipRect = TRUE;
+}
+
+
+// -----------------------------------------------------------------------
+
+BOOL SalGraphics::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ if ( nWidth && nHeight )
+ {
+ RECT* pRect = maGraphicsData.mpNextClipRect;
+ RECT* pBoundRect = &(maGraphicsData.mpClipRgnData->rdh.rcBound);
+ long nRight = nX + nWidth;
+ long nBottom = nY + nHeight;
+
+ if ( maGraphicsData.mbFirstClipRect )
+ {
+ pBoundRect->left = nX;
+ pBoundRect->top = nY;
+ pBoundRect->right = nRight;
+ pBoundRect->bottom = nBottom;
+ maGraphicsData.mbFirstClipRect = FALSE;
+ }
+ else
+ {
+ if ( nX < pBoundRect->left )
+ pBoundRect->left = (int)nX;
+
+ if ( nY < pBoundRect->top )
+ pBoundRect->top = (int)nY;
+
+ if ( nRight > pBoundRect->right )
+ pBoundRect->right = (int)nRight;
+
+ if ( nBottom > pBoundRect->bottom )
+ pBoundRect->bottom = (int)nBottom;
+ }
+
+ pRect->left = (int)nX;
+ pRect->top = (int)nY;
+ pRect->right = (int)nRight;
+ pRect->bottom = (int)nBottom;
+ maGraphicsData.mpNextClipRect++;
+ }
+ else
+ {
+ maGraphicsData.mpClipRgnData->rdh.nCount--;
+ maGraphicsData.mpClipRgnData->rdh.nRgnSize -= sizeof( RECT );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::EndSetClipRegion()
+{
+ // Aus den Region-Daten muessen wir jetzt eine ClipRegion erzeugen
+ if ( maGraphicsData.mpClipRgnData->rdh.nCount == 1 )
+ {
+ RECT* pRect = &(maGraphicsData.mpClipRgnData->rdh.rcBound);
+ maGraphicsData.mhRegion = CreateRectRgn( pRect->left, pRect->top,
+ pRect->right, pRect->bottom );
+ }
+ else
+ {
+ ULONG nSize = maGraphicsData.mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
+ maGraphicsData.mhRegion = ExtCreateRegion( NULL, nSize, maGraphicsData.mpClipRgnData );
+
+ // if ExtCreateRegion(...) is not supported
+ if( !maGraphicsData.mhRegion )
+ {
+ RGNDATAHEADER* pHeader = (RGNDATAHEADER*) maGraphicsData.mpClipRgnData;
+
+ if( pHeader->nCount )
+ {
+ RECT* pRect = (RECT*) maGraphicsData.mpClipRgnData->Buffer;
+ maGraphicsData.mhRegion = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
+ pRect++;
+
+ for( ULONG n = 1; n < pHeader->nCount; n++, pRect++ )
+ {
+ HRGN hRgn = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
+ CombineRgn( maGraphicsData.mhRegion, maGraphicsData.mhRegion, hRgn, RGN_OR );
+ DeleteRegion( hRgn );
+ }
+ }
+ }
+
+ if ( maGraphicsData.mpClipRgnData != maGraphicsData.mpStdClipRgnData )
+ delete maGraphicsData.mpClipRgnData;
+ }
+
+ SelectClipRgn( maGraphicsData.mhDC, maGraphicsData.mhRegion );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetLineColor()
+{
+ // create and select new pen
+ HPEN hNewPen = GetStockPen( NULL_PEN );
+ HPEN hOldPen = SelectPen( maGraphicsData.mhDC, hNewPen );
+
+ // destory or save old pen
+ if ( maGraphicsData.mhPen )
+ {
+ if ( !maGraphicsData.mbStockPen )
+ DeletePen( maGraphicsData.mhPen );
+ }
+ else
+ maGraphicsData.mhDefPen = hOldPen;
+
+ // set new data
+ maGraphicsData.mhPen = hNewPen;
+ maGraphicsData.mbPen = FALSE;
+ maGraphicsData.mbStockPen = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetLineColor( SalColor nSalColor )
+{
+ COLORREF nPenColor = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+ HPEN hNewPen = 0;
+ BOOL bStockPen;
+
+ // search for stock pen (only screen, because printer have problems,
+ // when we use stock objects)
+ if ( !maGraphicsData.mbPrinter )
+ {
+ SalData* pSalData = GetSalData();
+ for ( USHORT i = 0; i < pSalData->mnStockPenCount; i++ )
+ {
+ if ( nPenColor == pSalData->maStockPenColorAry[i] )
+ {
+ hNewPen = pSalData->mhStockPenAry[i];
+ bStockPen = TRUE;
+ break;
+ }
+ }
+ }
+
+ // create new pen
+ if ( !hNewPen )
+ {
+ if ( !maGraphicsData.mbPrinter )
+ {
+ if ( GetSalData()->mhDitherPal && ImplIsSysColorEntry( nSalColor ) )
+ nPenColor = PALRGB_TO_RGB( nPenColor );
+ }
+
+ hNewPen = CreatePen( PS_SOLID, maGraphicsData.mnPenWidth, nPenColor );
+ bStockPen = FALSE;
+ }
+
+ // select new pen
+ HPEN hOldPen = SelectPen( maGraphicsData.mhDC, hNewPen );
+
+ // destory or save old pen
+ if ( maGraphicsData.mhPen )
+ {
+ if ( !maGraphicsData.mbStockPen )
+ DeletePen( maGraphicsData.mhPen );
+ }
+ else
+ maGraphicsData.mhDefPen = hOldPen;
+
+ // set new data
+ maGraphicsData.mnPenColor = nPenColor;
+ maGraphicsData.mhPen = hNewPen;
+ maGraphicsData.mbPen = TRUE;
+ maGraphicsData.mbStockPen = bStockPen;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetFillColor()
+{
+ // create and select new brush
+ HBRUSH hNewBrush = GetStockBrush( NULL_BRUSH );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hNewBrush );
+
+ // destory or save old brush
+ if ( maGraphicsData.mhBrush )
+ {
+ if ( !maGraphicsData.mbStockBrush )
+ DeleteBrush( maGraphicsData.mhBrush );
+ }
+ else
+ maGraphicsData.mhDefBrush = hOldBrush;
+
+ // set new data
+ maGraphicsData.mhBrush = hNewBrush;
+ maGraphicsData.mbBrush = FALSE;
+ maGraphicsData.mbStockBrush = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetFillColor( SalColor nSalColor )
+{
+ SalData* pSalData = GetSalData();
+ BYTE nRed = SALCOLOR_RED( nSalColor );
+ BYTE nGreen = SALCOLOR_GREEN( nSalColor );
+ BYTE nBlue = SALCOLOR_BLUE( nSalColor );
+ COLORREF nBrushColor = PALETTERGB( nRed, nGreen, nBlue );
+ HBRUSH hNewBrush = 0;
+ BOOL bStockBrush;
+
+ // search for stock brush (only screen, because printer have problems,
+ // when we use stock objects)
+ if ( !maGraphicsData.mbPrinter )
+ {
+ for ( USHORT i = 0; i < pSalData->mnStockBrushCount; i++ )
+ {
+ if ( nBrushColor == pSalData->maStockBrushColorAry[ i ] )
+ {
+ hNewBrush = pSalData->mhStockBrushAry[i];
+ bStockBrush = TRUE;
+ break;
+ }
+ }
+ }
+
+ // create new brush
+ if ( !hNewBrush )
+ {
+ if ( maGraphicsData.mbPrinter || !pSalData->mhDitherDIB )
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ else
+ {
+ if ( 24 == ((BITMAPINFOHEADER*)pSalData->mpDitherDIB)->biBitCount )
+ {
+ BYTE* pTmp = pSalData->mpDitherDIBData;
+ long* pDitherDiff = pSalData->mpDitherDiff;
+ BYTE* pDitherLow = pSalData->mpDitherLow;
+ BYTE* pDitherHigh = pSalData->mpDitherHigh;
+
+ for( long nY = 0L; nY < 8L; nY++ )
+ {
+ for( long nX = 0L; nX < 8L; nX++ )
+ {
+ const long nThres = aOrdDither16Bit[ nY ][ nX ];
+ *pTmp++ = DMAP( nBlue, nThres );
+ *pTmp++ = DMAP( nGreen, nThres );
+ *pTmp++ = DMAP( nRed, nThres );
+ }
+ }
+
+ hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_RGB_COLORS );
+ }
+ else if ( ImplIsSysColorEntry( nSalColor ) )
+ {
+ nBrushColor = PALRGB_TO_RGB( nBrushColor );
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ }
+ else if ( ImplIsPaletteEntry( nRed, nGreen, nBlue ) )
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ else
+ {
+ BYTE* pTmp = pSalData->mpDitherDIBData;
+ long* pDitherDiff = pSalData->mpDitherDiff;
+ BYTE* pDitherLow = pSalData->mpDitherLow;
+ BYTE* pDitherHigh = pSalData->mpDitherHigh;
+
+ for ( long nY = 0L; nY < 8L; nY++ )
+ {
+ for ( long nX = 0L; nX < 8L; nX++ )
+ {
+ const long nThres = aOrdDither8Bit[ nY ][ nX ];
+ *pTmp = DMAP( nRed, nThres ) + DMAP( nGreen, nThres ) * 6 + DMAP( nBlue, nThres ) * 36;
+ pTmp++;
+ }
+ }
+
+ hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_PAL_COLORS );
+ }
+ }
+
+ bStockBrush = FALSE;
+ }
+
+ // select new brush
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hNewBrush );
+
+ // destory or save old brush
+ if ( maGraphicsData.mhBrush )
+ {
+ if ( !maGraphicsData.mbStockBrush )
+ DeleteBrush( maGraphicsData.mhBrush );
+ }
+ else
+ maGraphicsData.mhDefBrush = hOldBrush;
+
+ // set new data
+ maGraphicsData.mnBrushColor = nBrushColor;
+ maGraphicsData.mhBrush = hNewBrush;
+ maGraphicsData.mbBrush = FALSE;
+ maGraphicsData.mbStockBrush = bStockBrush;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetXORMode( BOOL bSet )
+{
+ maGraphicsData.mbXORMode = bSet;
+ ::SetROP2( maGraphicsData.mhDC, bSet ? R2_XORPEN : R2_COPYPEN );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetROPLineColor( SalROPColor nROPColor )
+{
+ SetLineColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetROPFillColor( SalROPColor nROPColor )
+{
+ SetFillColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPixel( long nX, long nY )
+{
+ if ( maGraphicsData.mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( maGraphicsData.mnPenColor );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ PatBlt( maGraphicsData.mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ SetPixel( maGraphicsData.mhDC, (int)nX, (int)nY, maGraphicsData.mnPenColor );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPixel( long nX, long nY, SalColor nSalColor )
+{
+ COLORREF nCol = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ if ( !maGraphicsData.mbPrinter &&
+ GetSalData()->mhDitherPal &&
+ ImplIsSysColorEntry( nSalColor ) )
+ nCol = PALRGB_TO_RGB( nCol );
+
+ if ( maGraphicsData.mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( nCol );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ PatBlt( maGraphicsData.mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ ::SetPixel( maGraphicsData.mhDC, (int)nX, (int)nY, nCol );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ MoveToEx( maGraphicsData.mhDC, (int)nX1, (int)nY1, NULL );
+
+ // we must paint the endpoint
+ int bPaintEnd = TRUE;
+ if ( nX1 == nX2 )
+ {
+ bPaintEnd = FALSE;
+ if ( nY1 <= nY2 )
+ nY2++;
+ else
+ nY2--;
+ }
+ if ( nY1 == nY2 )
+ {
+ bPaintEnd = FALSE;
+ if ( nX1 <= nX2 )
+ nX2++;
+ else
+ nX2--;
+ }
+
+ LineTo( maGraphicsData.mhDC, (int)nX2, (int)nY2 );
+
+ if ( bPaintEnd && !maGraphicsData.mbPrinter )
+ {
+ if ( maGraphicsData.mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( maGraphicsData.mnPenColor );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ PatBlt( maGraphicsData.mhDC, (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ SetPixel( maGraphicsData.mhDC, (int)nX2, (int)nY2, maGraphicsData.mnPenColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ if ( !maGraphicsData.mbPen )
+ {
+ if ( !maGraphicsData.mbPrinter )
+ {
+ PatBlt( maGraphicsData.mhDC, (int)nX, (int)nY, (int)nWidth, (int)nHeight,
+ maGraphicsData.mbXORMode ? PATINVERT : PATCOPY );
+ }
+ else
+ {
+ RECT aWinRect;
+ aWinRect.left = nX;
+ aWinRect.top = nY;
+ aWinRect.right = nX+nWidth;
+ aWinRect.bottom = nY+nHeight;
+ ::FillRect( maGraphicsData.mhDC, &aWinRect, maGraphicsData.mhBrush );
+ }
+ }
+ else
+ WIN_Rectangle( maGraphicsData.mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolyLine( ULONG nPoints, const SalPoint* pPtAry )
+{
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolyLine(): POINT != SalPoint" );
+
+ POINT* pWinPtAry = (POINT*)pPtAry;
+ // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
+ // von Punkten
+ if ( !Polyline( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ Polyline( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolygon( ULONG nPoints, const SalPoint* pPtAry )
+{
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolygon(): POINT != SalPoint" );
+
+ POINT* pWinPtAry = (POINT*)pPtAry;
+ // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
+ // von Punkten
+ if ( !WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolyPolygon( ULONG nPoly, const ULONG* pPoints,
+ PCONSTSALPOINT* pPtAry )
+{
+ UINT aWinPointAry[SAL_POLYPOLYCOUNT_STACKBUF];
+ UINT* pWinPointAry;
+ UINT nPolyPolyPoints = 0;
+ UINT nPoints;
+ UINT i;
+
+ if ( nPoly <= SAL_POLYPOLYCOUNT_STACKBUF )
+ pWinPointAry = aWinPointAry;
+ else
+ pWinPointAry = new UINT[nPoly];
+
+ for ( i = 0; i < (UINT)nPoly; i++ )
+ {
+ nPoints = (UINT)pPoints[i]+1;
+ pWinPointAry[i] = nPoints;
+ nPolyPolyPoints += nPoints;
+ }
+
+ POINT aWinPointAryAry[SAL_POLYPOLYPOINTS_STACKBUF];
+ POINT* pWinPointAryAry;
+ if ( nPolyPolyPoints <= SAL_POLYPOLYPOINTS_STACKBUF )
+ pWinPointAryAry = aWinPointAryAry;
+ else
+ pWinPointAryAry = new POINT[nPolyPolyPoints];
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolyPolygon(): POINT != SalPoint" );
+ const SalPoint* pPolyAry;
+ UINT n = 0;
+ for ( i = 0; i < (UINT)nPoly; i++ )
+ {
+ nPoints = pWinPointAry[i];
+ pPolyAry = pPtAry[i];
+ memcpy( pWinPointAryAry+n, pPolyAry, (nPoints-1)*sizeof(POINT) );
+ pWinPointAryAry[n+nPoints-1] = pWinPointAryAry[n];
+ n += nPoints;
+ }
+
+ if ( !WIN_PolyPolygon( maGraphicsData.mhDC, pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) &&
+ (nPolyPolyPoints > MAX_64KSALPOINTS) )
+ {
+ nPolyPolyPoints = 0;
+ nPoly = 0;
+ do
+ {
+ nPolyPolyPoints += pWinPointAry[(UINT)nPoly];
+ nPoly++;
+ }
+ while ( nPolyPolyPoints < MAX_64KSALPOINTS );
+ nPoly--;
+ if ( pWinPointAry[(UINT)nPoly] > MAX_64KSALPOINTS )
+ pWinPointAry[(UINT)nPoly] = MAX_64KSALPOINTS;
+ if ( nPoly == 1 )
+ WIN_Polygon( maGraphicsData.mhDC, pWinPointAryAry, *pWinPointAry );
+ else
+ WIN_PolyPolygon( maGraphicsData.mhDC, pWinPointAryAry, (int*)pWinPointAry, nPoly );
+ }
+
+ if ( pWinPointAry != aWinPointAry )
+ delete pWinPointAry;
+ if ( pWinPointAryAry != aWinPointAryAry )
+ delete pWinPointAryAry;
+}
+
+
+// -----------------------------------------------------------------------
+
+#define POSTSCRIPT_BUFSIZE 0x4000 // MAXIMUM BUFSIZE EQ 0xFFFF
+#define POSTSCRIPT_BOUNDINGSEARCH 0x1000 // we only try to get the BoundingBox
+ // in the first 4096 bytes
+
+static BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, ULONG nComp, ULONG nSize )
+{
+ while ( nComp-- >= nSize )
+ {
+ for ( ULONG i = 0; i < nSize; i++ )
+ {
+ if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
+ break;
+ }
+ if ( i == nSize )
+ return pSource;
+ pSource++;
+ }
+ return NULL;
+}
+
+static BOOL ImplGetBoundingBox( double* nNumb, BYTE* pSource, ULONG nSize )
+{
+ BOOL bRetValue = FALSE;
+ ULONG nBytesRead;
+
+ if ( nSize < 256 ) // we assume that the file is greater than 256 bytes
+ return FALSE;
+
+ if ( nSize < POSTSCRIPT_BOUNDINGSEARCH )
+ nBytesRead = nSize;
+ else
+ nBytesRead = POSTSCRIPT_BOUNDINGSEARCH;
+
+ BYTE* pDest = ImplSearchEntry( pSource, (BYTE*)"%%BoundingBox:", nBytesRead, 14 );
+ if ( pDest )
+ {
+ int nSecurityCount = 100; // only 100 bytes following the bounding box will be checked
+ nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
+ pDest += 14;
+ for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ )
+ {
+ int nDivision = 1;
+ BOOL bDivision = FALSE;
+ BOOL bNegative = FALSE;
+ BOOL bValid = TRUE;
+
+ while ( ( --nSecurityCount ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++;
+ BYTE nByte = *pDest;
+ while ( nSecurityCount && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
+ {
+ switch ( nByte )
+ {
+ case '.' :
+ if ( bDivision )
+ bValid = FALSE;
+ else
+ bDivision = TRUE;
+ break;
+ case '-' :
+ bNegative = TRUE;
+ break;
+ default :
+ if ( ( nByte < '0' ) || ( nByte > '9' ) )
+ nSecurityCount = 1; // error parsing the bounding box values
+ else if ( bValid )
+ {
+ if ( bDivision )
+ nDivision*=10;
+ nNumb[i] *= 10;
+ nNumb[i] += nByte - '0';
+ }
+ break;
+ }
+ nSecurityCount--;
+ nByte = *(++pDest);
+ }
+ if ( bNegative )
+ nNumb[i] = -nNumb[i];
+ if ( bDivision && ( nDivision != 1 ) )
+ nNumb[i] /= nDivision;
+ }
+ if ( nSecurityCount)
+ bRetValue = TRUE;
+ }
+ return bRetValue;
+}
+
+inline void ImplWriteDouble( BYTE** pBuf, double nNumb )
+{
+ *pBuf += sprintf( (char*)*pBuf, "%f", nNumb );
+ *(*pBuf)++ = ' ';
+}
+
+inline void ImplWriteString( BYTE** pBuf, const char* sString )
+{
+ strcpy( (char*)*pBuf, sString );
+ *pBuf += strlen( sString );
+}
+
+BOOL SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize )
+{
+ BOOL bRetValue = FALSE;
+
+ if ( maGraphicsData.mbPrinter )
+ {
+ int nEscape = POSTSCRIPT_PASSTHROUGH;
+
+ if ( Escape( maGraphicsData.mhDC, QUERYESCSUPPORT, sizeof( int ), ( LPSTR )&nEscape, 0 ) )
+ {
+ BYTE* pBuf = new BYTE[ POSTSCRIPT_BUFSIZE ];
+
+ double nBoundingBox[4];
+
+ if ( pBuf && ImplGetBoundingBox( nBoundingBox, (BYTE*)pPtr, nSize ) )
+ {
+ double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] );
+ double dM22 = nHeight / (nBoundingBox[1] - nBoundingBox[3] );
+ BYTE* pTemp = pBuf + 2; // +2 because we want to insert the size later
+ ImplWriteString( &pTemp, "\n\nsave\n[ " );
+ ImplWriteDouble( &pTemp, dM11 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, dM22 );
+ ImplWriteDouble( &pTemp, nX - ( dM11 * nBoundingBox[0] ) );
+ ImplWriteDouble( &pTemp, nY - ( dM22 * nBoundingBox[3] ) );
+ ImplWriteString( &pTemp, "] concat /showpage {} def\n" );
+ ImplWriteString( &pTemp, "%%BeginDocument:\n" );
+ *((USHORT*)pBuf) = (USHORT)( pTemp - pBuf - 2 );
+ Escape ( maGraphicsData.mhDC, nEscape, pTemp - pBuf, (LPTSTR)((BYTE*)pBuf), 0 );
+
+ ULONG nToDo = nSize;
+ ULONG nDoNow;
+ while ( nToDo )
+ {
+ nDoNow = nToDo;
+ if ( nToDo > POSTSCRIPT_BUFSIZE - 2 )
+ nDoNow = POSTSCRIPT_BUFSIZE - 2;
+ *((USHORT*)pBuf) = (USHORT)nDoNow;
+ memcpy( pBuf + 2, (BYTE*)pPtr + nSize - nToDo, nDoNow );
+ ULONG nResult = Escape ( maGraphicsData.mhDC, nEscape, nDoNow + 2, (LPTSTR)((BYTE*)pBuf), 0 );
+ if (!nResult )
+ break;
+ nToDo -= nResult;
+ }
+ pTemp = pBuf + 2;
+ ImplWriteString( &pTemp, "%%EndDocument\n" );
+ ImplWriteString( &pTemp, "restore\n\n" );
+ *((USHORT*)pBuf) = (USHORT)( pTemp - pBuf - 2 );
+ Escape ( maGraphicsData.mhDC, nEscape, pTemp - pBuf, (LPTSTR)((BYTE*)pBuf), 0 );
+ bRetValue = TRUE;
+ }
+ delete pBuf;
+ }
+ }
+
+ return bRetValue;
+}
diff --git a/vcl/win/source/gdi/salgdi2.cxx b/vcl/win/source/gdi/salgdi2.cxx
new file mode 100644
index 000000000000..20252e35f31b
--- /dev/null
+++ b/vcl/win/source/gdi/salgdi2.cxx
@@ -0,0 +1,782 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#define _SV_SALGDI2_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+
+// =======================================================================
+
+BOOL bFastTransparent = FALSE;
+
+// =======================================================================
+
+void SalGraphics::CopyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics )
+{
+ HDC hSrcDC;
+ DWORD nRop;
+
+ if ( pSrcGraphics )
+ hSrcDC = pSrcGraphics->maGraphicsData.mhDC;
+ else
+ hSrcDC = maGraphicsData.mhDC;
+
+ if ( maGraphicsData.mbXORMode )
+ nRop = SRCINVERT;
+ else
+ nRop = SRCCOPY;
+
+ if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) &&
+ (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) )
+ {
+ BitBlt( maGraphicsData.mhDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ hSrcDC,
+ (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
+ nRop );
+ }
+ else
+ {
+ int nOldStretchMode = SetStretchBltMode( maGraphicsData.mhDC, STRETCH_DELETESCANS );
+ StretchBlt( maGraphicsData.mhDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ hSrcDC,
+ (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
+ (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight,
+ nRop );
+ SetStretchBltMode( maGraphicsData.mhDC, nOldStretchMode );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplCalcOutSideRgn( const RECT& rSrcRect,
+ int nLeft, int nTop, int nRight, int nBottom,
+ HRGN& rhInvalidateRgn )
+{
+ HRGN hTempRgn;
+
+ // Bereiche ausserhalb des sichtbaren Bereiches berechnen
+ if ( rSrcRect.left < nLeft )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( -31999, 0, nLeft, 31999 );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ if ( rSrcRect.top < nTop )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( 0, -31999, 31999, nTop );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ if ( rSrcRect.right > nRight )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( nRight, 0, 31999, 31999 );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ if ( rSrcRect.bottom > nBottom )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( 0, nBottom, 31999, 31999 );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::CopyArea( long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ USHORT nFlags )
+{
+ BitBlt( maGraphicsData.mhDC,
+ (int)nDestX, (int)nDestY,
+ (int)nSrcWidth, (int)nSrcHeight,
+ maGraphicsData.mhDC,
+ (int)nSrcX, (int)nSrcY,
+ SRCCOPY );
+
+ // Muessen die ueberlappenden Bereiche auch invalidiert werden?
+ if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && maGraphicsData.mbWindow )
+ {
+ // Overlap-Bereich berechnen und invalidieren
+ RECT aSrcRect;
+ RECT aClipRect;
+ RECT aTempRect;
+ RECT aTempRect2;
+ HRGN hInvalidateRgn;
+ HRGN hTempRgn;
+ HWND hWnd;
+ int nRgnType;
+
+ aSrcRect.left = (int)nSrcX;
+ aSrcRect.top = (int)nSrcY;
+ aSrcRect.right = aSrcRect.left+(int)nSrcWidth;
+ aSrcRect.bottom = aSrcRect.top+(int)nSrcHeight;
+ GetClientRect( maGraphicsData.mhWnd, &aClipRect );
+ if ( IntersectRect( &aSrcRect, &aSrcRect, &aClipRect ) )
+ {
+ // Rechteck in Screen-Koordinaaten umrechnen
+ POINT aPt;
+ int nScreenDX = GetSystemMetrics( SM_CXSCREEN );
+ int nScreenDY = GetSystemMetrics( SM_CYSCREEN );
+ aPt.x = 0;
+ aPt.y = 0;
+ ClientToScreen( maGraphicsData.mhWnd, &aPt );
+ aSrcRect.left += aPt.x;
+ aSrcRect.top += aPt.y;
+ aSrcRect.right += aPt.x;
+ aSrcRect.bottom += aPt.y;
+ hInvalidateRgn = 0;
+ // Bereiche ausserhalb des sichtbaren Bereiches berechnen
+ ImplCalcOutSideRgn( aSrcRect, 0, 0, nScreenDX, nScreenDY, hInvalidateRgn );
+
+ // Bereiche die von anderen Fenstern ueberlagert werden berechnen
+ HRGN hTempRgn2 = 0;
+ HWND hWndTopWindow = maGraphicsData.mhWnd;
+ // Find the TopLevel Window, because only Windows which are in
+ // in the foreground of our TopLevel window must be considered
+ if ( GetWindowStyle( hWndTopWindow ) & WS_CHILD )
+ {
+ RECT aTempRect3 = aSrcRect;
+ do
+ {
+ hWndTopWindow = ::GetParent( hWndTopWindow );
+
+ // Test, if the Parent clip our window
+ GetClientRect( hWndTopWindow, &aTempRect );
+ POINT aPt2;
+ aPt2.x = 0;
+ aPt2.y = 0;
+ ClientToScreen( hWndTopWindow, &aPt2 );
+ aTempRect.left += aPt2.x;
+ aTempRect.top += aPt2.y;
+ aTempRect.right += aPt2.x;
+ aTempRect.bottom += aPt2.y;
+ IntersectRect( &aTempRect3, &aTempRect3, &aTempRect );
+ }
+ while ( GetWindowStyle( hWndTopWindow ) & WS_CHILD );
+
+ // If one or more Parents clip our window, than we must
+ // calculate the outside area
+ if ( !EqualRect( &aSrcRect, &aTempRect3 ) )
+ {
+ ImplCalcOutSideRgn( aSrcRect,
+ aTempRect3.left, aTempRect3.top,
+ aTempRect3.right, aTempRect3.bottom,
+ hInvalidateRgn );
+ }
+ }
+ hWnd = GetWindow( GetDesktopWindow(), GW_CHILD );
+ while ( hWnd )
+ {
+ if ( hWnd == hWndTopWindow )
+ break;
+ if ( IsWindowVisible( hWnd ) && !IsIconic( hWnd ) )
+ {
+ GetWindowRect( hWnd, &aTempRect );
+ if ( IntersectRect( &aTempRect2, &aSrcRect, &aTempRect ) )
+ {
+ if ( !hInvalidateRgn )
+ hInvalidateRgn = CreateRectRgnIndirect( &aSrcRect );
+ hTempRgn = CreateRectRgnIndirect( &aTempRect );
+ if ( !hTempRgn2 )
+ hTempRgn2 = CreateRectRgn( 0, 0, 0, 0 );
+ nRgnType = GetWindowRgn( hWnd, hTempRgn2 );
+ if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
+ {
+ OffsetRgn( hTempRgn2, aTempRect.left, aTempRect.top );
+ CombineRgn( hTempRgn, hTempRgn, hTempRgn2, RGN_AND );
+ }
+ CombineRgn( hInvalidateRgn, hInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ }
+ hWnd = GetWindow( hWnd, GW_HWNDNEXT );
+ }
+ if ( hTempRgn2 )
+ DeleteRegion( hTempRgn2 );
+ if ( hInvalidateRgn )
+ {
+ hTempRgn = CreateRectRgnIndirect( &aSrcRect );
+ nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_DIFF );
+ if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
+ {
+ int nOffX = (int)(nDestX-nSrcX);
+ int nOffY = (int)(nDestY-nSrcY);
+ OffsetRgn( hInvalidateRgn, nOffX-aPt.x, nOffY-aPt.y );
+ // Combine Invalidate Region with existing ClipRegion
+ if ( GetClipRgn( maGraphicsData.mhDC, hTempRgn ) == 1 )
+ nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_AND );
+ if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
+ {
+ InvalidateRgn( maGraphicsData.mhWnd, hInvalidateRgn, TRUE );
+ // Hier loesen wir nur ein Update aus, wenn es der
+ // MainThread ist, damit es beim Bearbeiten der
+ // Paint-Message keinen Deadlock gibt, da der
+ // SolarMutex durch diesen Thread schon gelockt ist
+ SalData* pSalData = GetSalData();
+ DWORD nCurThreadId = GetCurrentThreadId();
+ if ( pSalData->mnAppThreadId == nCurThreadId )
+ UpdateWindow( maGraphicsData.mhWnd );
+ }
+ }
+ DeleteRegion( hTempRgn );
+ DeleteRegion( hInvalidateRgn );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDrawBitmap( HDC hDC,
+ const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap,
+ BOOL bPrinter, int nDrawMode )
+{
+ if( hDC )
+ {
+ HGLOBAL hDrawDIB;
+ HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB();
+ SalBitmap* pTmpSalBmp;
+ BOOL bPrintDDB = ( bPrinter && hDrawDDB );
+
+ if( bPrintDDB )
+ {
+ pTmpSalBmp = new SalBitmap;
+ pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() );
+ hDrawDIB = pTmpSalBmp->ImplGethDIB();
+ }
+ else
+ hDrawDIB = rSalBitmap.ImplGethDIB();
+
+ if( hDrawDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDrawDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+ PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
+ rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD );
+ const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
+
+ int nCount = StretchDIBits( hDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ (int)pPosAry->mnSrcX, (int)(pBIH->biHeight - pPosAry->mnSrcHeight - pPosAry->mnSrcY),
+ (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight,
+ pBits, pBI, DIB_RGB_COLORS, nDrawMode );
+
+ GlobalUnlock( hDrawDIB );
+ SetStretchBltMode( hDC, nOldStretchMode );
+ }
+ else if( hDrawDDB && !bPrintDDB )
+ {
+ HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_DRAW, hDrawDDB );
+ COLORREF nOldBkColor;
+ COLORREF nOldTextColor;
+ BOOL bMono = ( rSalBitmap.GetBitCount() == 1 );
+
+ if( bMono )
+ {
+ nOldBkColor = SetBkColor( hDC, RGB( 0xFF, 0xFF, 0xFF ) );
+ nOldTextColor = ::SetTextColor( hDC, RGB( 0x00, 0x00, 0x00 ) );
+ }
+
+ if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) &&
+ (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) )
+ {
+ BitBlt( hDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ hBmpDC,
+ (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
+ nDrawMode );
+ }
+ else
+ {
+ const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
+
+ StretchBlt( hDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ hBmpDC,
+ (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
+ (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight,
+ nDrawMode );
+
+ SetStretchBltMode( hDC, nOldStretchMode );
+ }
+
+ if( bMono )
+ {
+ SetBkColor( hDC, nOldBkColor );
+ ::SetTextColor( hDC, nOldTextColor );
+ }
+
+ ImplReleaseCachedDC( CACHED_HDC_DRAW );
+ }
+
+ if( bPrintDDB )
+ delete pTmpSalBmp;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap )
+{
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, rSalBitmap,
+ maGraphicsData.mbPrinter,
+ maGraphicsData.mbXORMode ? SRCINVERT : SRCCOPY );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nTransparentColor )
+{
+ DBG_ASSERT( !maGraphicsData.mbPrinter, "No transparency print possible!" );
+
+ SalBitmap* pMask = new SalBitmap;
+ HDC hDC = maGraphicsData.mhDC;
+ const Point aPoint;
+ const Size aSize( rSalBitmap.GetSize() );
+ HBITMAP hMaskBitmap = CreateBitmap( (int) aSize.Width(), (int) aSize.Height(), 1, 1, NULL );
+ HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_1, hMaskBitmap );
+ const BYTE cRed = SALCOLOR_RED( nTransparentColor );
+ const BYTE cGreen = SALCOLOR_GREEN( nTransparentColor );
+ const BYTE cBlue = SALCOLOR_BLUE( nTransparentColor );
+
+ if( rSalBitmap.ImplGethDDB() )
+ {
+ HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, rSalBitmap.ImplGethDDB() );
+ COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
+
+ BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
+
+ SetBkColor( hSrcDC, aOldCol );
+ ImplReleaseCachedDC( CACHED_HDC_2 );
+ }
+ else
+ {
+ SalBitmap* pTmpSalBmp = new SalBitmap;
+
+ if( pTmpSalBmp->Create( rSalBitmap, this ) )
+ {
+ HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, pTmpSalBmp->ImplGethDDB() );
+ COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
+
+ BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
+
+ SetBkColor( hSrcDC, aOldCol );
+ ImplReleaseCachedDC( CACHED_HDC_2 );
+ }
+
+ delete pTmpSalBmp;
+ }
+
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+
+ // hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE )
+ if( pMask->Create( hMaskBitmap, FALSE, FALSE ) )
+ DrawBitmap( pPosAry, rSalBitmap, *pMask );
+
+ delete pMask;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rTransparentBitmap )
+{
+ DBG_ASSERT( !maGraphicsData.mbPrinter, "No transparency print possible!" );
+
+ if( bFastTransparent )
+ {
+ // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
+ // die Farben der Maske richtig auf die Palette abzubilden,
+ // wenn wir die DIB direkt ausgeben => DDB-Ausgabe
+ if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 )
+ {
+ SalBitmap aTmp;
+ if( aTmp.Create( rTransparentBitmap, this ) )
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, aTmp, FALSE, SRCAND );
+ }
+ else
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, rTransparentBitmap, FALSE, SRCAND );
+
+ // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
+ // die Farben der Maske richtig auf die Palette abzubilden,
+ // wenn wir die DIB direkt ausgeben => DDB-Ausgabe
+ if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 )
+ {
+ SalBitmap aTmp;
+ if( aTmp.Create( rSalBitmap, this ) )
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, aTmp, FALSE, SRCPAINT );
+ }
+ else
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, rSalBitmap, FALSE, SRCPAINT );
+ }
+ else
+ {
+ SalTwoRect aPosAry = *pPosAry;
+ int nDstX = (int)aPosAry.mnDestX;
+ int nDstY = (int)aPosAry.mnDestY;
+ int nDstWidth = (int)aPosAry.mnDestWidth;
+ int nDstHeight = (int)aPosAry.mnDestHeight;
+ HDC hDC = maGraphicsData.mhDC;
+ HBITMAP hMemBitmap = 0;
+ HBITMAP hMaskBitmap = 0;
+
+ if( ( nDstWidth > CACHED_HDC_DEFEXT ) || ( nDstHeight > CACHED_HDC_DEFEXT ) )
+ {
+ hMemBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
+ hMaskBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
+ }
+
+ HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, hMemBitmap );
+ HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_2, hMaskBitmap );
+
+ aPosAry.mnDestX = aPosAry.mnDestY = 0;
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hDC, nDstX, nDstY, SRCCOPY );
+
+ // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
+ // die Farben der Maske richtig auf die Palette abzubilden,
+ // wenn wir die DIB direkt ausgeben => DDB-Ausgabe
+ if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 )
+ {
+ SalBitmap aTmp;
+
+ if( aTmp.Create( rTransparentBitmap, this ) )
+ ImplDrawBitmap( hMaskDC, &aPosAry, aTmp, FALSE, SRCCOPY );
+ }
+ else
+ ImplDrawBitmap( hMaskDC, &aPosAry, rTransparentBitmap, FALSE, SRCCOPY );
+
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCAND );
+ ImplDrawBitmap( hMaskDC, &aPosAry, rSalBitmap, FALSE, SRCERASE );
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCPAINT );
+ BitBlt( hDC, nDstX, nDstY, nDstWidth, nDstHeight, hMemDC, 0, 0, SRCCOPY );
+
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+ ImplReleaseCachedDC( CACHED_HDC_2 );
+
+ // hMemBitmap != 0 ==> hMaskBitmap != 0
+ if( hMemBitmap )
+ {
+ DeleteObject( hMemBitmap );
+ DeleteObject( hMaskBitmap );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawMask( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor )
+{
+ DBG_ASSERT( !maGraphicsData.mbPrinter, "No transparency print possible!" );
+
+ SalTwoRect aPosAry = *pPosAry;
+ const BYTE cRed = SALCOLOR_RED( nMaskColor );
+ const BYTE cGreen = SALCOLOR_GREEN( nMaskColor );
+ const BYTE cBlue = SALCOLOR_BLUE( nMaskColor );
+ HDC hDC = maGraphicsData.mhDC;
+ HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) );
+ HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush );
+
+ // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
+ // die Farben der Maske richtig auf die Palette abzubilden,
+ // wenn wir die DIB direkt ausgeben => DDB-Ausgabe
+ if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 )
+ {
+ SalBitmap aTmp;
+
+ if( aTmp.Create( rSalBitmap, this ) )
+ ImplDrawBitmap( hDC, &aPosAry, aTmp, FALSE, 0x00B8074AUL );
+ }
+ else
+ ImplDrawBitmap( hDC, &aPosAry, rSalBitmap, FALSE, 0x00B8074AUL );
+
+ SelectBrush( hDC, hOldBrush );
+ DeleteBrush( hMaskBrush );
+}
+
+// -----------------------------------------------------------------------
+
+SalBitmap* SalGraphics::GetBitmap( long nX, long nY, long nDX, long nDY )
+{
+ DBG_ASSERT( !maGraphicsData.mbPrinter, "No ::GetBitmap() from printer possible!" );
+
+ SalBitmap* pSalBitmap = NULL;
+
+ nDX = labs( nDX );
+ nDY = labs( nDY );
+
+ HDC hDC = maGraphicsData.mhDC;
+ HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY );
+ HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap );
+ BOOL bRet;
+
+ bRet = BitBlt( hBmpDC, 0, 0, (int) nDX, (int) nDY, hDC, (int) nX, (int) nY, SRCCOPY );
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+
+ if( bRet )
+ {
+ pSalBitmap = new SalBitmap;
+
+ if( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) )
+ {
+ delete pSalBitmap;
+ pSalBitmap = NULL;
+ }
+ }
+
+ return pSalBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+SalColor SalGraphics::GetPixel( long nX, long nY )
+{
+ COLORREF aWinCol = ::GetPixel( maGraphicsData.mhDC, (int) nX, (int) nY );
+
+#ifdef WIN
+ if ( -1 == aWinCol )
+#else
+ if ( CLR_INVALID == aWinCol )
+#endif
+ return MAKE_SALCOLOR( 0, 0, 0 );
+ else
+ return MAKE_SALCOLOR( GetRValue( aWinCol ),
+ GetGValue( aWinCol ),
+ GetBValue( aWinCol ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::Invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
+{
+ if ( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+ HPEN hDotPen = CreatePen( PS_DOT, 0, 0 );
+ HPEN hOldPen = SelectPen( maGraphicsData.mhDC, hDotPen );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, GetStockBrush( NULL_BRUSH ) );
+ int nOldROP = SetROP2( maGraphicsData.mhDC, R2_NOT );
+
+ WIN_Rectangle( maGraphicsData.mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
+
+ SetROP2( maGraphicsData.mhDC, nOldROP );
+ SelectPen( maGraphicsData.mhDC, hOldPen );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeletePen( hDotPen );
+ }
+ else if ( nFlags & SAL_INVERT_50 )
+ {
+ SalData* pSalData = GetSalData();
+ if ( !pSalData->mh50Brush )
+ {
+ if ( !pSalData->mh50Bmp )
+ pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
+ pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
+ }
+
+ COLORREF nOldTextColor = ::SetTextColor( maGraphicsData.mhDC, 0 );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, pSalData->mh50Brush );
+ PatBlt( maGraphicsData.mhDC, nX, nY, nWidth, nHeight, PATINVERT );
+ ::SetTextColor( maGraphicsData.mhDC, nOldTextColor );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ }
+ else
+ {
+ RECT aRect;
+ aRect.left = (int)nX;
+ aRect.top = (int)nY;
+ aRect.right = (int)nX+nWidth;
+ aRect.bottom = (int)nY+nHeight;
+ ::InvertRect( maGraphicsData.mhDC, &aRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::Invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert nSalFlags )
+{
+ HPEN hPen;
+ HPEN hOldPen;
+ HBRUSH hBrush;
+ HBRUSH hOldBrush;
+ COLORREF nOldTextColor;
+ int nOldROP = SetROP2( maGraphicsData.mhDC, R2_NOT );
+
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ hPen = CreatePen( PS_DOT, 0, 0 );
+ else
+ {
+
+ if ( nSalFlags & SAL_INVERT_50 )
+ {
+ SalData* pSalData = GetSalData();
+ if ( !pSalData->mh50Brush )
+ {
+ if ( !pSalData->mh50Bmp )
+ pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
+ pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
+ }
+
+ hBrush = pSalData->mh50Brush;
+ }
+ else
+ hBrush = GetStockBrush( BLACK_BRUSH );
+
+ hPen = GetStockPen( NULL_PEN );
+ nOldTextColor = ::SetTextColor( maGraphicsData.mhDC, 0 );
+ hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ }
+ hOldPen = SelectPen( maGraphicsData.mhDC, hPen );
+
+ POINT* pWinPtAry;
+#ifdef WIN
+ if ( nPoints > MAX_64KSALPOINTS )
+ nPoints = MAX_64KSALPOINTS;
+
+ pWinPtAry = new POINT[(USHORT)nPoints];
+ const SalPoint huge* pHugePtAry = (const SalPoint huge*)pPtAry;
+ for( USHORT i=0; i < (USHORT)nPoints ; i++ )
+ {
+ pWinPtAry[i].x = (int)pHugePtAry[i].mnX;
+ pWinPtAry[i].y = (int)pHugePtAry[i].mnY;
+ }
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ Polyline( maGraphicsData.mhDC, pWinPtAry, (int)nPoints );
+ else
+ WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, (int)nPoints );
+ delete pWinPtAry;
+#else
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolyLine(): POINT != SalPoint" );
+
+ pWinPtAry = (POINT*)pPtAry;
+ // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
+ // von Punkten
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ {
+ if ( !Polyline( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ Polyline( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+ }
+ else
+ {
+ if ( !WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+ }
+#endif
+
+ SetROP2( maGraphicsData.mhDC, nOldROP );
+ SelectPen( maGraphicsData.mhDC, hOldPen );
+
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ DeletePen( hPen );
+ else
+ {
+ ::SetTextColor( maGraphicsData.mhDC, nOldTextColor );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ }
+}
diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx
new file mode 100644
index 000000000000..aa6b4c347090
--- /dev/null
+++ b/vcl/win/source/gdi/salgdi3.cxx
@@ -0,0 +1,1531 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi3.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALGDI3_CXX
+
+#ifndef _RTL_TENCINFO_H
+#include <rtl/tencinfo.h>
+#endif
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+#ifndef _SV_FONT_HXX
+#include <font.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#ifdef WIN
+#define GDI_ERROR (0xFFFFFFFFUL)
+#endif
+
+#define GLYPH_INC (512UL)
+#define MAX_POLYCOUNT (2048UL)
+#define CHECKPOINTS( _def_nPnt ) \
+ if( (_def_nPnt) >= nPtSize ) \
+ nPtSize = ImplIncreaseArrays( nPtSize, &pPoints, &pFlags, GLYPH_INC )
+
+// -----------
+// - Inlines -
+// -----------
+
+inline FIXED FixedFromDouble( double d )
+{
+ const long l = (long) ( d * 65536. );
+ return *(FIXED*) &l;
+}
+
+// -----------------------------------------------------------------------
+
+inline int IntFromFixed(FIXED f)
+{
+ return( ( f.fract >= 0x8000 ) ? ( f.value + 1 ) : f.value );
+}
+
+// -----------------------------------------------------------------------
+
+inline FIXED fxDiv2( FIXED fxVal1, FIXED fxVal2 )
+{
+ const long l = (*((long far *)&(fxVal1)) + *((long far *)&(fxVal2))) >> 1;
+ return *(FIXED*) &l;
+}
+
+// =======================================================================
+
+#define SAL_DRAWTEXT_STACKBUF 128
+
+// =======================================================================
+
+// Diese Variablen koennen static sein, da systemweite Einstellungen
+// gemerkt werden
+static BOOL bImplSalCourierScalable = FALSE;
+static BOOL bImplSalCourierNew = FALSE;
+
+// =======================================================================
+
+struct ImplEnumInfo
+{
+ HDC mhDC;
+ ImplDevFontList* mpList;
+ XubString* mpName;
+ LOGFONTA* mpLogFontA;
+ LOGFONTW* mpLogFontW;
+ BOOL mbCourier;
+ BOOL mbImplSalCourierScalable;
+ BOOL mbImplSalCourierNew;
+ BOOL mbPrinter;
+};
+
+// =======================================================================
+
+static CharSet ImplCharSetToSal( BYTE nCharSet )
+{
+ if ( nCharSet == OEM_CHARSET )
+ {
+ UINT nCP = (USHORT)GetOEMCP();
+ return rtl_getTextEncodingFromPCCodePage( nCP );
+ }
+ else
+ return rtl_getTextEncodingFromWindowsCharset( nCharSet );
+}
+
+// -----------------------------------------------------------------------
+
+static BYTE ImplCharSetToWin( CharSet eCharSet )
+{
+ return rtl_getBestWindowsCharsetFromTextEncoding( eCharSet );
+}
+
+// -----------------------------------------------------------------------
+
+static FontFamily ImplFamilyToSal( BYTE nFamily )
+{
+ switch ( nFamily & 0xF0 )
+ {
+ case FF_DECORATIVE:
+ return FAMILY_DECORATIVE;
+
+ case FF_MODERN:
+ return FAMILY_MODERN;
+
+ case FF_ROMAN:
+ return FAMILY_ROMAN;
+
+ case FF_SCRIPT:
+ return FAMILY_SCRIPT;
+
+ case FF_SWISS:
+ return FAMILY_SWISS;
+ }
+
+ return FAMILY_DONTKNOW;
+}
+
+// -----------------------------------------------------------------------
+
+static BYTE ImplFamilyToWin( FontFamily eFamily )
+{
+ switch ( eFamily )
+ {
+ case FAMILY_DECORATIVE:
+ return FF_DECORATIVE;
+
+ case FAMILY_MODERN:
+ return FF_MODERN;
+
+ case FAMILY_ROMAN:
+ return FF_ROMAN;
+
+ case FAMILY_SCRIPT:
+ return FF_SCRIPT;
+
+ case FAMILY_SWISS:
+ return FF_SWISS;
+
+ case FAMILY_SYSTEM:
+ return FF_SWISS;
+ }
+
+ return FF_DONTCARE;
+}
+
+// -----------------------------------------------------------------------
+
+static FontWeight ImplWeightToSal( WinWeight nWeight )
+{
+ if ( nWeight <= FW_THIN )
+ return WEIGHT_THIN;
+ else if ( nWeight <= FW_ULTRALIGHT )
+ return WEIGHT_ULTRALIGHT;
+ else if ( nWeight <= FW_LIGHT )
+ return WEIGHT_LIGHT;
+ else if ( nWeight < FW_MEDIUM )
+ return WEIGHT_NORMAL;
+ else if ( nWeight == FW_MEDIUM )
+ return WEIGHT_MEDIUM;
+ else if ( nWeight <= FW_SEMIBOLD )
+ return WEIGHT_SEMIBOLD;
+ else if ( nWeight <= FW_BOLD )
+ return WEIGHT_BOLD;
+ else if ( nWeight <= FW_ULTRABOLD )
+ return WEIGHT_ULTRABOLD;
+ else
+ return WEIGHT_BLACK;
+}
+
+// -----------------------------------------------------------------------
+
+static WinWeight ImplWeightToWin( FontWeight eWeight )
+{
+ switch ( eWeight )
+ {
+ case WEIGHT_THIN:
+ return FW_THIN;
+
+ case WEIGHT_ULTRALIGHT:
+ return FW_ULTRALIGHT;
+
+ case WEIGHT_LIGHT:
+ return FW_LIGHT;
+
+ case WEIGHT_SEMILIGHT:
+ case WEIGHT_NORMAL:
+ return FW_NORMAL;
+
+ case WEIGHT_MEDIUM:
+ return FW_MEDIUM;
+
+ case WEIGHT_SEMIBOLD:
+ return FW_SEMIBOLD;
+
+ case WEIGHT_BOLD:
+ return FW_BOLD;
+
+ case WEIGHT_ULTRABOLD:
+ return FW_ULTRABOLD;
+
+ case WEIGHT_BLACK:
+ return FW_BLACK;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+inline FontPitch ImplLogPitchToSal( BYTE nPitch )
+{
+ if ( nPitch & FIXED_PITCH )
+ return PITCH_FIXED;
+ else
+ return PITCH_VARIABLE;
+}
+
+// -----------------------------------------------------------------------
+
+inline FontPitch ImplMetricPitchToSal( BYTE nPitch )
+{
+ // Sausaecke bei MS !! siehe NT Hilfe
+ if ( !(nPitch & TMPF_FIXED_PITCH) )
+ return PITCH_FIXED;
+ else
+ return PITCH_VARIABLE;
+}
+
+// -----------------------------------------------------------------------
+
+inline BYTE ImplPitchToWin( FontPitch ePitch )
+{
+ if ( ePitch == PITCH_FIXED )
+ return FIXED_PITCH;
+ else if ( ePitch == PITCH_VARIABLE )
+ return VARIABLE_PITCH;
+ else
+ return DEFAULT_PITCH;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplLogMetricToDevFontDataA( const LOGFONTA* pLogFont,
+ const NEWTEXTMETRICA* pMetric,
+ DWORD nFontType,
+ ImplFontData* pData )
+{
+ if ( !(nFontType & RASTER_FONTTYPE) )
+ {
+ pData->mnWidth = 0;
+ pData->mnHeight = 0;
+ }
+ else
+ {
+ pData->mnWidth = 0;
+ pData->mnHeight = pMetric->tmHeight-pMetric->tmInternalLeading;
+ }
+ pData->meFamily = ImplFamilyToSal( pLogFont->lfPitchAndFamily );
+ pData->meCharSet = ImplCharSetToSal( pLogFont->lfCharSet );
+ pData->meWidthType = WIDTH_DONTKNOW;
+ pData->meWeight = ImplWeightToSal( pLogFont->lfWeight );
+ pData->meItalic = (pLogFont->lfItalic) ? ITALIC_NORMAL : ITALIC_NONE;
+ pData->mePitch = ImplLogPitchToSal( pLogFont->lfPitchAndFamily );
+ if ( pMetric->tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE) )
+ pData->meType = TYPE_SCALABLE;
+ else
+ pData->meType = TYPE_RASTER;
+ pData->mbOrientation = (nFontType & RASTER_FONTTYPE) == 0;
+ pData->mbDevice = (pMetric->tmPitchAndFamily & TMPF_DEVICE) != 0;
+ pData->mnQuality = 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplLogMetricToDevFontDataW( const LOGFONTW* pLogFont,
+ const NEWTEXTMETRICW* pMetric,
+ DWORD nFontType,
+ ImplFontData* pData )
+{
+ if ( !(nFontType & RASTER_FONTTYPE) )
+ {
+ pData->mnWidth = 0;
+ pData->mnHeight = 0;
+ }
+ else
+ {
+ pData->mnWidth = 0;
+ pData->mnHeight = pMetric->tmHeight-pMetric->tmInternalLeading;
+ }
+ pData->meFamily = ImplFamilyToSal( pLogFont->lfPitchAndFamily );
+ pData->meCharSet = ImplCharSetToSal( pLogFont->lfCharSet );
+ pData->meWidthType = WIDTH_DONTKNOW;
+ pData->meWeight = ImplWeightToSal( pLogFont->lfWeight );
+ pData->meItalic = (pLogFont->lfItalic) ? ITALIC_NORMAL : ITALIC_NONE;
+ pData->mePitch = ImplLogPitchToSal( pLogFont->lfPitchAndFamily );
+ if ( pMetric->tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE) )
+ pData->meType = TYPE_SCALABLE;
+ else
+ pData->meType = TYPE_RASTER;
+ pData->mbOrientation = (nFontType & RASTER_FONTTYPE) == 0;
+ pData->mbDevice = (pMetric->tmPitchAndFamily & TMPF_DEVICE) != 0;
+ pData->mnQuality = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalLogFontToFontA( const LOGFONTA& rLogFont, Font& rFont )
+{
+ XubString aFontName( ImplSalGetUniString( rLogFont.lfFaceName ) );
+ if ( aFontName.Len() )
+ {
+ rFont.SetName( aFontName );
+ long nFontHeight = rLogFont.lfHeight;
+ if ( nFontHeight < 0 )
+ nFontHeight = -nFontHeight;
+ HDC hDC = GetDC( 0 );
+ long nDPIY = GetDeviceCaps( hDC, LOGPIXELSY );
+ ReleaseDC( 0, hDC );
+ nFontHeight *= 72;
+ nFontHeight += nDPIY/2;
+ nFontHeight /= nDPIY;
+ rFont.SetSize( Size( 0, nFontHeight ) );
+ rFont.SetOrientation( (short)rLogFont.lfEscapement );
+ rFont.SetCharSet( ImplCharSetToSal( rLogFont.lfCharSet ) );
+ rFont.SetFamily( ImplFamilyToSal( rLogFont.lfPitchAndFamily ) );
+ rFont.SetPitch( ImplLogPitchToSal( rLogFont.lfPitchAndFamily ) );
+ rFont.SetWeight( ImplWeightToSal( rLogFont.lfWeight ) );
+ if ( rLogFont.lfItalic )
+ rFont.SetItalic( ITALIC_NORMAL );
+ else
+ rFont.SetItalic( ITALIC_NONE );
+ if ( rLogFont.lfUnderline )
+ rFont.SetUnderline( UNDERLINE_SINGLE );
+ else
+ rFont.SetUnderline( UNDERLINE_NONE );
+ if ( rLogFont.lfStrikeOut )
+ rFont.SetStrikeout( STRIKEOUT_SINGLE );
+ else
+ rFont.SetStrikeout( STRIKEOUT_NONE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalLogFontToFontW( const LOGFONTW& rLogFont, Font& rFont )
+{
+ XubString aFontName( rLogFont.lfFaceName );
+ if ( aFontName.Len() )
+ {
+ rFont.SetName( aFontName );
+ long nFontHeight = rLogFont.lfHeight;
+ if ( nFontHeight < 0 )
+ nFontHeight = -nFontHeight;
+ HDC hDC = GetDC( 0 );
+ long nDPIY = GetDeviceCaps( hDC, LOGPIXELSY );
+ ReleaseDC( 0, hDC );
+ nFontHeight *= 72;
+ nFontHeight += nDPIY/2;
+ nFontHeight /= nDPIY;
+ rFont.SetSize( Size( 0, nFontHeight ) );
+ rFont.SetOrientation( (short)rLogFont.lfEscapement );
+ rFont.SetCharSet( ImplCharSetToSal( rLogFont.lfCharSet ) );
+ rFont.SetFamily( ImplFamilyToSal( rLogFont.lfPitchAndFamily ) );
+ rFont.SetPitch( ImplLogPitchToSal( rLogFont.lfPitchAndFamily ) );
+ rFont.SetWeight( ImplWeightToSal( rLogFont.lfWeight ) );
+ if ( rLogFont.lfItalic )
+ rFont.SetItalic( ITALIC_NORMAL );
+ else
+ rFont.SetItalic( ITALIC_NONE );
+ if ( rLogFont.lfUnderline )
+ rFont.SetUnderline( UNDERLINE_SINGLE );
+ else
+ rFont.SetUnderline( UNDERLINE_NONE );
+ if ( rLogFont.lfStrikeOut )
+ rFont.SetStrikeout( STRIKEOUT_SINGLE );
+ else
+ rFont.SetStrikeout( STRIKEOUT_NONE );
+ }
+}
+
+// =======================================================================
+
+void SalGraphics::SetTextColor( SalColor nSalColor )
+{
+ COLORREF aCol = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ if( !maGraphicsData.mbPrinter &&
+ GetSalData()->mhDitherPal &&
+ ImplIsSysColorEntry( nSalColor ) )
+ {
+ aCol = PALRGB_TO_RGB( aCol );
+ }
+
+ ::SetTextColor( maGraphicsData.mhDC, aCol );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalGraphics::SetFont( ImplFontSelectData* pFont )
+{
+ HFONT hNewFont;
+ if ( aSalShlData.mbWNT )
+ {
+ LOGFONTW aLogFont;
+ UniString aName;
+ if ( pFont->mpFontData )
+ aName = pFont->mpFontData->maName;
+ else
+ aName = pFont->maName.GetToken( 0 );
+
+ UINT nNameLen = aName.Len();
+ if ( nNameLen > (sizeof( aLogFont.lfFaceName )/sizeof( wchar_t ))-1 )
+ nNameLen = (sizeof( aLogFont.lfFaceName )/sizeof( wchar_t ))-1;
+ memcpy( aLogFont.lfFaceName, aName.GetBuffer(), nNameLen*sizeof( wchar_t ) );
+ aLogFont.lfFaceName[nNameLen] = 0;
+ if ( pFont->mpFontData &&
+ ((pFont->meCharSet == RTL_TEXTENCODING_DONTKNOW) ||
+ ((WIN_BYTE)(pFont->mpFontData->mpSysData) == OEM_CHARSET)) )
+ aLogFont.lfCharSet = (WIN_BYTE)(pFont->mpFontData->mpSysData);
+ else
+ aLogFont.lfCharSet = ImplCharSetToWin( pFont->meCharSet );
+ aLogFont.lfPitchAndFamily = ImplPitchToWin( pFont->mePitch );
+ aLogFont.lfPitchAndFamily |= ImplFamilyToWin( pFont->meFamily );
+ aLogFont.lfWeight = ImplWeightToWin( pFont->meWeight );
+ aLogFont.lfHeight = (int)-pFont->mnHeight;
+ aLogFont.lfWidth = (int)pFont->mnWidth;
+ aLogFont.lfUnderline = 0;
+ aLogFont.lfStrikeOut = 0;
+ aLogFont.lfItalic = (pFont->meItalic) != ITALIC_NONE;
+ aLogFont.lfEscapement = pFont->mnOrientation;
+ aLogFont.lfOrientation = 0;
+ aLogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ aLogFont.lfQuality = DEFAULT_QUALITY;
+ if ( pFont->mnOrientation )
+ {
+ aLogFont.lfOutPrecision = OUT_TT_PRECIS;
+ aLogFont.lfClipPrecision |= CLIP_LH_ANGLES;
+ }
+ else
+ aLogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
+
+ // Auf dem Bildschirm nehmen wir Courier New, wenn Courier nicht
+ // skalierbar ist und wenn der Font skaliert oder rotiert werden
+ // muss
+ if ( maGraphicsData.mbScreen &&
+ (pFont->mnWidth || pFont->mnOrientation ||
+ !pFont->mpFontData || (pFont->mpFontData->mnHeight != pFont->mnHeight)) &&
+ !bImplSalCourierScalable && bImplSalCourierNew &&
+ (ImplSalWICompareAscii( aLogFont.lfFaceName, "Courier" ) == 0) )
+ lstrcpyW( aLogFont.lfFaceName, L"Courier New" );
+
+ hNewFont = CreateFontIndirectW( &aLogFont );
+ }
+ else
+ {
+ if ( !maGraphicsData.mpLogFont )
+ maGraphicsData.mpLogFont = new LOGFONTA;
+
+ ByteString aName;
+ if ( pFont->mpFontData )
+ aName = ImplSalGetWinAnsiString( pFont->mpFontData->maName );
+ else
+ aName = ImplSalGetWinAnsiString( pFont->maName.GetToken( 0 ) );
+ UINT nNameLen = aName.Len();
+ if ( nNameLen > sizeof( maGraphicsData.mpLogFont->lfFaceName )-1 )
+ nNameLen = sizeof( maGraphicsData.mpLogFont->lfFaceName )-1;
+ memcpy( maGraphicsData.mpLogFont->lfFaceName, aName.GetBuffer(), nNameLen );
+ maGraphicsData.mpLogFont->lfFaceName[nNameLen] = 0;
+ if ( pFont->mpFontData &&
+ ((pFont->meCharSet == RTL_TEXTENCODING_DONTKNOW) ||
+ ((WIN_BYTE)(pFont->mpFontData->mpSysData) == OEM_CHARSET)) )
+ maGraphicsData.mpLogFont->lfCharSet = (WIN_BYTE)(pFont->mpFontData->mpSysData);
+ else
+ maGraphicsData.mpLogFont->lfCharSet = ImplCharSetToWin( pFont->meCharSet );
+ maGraphicsData.mpLogFont->lfPitchAndFamily = ImplPitchToWin( pFont->mePitch );
+ maGraphicsData.mpLogFont->lfPitchAndFamily |= ImplFamilyToWin( pFont->meFamily );
+ maGraphicsData.mpLogFont->lfWeight = ImplWeightToWin( pFont->meWeight );
+ maGraphicsData.mpLogFont->lfHeight = (int)-pFont->mnHeight;
+ maGraphicsData.mpLogFont->lfWidth = (int)pFont->mnWidth;
+ maGraphicsData.mpLogFont->lfUnderline = 0;
+ maGraphicsData.mpLogFont->lfStrikeOut = 0;
+ maGraphicsData.mpLogFont->lfItalic = (pFont->meItalic) != ITALIC_NONE;
+ maGraphicsData.mpLogFont->lfEscapement = pFont->mnOrientation;
+ maGraphicsData.mpLogFont->lfOrientation = 0;
+ maGraphicsData.mpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ maGraphicsData.mpLogFont->lfQuality = DEFAULT_QUALITY;
+ if ( pFont->mnOrientation )
+ {
+ maGraphicsData.mpLogFont->lfOutPrecision = OUT_TT_PRECIS;
+ maGraphicsData.mpLogFont->lfClipPrecision |= CLIP_LH_ANGLES;
+ }
+ else
+ maGraphicsData.mpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
+
+ // Auf dem Bildschirm nehmen wir Courier New, wenn Courier nicht
+ // skalierbar ist und wenn der Font skaliert oder rotiert werden
+ // muss
+ if ( maGraphicsData.mbScreen &&
+ (pFont->mnWidth || pFont->mnOrientation ||
+ !pFont->mpFontData || (pFont->mpFontData->mnHeight != pFont->mnHeight)) &&
+ !bImplSalCourierScalable && bImplSalCourierNew &&
+ (stricmp( maGraphicsData.mpLogFont->lfFaceName, "Courier" ) == 0) )
+ strcpy( maGraphicsData.mpLogFont->lfFaceName, "Courier New" );
+
+ hNewFont = CreateFontIndirectA( maGraphicsData.mpLogFont );
+ }
+
+ HFONT hOldFont = SelectFont( maGraphicsData.mhDC, hNewFont );
+
+ // destory or save old font
+ if ( maGraphicsData.mhFont )
+ DeleteFont( maGraphicsData.mhFont );
+ else
+ maGraphicsData.mhDefFont = hOldFont;
+
+ // set new data
+ maGraphicsData.mhFont = hNewFont;
+ maGraphicsData.mbCalcOverhang = TRUE;
+
+ maGraphicsData.mnFontCharSetCount = 0;
+ maGraphicsData.mbFontKernInit = TRUE;
+ if ( maGraphicsData.mpFontKernPairs )
+ {
+ delete maGraphicsData.mpFontKernPairs;
+ maGraphicsData.mpFontKernPairs = 0;
+ }
+ maGraphicsData.mnFontKernPairCount = 0;
+
+ // Auf dem Printer immer mit DrawTextArray arbeiten, da dort die
+ // Zeichenbreiten genauer als Pixel sein koennen
+ if ( maGraphicsData.mbPrinter )
+ return SAL_SETFONT_USEDRAWTEXTARRAY;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long SalGraphics::GetCharWidth( sal_Unicode nChar1, sal_Unicode nChar2, long* pWidthAry )
+{
+ SIZE aExtent;
+ SIZE aExtent2;
+ sal_Unicode nCharCount = nChar2-nChar1+1;
+ sal_Unicode i;
+ int* pWinWidthAry = (int*)pWidthAry;
+ DBG_ASSERT( sizeof( int ) == sizeof( long ), "SalGraphics::GetCharWidth(): int != long" );
+
+ // Da nicht bei allen Treibern diese Funktion funktioniert
+ if ( !GetCharWidthW( maGraphicsData.mhDC, nChar1, nChar2, pWinWidthAry ) )
+ {
+ for ( i = 0; i < nCharCount; i++ )
+ {
+ WCHAR c =i+nChar1;
+ if ( !GetTextExtentPointW( maGraphicsData.mhDC, &c, 1, &aExtent ) )
+ pWinWidthAry[i] = 0;
+ else
+ pWinWidthAry[i] = aExtent.cx;
+ }
+ }
+
+ // Ueberhang abziehen
+ if ( maGraphicsData.mbCalcOverhang )
+ {
+ WCHAR aAA[2] = { 'A', 'A' };
+ if ( GetTextExtentPointW( maGraphicsData.mhDC, aAA, 2, &aExtent ) &&
+ GetTextExtentPointW( maGraphicsData.mhDC, aAA, 1, &aExtent2 ) )
+ {
+ maGraphicsData.mbCalcOverhang = FALSE;
+ maGraphicsData.mnFontOverhang = (aExtent2.cx*2)-aExtent.cx;
+ }
+
+ int nOverhang = maGraphicsData.mnFontOverhang;
+ if ( nOverhang )
+ {
+ for ( i = 0; i < nCharCount; i++ )
+ pWinWidthAry[i] -= nOverhang;
+ }
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetFontMetric( ImplFontMetricData* pMetric )
+{
+ if ( aSalShlData.mbWNT )
+ {
+ wchar_t aFaceName[LF_FACESIZE+60];
+ GetTextFaceW( maGraphicsData.mhDC, sizeof( aFaceName ), aFaceName );
+ pMetric->maName = aFaceName;
+
+ TEXTMETRICW aWinMetric;
+ GetTextMetricsW( maGraphicsData.mhDC, &aWinMetric );
+
+ pMetric->mnWidth = aWinMetric.tmAveCharWidth;
+ pMetric->meFamily = ImplFamilyToSal( aWinMetric.tmPitchAndFamily );;
+ pMetric->meCharSet = ImplCharSetToSal( aWinMetric.tmCharSet );
+ pMetric->meWeight = ImplWeightToSal( aWinMetric.tmWeight );
+ pMetric->mePitch = ImplMetricPitchToSal( aWinMetric.tmPitchAndFamily );
+ if ( aWinMetric.tmItalic )
+ pMetric->meItalic = ITALIC_NORMAL;
+ else
+ pMetric->meItalic = ITALIC_NONE;
+ if ( aWinMetric.tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE) )
+ pMetric->meType = TYPE_SCALABLE;
+ else
+ {
+ pMetric->meType = TYPE_RASTER;
+ pMetric->mnOrientation = 0;
+ }
+ pMetric->mbDevice = (aWinMetric.tmPitchAndFamily & TMPF_DEVICE) != 0;
+ pMetric->mnAscent = aWinMetric.tmAscent;
+ pMetric->mnDescent = aWinMetric.tmDescent;
+ pMetric->mnLeading = aWinMetric.tmInternalLeading;
+ pMetric->mnSlant = 0;
+ pMetric->mnFirstChar = 0;
+ pMetric->mnLastChar = 0xFF;
+ }
+ else
+ {
+ char aFaceName[LF_FACESIZE+60];
+ GetTextFaceA( maGraphicsData.mhDC, sizeof( aFaceName ), aFaceName );
+ pMetric->maName = ImplSalGetUniString( aFaceName );
+
+ TEXTMETRICA aWinMetric;
+ GetTextMetricsA( maGraphicsData.mhDC, &aWinMetric );
+
+ pMetric->mnWidth = aWinMetric.tmAveCharWidth;
+ pMetric->meFamily = ImplFamilyToSal( aWinMetric.tmPitchAndFamily );;
+ pMetric->meCharSet = ImplCharSetToSal( aWinMetric.tmCharSet );
+ pMetric->meWeight = ImplWeightToSal( aWinMetric.tmWeight );
+ pMetric->mePitch = ImplMetricPitchToSal( aWinMetric.tmPitchAndFamily );
+ if ( aWinMetric.tmItalic )
+ pMetric->meItalic = ITALIC_NORMAL;
+ else
+ pMetric->meItalic = ITALIC_NONE;
+ if ( aWinMetric.tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE) )
+ pMetric->meType = TYPE_SCALABLE;
+ else
+ {
+ pMetric->meType = TYPE_RASTER;
+ pMetric->mnOrientation = 0;
+ }
+ pMetric->mbDevice = (aWinMetric.tmPitchAndFamily & TMPF_DEVICE) != 0;
+ pMetric->mnAscent = aWinMetric.tmAscent;
+ pMetric->mnDescent = aWinMetric.tmDescent;
+ pMetric->mnLeading = aWinMetric.tmInternalLeading;
+ pMetric->mnSlant = 0;
+ pMetric->mnFirstChar = 0;
+ pMetric->mnLastChar = 0xFF;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+int CALLBACK SalEnumCharSetsProcExA( const ENUMLOGFONTEXA* pLogFont,
+ const NEWTEXTMETRICEXA* pMetric,
+ DWORD nFontType, LPARAM lParam )
+{
+ SalGraphicsData* pData = (SalGraphicsData*)lParam;
+ // Charset already in the list?
+ for ( BYTE i = 0; i < pData->mnFontCharSetCount; i++ )
+ {
+ if ( pData->mpFontCharSets[i] == pLogFont->elfLogFont.lfCharSet )
+ return 1;
+ }
+ pData->mpFontCharSets[pData->mnFontCharSetCount] = pLogFont->elfLogFont.lfCharSet;
+ pData->mnFontCharSetCount++;
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetAllFontCharSets( SalGraphicsData* pData )
+{
+ if ( !pData->mpFontCharSets )
+ pData->mpFontCharSets = new BYTE[256];
+
+ LOGFONTA aLogFont;
+ memset( &aLogFont, 0, sizeof( aLogFont ) );
+ aLogFont.lfCharSet = DEFAULT_CHARSET;
+ GetTextFace( pData->mhDC, sizeof( aLogFont.lfFaceName ), aLogFont.lfFaceName );
+ EnumFontFamiliesExA( pData->mhDC, &aLogFont, (FONTENUMPROCA)SalEnumCharSetsProcExA,
+ (LPARAM)(void*)pData, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplAddKerningPairs( SalGraphicsData* pData )
+{
+ ULONG nPairs = ::GetKerningPairsA( pData->mhDC, 0, NULL );
+ if ( !nPairs )
+ return;
+
+ CHARSETINFO aInfo;
+ if ( !TranslateCharsetInfo( (DWORD*)(ULONG)GetTextCharset( pData->mhDC ), &aInfo, TCI_SRCCHARSET ) )
+ return;
+
+ if ( !pData->mpFontKernPairs )
+ pData->mpFontKernPairs = new KERNINGPAIR[nPairs];
+ else
+ {
+ KERNINGPAIR* pOldPairs = pData->mpFontKernPairs;
+ pData->mpFontKernPairs = new KERNINGPAIR[nPairs+pData->mnFontKernPairCount];
+ memcpy( pData->mpFontKernPairs, pOldPairs,
+ pData->mnFontKernPairCount*sizeof( KERNINGPAIR ) );
+ delete pOldPairs;
+ }
+
+ UINT nCP = aInfo.ciACP;
+ ULONG nOldPairs = pData->mnFontKernPairCount;
+ KERNINGPAIR* pTempPair = pData->mpFontKernPairs+pData->mnFontKernPairCount;
+ nPairs = ::GetKerningPairsA( pData->mhDC, nPairs, pTempPair );
+ for ( ULONG i = 0; i < nPairs; i++ )
+ {
+ unsigned char aBuf[2];
+ wchar_t nChar;
+ int nLen;
+ BOOL bAdd = TRUE;
+
+ // None-ASCII?, then we must convert the char
+ if ( (pTempPair->wFirst > 125) || (pTempPair->wFirst == 92) )
+ {
+ if ( pTempPair->wFirst < 256 )
+ {
+ aBuf[0] = (unsigned char)pTempPair->wFirst;
+ nLen = 1;
+ }
+ else
+ {
+ aBuf[0] = (unsigned char)(pTempPair->wFirst >> 8);
+ aBuf[1] = (unsigned char)(pTempPair->wFirst & 0xFF);
+ nLen = 2;
+ }
+ if ( MultiByteToWideChar( nCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS,
+ (const char*)aBuf, nLen, &nChar, 1 ) )
+ pTempPair->wFirst = nChar;
+ else
+ bAdd = FALSE;
+ }
+ if ( (pTempPair->wSecond > 125) || (pTempPair->wSecond == 92) )
+ {
+ if ( pTempPair->wSecond < 256 )
+ {
+ aBuf[0] = (unsigned char)pTempPair->wSecond;
+ nLen = 1;
+ }
+ else
+ {
+ aBuf[0] = (unsigned char)(pTempPair->wSecond >> 8);
+ aBuf[1] = (unsigned char)(pTempPair->wSecond & 0xFF);
+ nLen = 2;
+ }
+ if ( MultiByteToWideChar( nCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS,
+ (const char*)aBuf, nLen, &nChar, 1 ) )
+ pTempPair->wSecond = nChar;
+ else
+ bAdd = FALSE;
+ }
+
+ KERNINGPAIR* pTempPair2 = pData->mpFontKernPairs;
+ for ( ULONG j = 0; j < nOldPairs; j++ )
+ {
+ if ( (pTempPair2->wFirst == pTempPair->wFirst) &&
+ (pTempPair2->wSecond == pTempPair->wSecond) )
+ {
+ bAdd = FALSE;
+ break;
+ }
+ pTempPair2++;
+ }
+
+ if ( bAdd )
+ {
+ KERNINGPAIR* pDestPair = pData->mpFontKernPairs+pData->mnFontKernPairCount;
+ if ( pDestPair != pTempPair )
+ memcpy( pDestPair, pTempPair, sizeof( KERNINGPAIR ) );
+ pData->mnFontKernPairCount++;
+ }
+
+ pTempPair++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs )
+{
+ DBG_ASSERT( sizeof( KERNINGPAIR ) == sizeof( ImplKernPairData ),
+ "SalGraphics::GetKernPairs(): KERNINGPAIR != ImplKernPairData" );
+
+ if ( aSalShlData.mbWNT )
+ {
+ if ( !pKernPairs )
+ return ::GetKerningPairsW( maGraphicsData.mhDC, 0, NULL );
+ else
+ return ::GetKerningPairsW( maGraphicsData.mhDC, nPairs, (KERNINGPAIR*)pKernPairs );
+ }
+ else
+ {
+ if ( maGraphicsData.mbFontKernInit )
+ {
+ if ( maGraphicsData.mpFontKernPairs )
+ {
+ delete maGraphicsData.mpFontKernPairs;
+ maGraphicsData.mpFontKernPairs = 0;
+ }
+ maGraphicsData.mnFontKernPairCount = 0;
+
+ if ( !maGraphicsData.mnFontCharSetCount )
+ ImplGetAllFontCharSets( &maGraphicsData );
+
+ if ( maGraphicsData.mnFontCharSetCount <= 1 )
+ ImplAddKerningPairs( &maGraphicsData );
+ else
+ {
+ // Query All Kerning Pairs from all possible CharSets
+ for ( BYTE i = 0; i < maGraphicsData.mnFontCharSetCount; i++ )
+ {
+ maGraphicsData.mpLogFont->lfCharSet = maGraphicsData.mpFontCharSets[i];
+ HFONT hNewFont = CreateFontIndirectA( maGraphicsData.mpLogFont );
+ HFONT hOldFont = SelectFont( maGraphicsData.mhDC, hNewFont );
+ ImplAddKerningPairs( &maGraphicsData );
+ SelectFont( maGraphicsData.mhDC, hOldFont );
+ DeleteFont( hNewFont );
+ }
+ }
+
+ maGraphicsData.mbFontKernInit = FALSE;
+ }
+
+ if ( !pKernPairs )
+ return maGraphicsData.mnFontKernPairCount;
+ else
+ {
+ if ( nPairs > maGraphicsData.mnFontKernPairCount )
+ nPairs = maGraphicsData.mnFontKernPairCount;
+ memcpy( pKernPairs, maGraphicsData.mpFontKernPairs,
+ nPairs*sizeof( ImplKernPairData ) );
+ return nPairs;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+int CALLBACK SalEnumFontsProcExA( const ENUMLOGFONTEXA* pLogFont,
+ const NEWTEXTMETRICEXA* pMetric,
+ DWORD nFontType, LPARAM lParam )
+{
+ ImplEnumInfo* pInfo = (ImplEnumInfo*)(void*)lParam;
+ if ( !pInfo->mpName )
+ {
+ // Ignore vertical fonts
+ if ( pLogFont->elfLogFont.lfFaceName[0] != '@' )
+ {
+ if ( !pInfo->mbImplSalCourierNew )
+ pInfo->mbImplSalCourierNew = stricmp( pLogFont->elfLogFont.lfFaceName, "Courier New" ) == 0;
+ if ( !pInfo->mbImplSalCourierScalable )
+ pInfo->mbCourier = stricmp( pLogFont->elfLogFont.lfFaceName, "Courier" ) == 0;
+ else
+ pInfo->mbCourier = FALSE;
+ XubString aName( ImplSalGetUniString( pLogFont->elfLogFont.lfFaceName ) );
+ pInfo->mpName = &aName;
+ strcpy( pInfo->mpLogFontA->lfFaceName, pLogFont->elfLogFont.lfFaceName );
+ pInfo->mpLogFontA->lfCharSet = pLogFont->elfLogFont.lfCharSet;
+ EnumFontFamiliesExA( pInfo->mhDC, pInfo->mpLogFontA, (FONTENUMPROCA)SalEnumFontsProcExA,
+ (LPARAM)(void*)pInfo, 0 );
+ pInfo->mpLogFontA->lfFaceName[0] = '\0';
+ pInfo->mpLogFontA->lfCharSet = DEFAULT_CHARSET;
+ pInfo->mpName = NULL;
+ pInfo->mbCourier = FALSE;
+ }
+ }
+ else
+ {
+ ImplFontData* pData = new ImplFontData;
+ pData->maName = *(pInfo->mpName);
+
+ ImplLogMetricToDevFontDataA( &(pLogFont->elfLogFont), &(pMetric->ntmTm), nFontType, pData );
+ // StyleName nur bei TrueType uebernehmen, da sonst bei 3.1 Mist drinsteht
+ if ( pMetric->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE )
+ pData->maStyleName = ImplSalGetUniString( (const char*)pLogFont->elfStyle );
+ pData->mpSysData = (void*)(pLogFont->elfLogFont.lfCharSet);
+ BOOL bAdd = TRUE;
+
+ // Wenn es sich um einen nicht skalierbaren Bildschirm-Font
+ // handelt, dann auf dem Drucker ignorieren
+ if ( pData->meType != TYPE_SCALABLE )
+ {
+ if ( pInfo->mbPrinter )
+ bAdd = pData->mbDevice;
+ }
+ else
+ {
+ // Feststellen, ob Courier skalierbar ist
+ if ( pInfo->mbCourier )
+ pInfo->mbImplSalCourierScalable = TRUE;
+ }
+
+ if ( bAdd )
+ pInfo->mpList->Add( pData );
+ else
+ delete pData;
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int CALLBACK SalEnumFontsProcExW( const ENUMLOGFONTEXW* pLogFont,
+ const NEWTEXTMETRICEXW* pMetric,
+ DWORD nFontType, LPARAM lParam )
+{
+ ImplEnumInfo* pInfo = (ImplEnumInfo*)(void*)lParam;
+ if ( !pInfo->mpName )
+ {
+ // Ignore vertical fonts
+ if ( pLogFont->elfLogFont.lfFaceName[0] != '@' )
+ {
+ if ( !pInfo->mbImplSalCourierNew )
+ pInfo->mbImplSalCourierNew = ImplSalWICompareAscii( pLogFont->elfLogFont.lfFaceName, "Courier New" ) == 0;
+ if ( !pInfo->mbImplSalCourierScalable )
+ pInfo->mbCourier = ImplSalWICompareAscii( pLogFont->elfLogFont.lfFaceName, "Courier" ) == 0;
+ else
+ pInfo->mbCourier = FALSE;
+ XubString aName( pLogFont->elfLogFont.lfFaceName );
+ pInfo->mpName = &aName;
+ memcpy( pInfo->mpLogFontW->lfFaceName, pLogFont->elfLogFont.lfFaceName, (aName.Len()+1)*sizeof( wchar_t ) );
+ pInfo->mpLogFontW->lfCharSet = pLogFont->elfLogFont.lfCharSet;
+ EnumFontFamiliesExW( pInfo->mhDC, pInfo->mpLogFontW, (FONTENUMPROCW)SalEnumFontsProcExW,
+ (LPARAM)(void*)pInfo, 0 );
+ pInfo->mpLogFontW->lfFaceName[0] = '\0';
+ pInfo->mpLogFontW->lfCharSet = DEFAULT_CHARSET;
+ pInfo->mpName = NULL;
+ pInfo->mbCourier = FALSE;
+ }
+ }
+ else
+ {
+ ImplFontData* pData = new ImplFontData;
+ pData->maName = *(pInfo->mpName);
+
+ ImplLogMetricToDevFontDataW( &(pLogFont->elfLogFont), &(pMetric->ntmTm), nFontType, pData );
+ // StyleName nur bei TrueType uebernehmen, da sonst bei 3.1 Mist drinsteht
+ if ( pMetric->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE )
+ pData->maStyleName = pLogFont->elfStyle;
+ pData->mpSysData = (void*)(pLogFont->elfLogFont.lfCharSet);
+ BOOL bAdd = TRUE;
+
+ // Wenn es sich um einen nicht skalierbaren Bildschirm-Font
+ // handelt, dann auf dem Drucker ignorieren
+ if ( pData->meType != TYPE_SCALABLE )
+ {
+ if ( pInfo->mbPrinter )
+ bAdd = pData->mbDevice;
+ }
+ else
+ {
+ // Feststellen, ob Courier skalierbar ist
+ if ( pInfo->mbCourier )
+ pInfo->mbImplSalCourierScalable = TRUE;
+ }
+
+ if ( bAdd )
+ pInfo->mpList->Add( pData );
+ else
+ delete pData;
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetDevFontList( ImplDevFontList* pList )
+{
+ ImplEnumInfo aInfo;
+ aInfo.mhDC = maGraphicsData.mhDC;
+ aInfo.mpList = pList;
+ aInfo.mpName = NULL;
+ aInfo.mpLogFontA = NULL;
+ aInfo.mpLogFontW = NULL;
+ aInfo.mbCourier = FALSE;
+ if ( !maGraphicsData.mbPrinter )
+ {
+ aInfo.mbImplSalCourierScalable = FALSE;
+ aInfo.mbImplSalCourierNew = FALSE;
+ aInfo.mbPrinter = FALSE;
+ }
+ else
+ {
+ aInfo.mbImplSalCourierScalable = TRUE;
+ aInfo.mbImplSalCourierNew = TRUE;
+ aInfo.mbPrinter = TRUE;
+ }
+
+ if ( aSalShlData.mbWNT )
+ {
+ LOGFONTW aLogFont;
+ memset( &aLogFont, 0, sizeof( aLogFont ) );
+ aLogFont.lfCharSet = DEFAULT_CHARSET;
+ aInfo.mpLogFontW = &aLogFont;
+ EnumFontFamiliesExW( maGraphicsData.mhDC, &aLogFont, (FONTENUMPROCW)SalEnumFontsProcExW,
+ (LPARAM)(void*)&aInfo, 0 );
+ }
+ else
+ {
+ LOGFONTA aLogFont;
+ memset( &aLogFont, 0, sizeof( aLogFont ) );
+ aLogFont.lfCharSet = DEFAULT_CHARSET;
+ aInfo.mpLogFontA = &aLogFont;
+ EnumFontFamiliesExA( maGraphicsData.mhDC, &aLogFont, (FONTENUMPROCA)SalEnumFontsProcExA,
+ (LPARAM)(void*)&aInfo, 0 );
+ }
+
+ // Feststellen, was es fuer Courier-Schriften auf dem Bildschirm gibt,
+ // um in SetFont() evt. Courier auf Courier New zu mappen
+ if ( !maGraphicsData.mbPrinter )
+ {
+ bImplSalCourierScalable = aInfo.mbImplSalCourierScalable;
+ bImplSalCourierNew = aInfo.mbImplSalCourierNew;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawText( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen )
+{
+ DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "SalGraphics::DrawText(): WCHAR != sal_Unicode" );
+
+ ::ExtTextOutW( maGraphicsData.mhDC, (int)nX, (int)nY,
+ 0, NULL, pStr, nLen, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawTextArray( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen,
+ const long* pDXAry )
+{
+ DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "SalGraphics::DrawText(): WCHAR != sal_Unicode" );
+
+ if ( nLen < 2 )
+ ::ExtTextOutW( maGraphicsData.mhDC, (int)nX, (int)nY, 0, NULL, pStr, nLen, NULL );
+ else
+ {
+ int aStackAry[SAL_DRAWTEXT_STACKBUF];
+ int* pWinDXAry;
+
+ if ( nLen <= SAL_DRAWTEXT_STACKBUF )
+ pWinDXAry = aStackAry;
+ else
+ pWinDXAry = new int[nLen];
+
+ pWinDXAry[0] = (int)pDXAry[0];
+ for ( xub_StrLen i = 1; i < nLen-1; i++ )
+ pWinDXAry[i] = (int)pDXAry[i]-pDXAry[i-1];
+
+ // Breite vom letzten Zeichen ermitteln, da wir dieses auch
+ // beim Windows-XArray in der richtigen Breite reingeben
+ // muessen, um nicht auf Probleme bei einigen
+ // Grafikkarten oder Druckertreibern zu stossen
+ SIZE aExtent;
+ if ( GetTextExtentPointW( maGraphicsData.mhDC, pStr+nLen-1, 1, &aExtent ) )
+ pWinDXAry[nLen-1] = aExtent.cx;
+ else
+ pWinDXAry[nLen-1] = 4095;
+
+ // Text ausgeben
+ ::ExtTextOutW( maGraphicsData.mhDC, (int)nX, (int)nY, 0, NULL, pStr, nLen, pWinDXAry );
+
+ if ( pWinDXAry != aStackAry )
+ delete pWinDXAry;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static ULONG ImplIncreaseArrays( ULONG nSize, SalPoint** ppPoints, BYTE** ppFlags, ULONG nIncSize )
+{
+ const ULONG nOldSize = nSize;
+ SalPoint* pNewPoints = new SalPoint[ nSize += nIncSize ];
+ BYTE* pNewFlags = new BYTE[ nSize ];
+
+ if( *ppPoints )
+ {
+ memcpy( pNewPoints, *ppPoints, nOldSize * sizeof( SalPoint ) );
+ memset( pNewPoints + nOldSize, 0, nIncSize * sizeof( SalPoint ) );
+ delete[] *ppPoints;
+ }
+ else
+ memset( pNewPoints, 0, nSize * sizeof( SalPoint ) );
+
+ if( *ppFlags )
+ {
+ memcpy( pNewFlags, *ppFlags, nOldSize );
+ memset( pNewFlags + nOldSize, 0, nIncSize );
+ delete[] *ppFlags;
+ }
+ else
+ memset( pNewFlags, 0, nSize );
+
+ *ppPoints = pNewPoints;
+ *ppFlags = pNewFlags;
+
+ return nSize;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetFamilyAndAscents( HDC hDC, BYTE& rPitch, long& rAscent )
+{
+ rPitch = 0;
+ rAscent = 0;
+
+ if ( aSalShlData.mbWNT )
+ {
+ TEXTMETRICW aTextMetricW;
+ if ( GetTextMetricsW( hDC, &aTextMetricW ) )
+ {
+ rPitch = aTextMetricW.tmPitchAndFamily;
+ rAscent = aTextMetricW.tmAscent;
+ }
+ }
+ else
+ {
+ TEXTMETRICA aTextMetricA;
+ if ( GetTextMetricsA( hDC, &aTextMetricA ) )
+ {
+ rPitch = aTextMetricA.tmPitchAndFamily;
+ rAscent = aTextMetricA.tmAscent;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplGetGlyphChar( SalGraphicsData* pData, sal_Unicode c,
+ WORD& rByteChar, HFONT& rOldFont )
+{
+ rOldFont = 0;
+
+ if ( !pData->mnFontCharSetCount )
+ ImplGetAllFontCharSets( pData );
+
+ // Try at first the current charset
+ CHARSETINFO aInfo;
+ char aDestBuf[2];
+ int nLen = 0;
+ WIN_BOOL bDefault;
+ if ( TranslateCharsetInfo( (DWORD*)(ULONG)GetTextCharset( pData->mhDC ), &aInfo, TCI_SRCCHARSET ) )
+ {
+ bDefault = FALSE;
+ nLen = WideCharToMultiByte( aInfo.ciACP,
+ WC_COMPOSITECHECK | WC_DISCARDNS | WC_DEFAULTCHAR,
+ &c, 1,
+ aDestBuf, sizeof( aDestBuf ),
+ NULL, &bDefault );
+ }
+
+ // Try all possible charsets
+ if ( (nLen != 1) || bDefault )
+ {
+ // Query All Kerning Pairs from all possible CharSets
+ for ( BYTE i = 0; i < pData->mnFontCharSetCount; i++ )
+ {
+ if ( TranslateCharsetInfo( (DWORD*)(ULONG)pData->mpFontCharSets[i], &aInfo, TCI_SRCCHARSET ) )
+ {
+ bDefault = FALSE;
+ nLen = WideCharToMultiByte( aInfo.ciACP,
+ WC_COMPOSITECHECK | WC_DISCARDNS | WC_DEFAULTCHAR,
+ &c, 1,
+ aDestBuf, sizeof( aDestBuf ),
+ NULL, &bDefault );
+ if ( (nLen == 1) && !bDefault )
+ {
+ pData->mpLogFont->lfCharSet = pData->mpFontCharSets[i];
+ HFONT hNewFont = CreateFontIndirectA( pData->mpLogFont );
+ rOldFont = SelectFont( pData->mhDC, hNewFont );
+ break;
+ }
+ }
+ }
+ }
+
+ // GetGlyphOutline() only works for characters < 256. For all characters
+ // greater than 256 we use the default mechanismn in VCL to scan
+ // the printed Glyph
+ if ( (nLen == 1) && !bDefault )
+ {
+ rByteChar = (unsigned char)aDestBuf[0];
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalGraphics::GetGlyphBoundRect( xub_Unicode cChar, long* pX, long* pY,
+ long* pWidth, long* pHeight )
+{
+ HDC hDC = maGraphicsData.mhDC;
+ BYTE nPitchAndFamily;
+ long nAscent;
+
+ ImplGetFamilyAndAscents( hDC, nPitchAndFamily, nAscent );
+ if ( !(nPitchAndFamily & TMPF_TRUETYPE) )
+ return FALSE;
+
+ GLYPHMETRICS aGlyphMetrics;
+ MAT2 aMat;
+ DWORD nSize;
+ BOOL bOK;
+ HFONT hOldFont = 0;
+
+ // Einheitsmatrix erzeugen
+ aMat.eM11 = FixedFromDouble(1.);
+ aMat.eM12 = FixedFromDouble(0.);
+ aMat.eM21 = FixedFromDouble(0.);
+ aMat.eM22 = FixedFromDouble(1.);
+ if ( aSalShlData.mbWNT )
+ nSize = ::GetGlyphOutlineW( hDC, cChar, GGO_METRICS, &aGlyphMetrics, 0, NULL, &aMat );
+ else
+ {
+ WORD nChar;
+ if ( ImplGetGlyphChar( &maGraphicsData, cChar, nChar, hOldFont ) )
+ nSize = ::GetGlyphOutlineA( hDC, nChar, GGO_METRICS, &aGlyphMetrics, 0, NULL, &aMat );
+ else
+ nSize = 0;
+ }
+ bOK = (nSize != GDI_ERROR) && nSize;
+ if ( bOK )
+ {
+ *pX = aGlyphMetrics.gmptGlyphOrigin.x;
+ *pY = nAscent - aGlyphMetrics.gmptGlyphOrigin.y;
+ *pWidth = aGlyphMetrics.gmBlackBoxX;
+ *pHeight = aGlyphMetrics.gmBlackBoxY;
+ }
+
+ if ( hOldFont )
+ {
+ HFONT hNewFont = SelectFont( maGraphicsData.mhDC, hOldFont );
+ DeleteFont( hNewFont );
+ }
+
+ return bOK;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalGraphics::GetGlyphOutline( xub_Unicode cChar, USHORT** ppPolySizes,
+ SalPoint** ppPoints, BYTE** ppFlags )
+{
+ HDC hDC = maGraphicsData.mhDC;
+ BYTE nPitchAndFamily;
+ long nAscent;
+
+ ImplGetFamilyAndAscents( hDC, nPitchAndFamily, nAscent );
+ if ( !(nPitchAndFamily & TMPF_TRUETYPE) )
+ return 0;
+
+ GLYPHMETRICS aGlyphMetrics;
+ MAT2 aMat;
+ DWORD nSize;
+ USHORT nChar = cChar;
+ HFONT hOldFont = 0;
+ ULONG nPolyCount = 0;
+
+ // Einheitsmatrix erzeugen
+ aMat.eM11 = FixedFromDouble(1.);
+ aMat.eM12 = FixedFromDouble(0.);
+ aMat.eM21 = FixedFromDouble(0.);
+ aMat.eM22 = FixedFromDouble(1.);
+
+ if ( aSalShlData.mbWNT )
+ nSize = ::GetGlyphOutlineW( hDC, nChar, GGO_NATIVE, &aGlyphMetrics, 0, NULL, &aMat );
+ else
+ {
+ if ( ImplGetGlyphChar( &maGraphicsData, cChar, nChar, hOldFont ) )
+ nSize = ::GetGlyphOutlineA( hDC, nChar, GGO_NATIVE, &aGlyphMetrics, 0, NULL, &aMat );
+ else
+ nSize = 0;
+ }
+
+ if ( (nSize != GDI_ERROR) && nSize )
+ {
+ BYTE* pData = new BYTE[ nSize ];
+ ULONG nTotalCount = 0;
+ DWORD nSize2;
+ if ( aSalShlData.mbWNT )
+ nSize2 = ::GetGlyphOutlineW( hDC, nChar, GGO_NATIVE, &aGlyphMetrics, nSize, pData, &aMat );
+ else
+ nSize2 = ::GetGlyphOutlineA( hDC, nChar, GGO_NATIVE, &aGlyphMetrics, nSize, pData, &aMat );
+ if ( nSize == nSize2 )
+ {
+ ULONG nPtSize = GLYPH_INC;
+ SalPoint* pPoints = new SalPoint[ GLYPH_INC ];
+ SalPoint* pTotalPoints = NULL;
+ BYTE* pFlags = new BYTE[ GLYPH_INC ];
+ BYTE* pTotalFlags = NULL;
+ TTPOLYGONHEADER* pHeader = (TTPOLYGONHEADER*)pData;
+ TTPOLYCURVE* pCurve;
+ *ppPolySizes = new USHORT[ MAX_POLYCOUNT ];
+ memset( *ppPolySizes, 0, MAX_POLYCOUNT * sizeof( USHORT ) );
+
+ while ( ((BYTE*)pHeader < pData+nSize) && (nPolyCount < (MAX_POLYCOUNT - 1)) )
+ {
+ if ( pHeader->dwType == TT_POLYGON_TYPE )
+ {
+ USHORT nPnt = 0;
+ USHORT i;
+
+ memset( pPoints, 0, nPtSize * sizeof( SalPoint ) );
+ memset( pFlags, 0, nPtSize );
+
+ // ersten Startpunkt holen; die folgenden Startpunkte sind
+ // die Endpunkte der vorhergehenden Kurven
+ pPoints[ nPnt ].mnX = IntFromFixed( pHeader->pfxStart.x );
+ pPoints[ nPnt++ ].mnY = IntFromFixed( pHeader->pfxStart.y );
+
+ pCurve = (TTPOLYCURVE*) ( pHeader + 1 );
+
+ while ( (BYTE*)pCurve < (BYTE*)pHeader+pHeader->cb )
+ {
+ if ( TT_PRIM_LINE == pCurve->wType )
+ {
+ for( i = 0; i < pCurve->cpfx; i++ )
+ {
+ CHECKPOINTS( nPnt );
+ pPoints[ nPnt ].mnX = IntFromFixed( pCurve->apfx[ i ].x );
+ pPoints[ nPnt++ ].mnY = IntFromFixed( pCurve->apfx[ i ].y );
+ }
+ }
+ else if ( pCurve->wType == TT_PRIM_QSPLINE )
+ {
+ for ( i = 0; i < pCurve->cpfx; )
+ {
+ // Punkt B, der Kontrollpunkt der Kurve
+ CHECKPOINTS( nPnt );
+ pPoints[ nPnt ].mnX = IntFromFixed( pCurve->apfx[ i ].x );
+ pPoints[ nPnt ].mnY = IntFromFixed( pCurve->apfx[ i++ ].y );
+
+ // Punkt verdoppeln fuer Bezier-Wandlung
+ CHECKPOINTS( nPnt + 1UL );
+ pPoints[ nPnt + 1 ] = pPoints[ nPnt ];
+ nPnt += 2;
+
+ // Endpunkt der Kurve bestimmen
+ if ( i == (pCurve->cpfx - 1) )
+ {
+ // entweder letzter Punkt
+ CHECKPOINTS( nPnt );
+ pPoints[ nPnt ].mnX = IntFromFixed( pCurve->apfx[ i ].x );
+ pPoints[ nPnt++].mnY = IntFromFixed( pCurve->apfx[ i++ ].y );
+ }
+ else
+ {
+ // oder die Mitte zwischen den Kontrollpunkten
+ // dieser und der naechsten Kurce
+ CHECKPOINTS( nPnt );
+ pPoints[ nPnt ].mnX = IntFromFixed( fxDiv2( pCurve->apfx[ i - 1 ].x,
+ pCurve->apfx[ i ].x ) );
+ pPoints[ nPnt++ ].mnY = IntFromFixed( fxDiv2( pCurve->apfx[ i - 1 ].y,
+ pCurve->apfx[ i ].y ) );
+ }
+
+ // Umrechnung in Bezier ( PQ = TrueType-Controlpunkt):
+ // P1 = 1/3 * (P0 + 2 * PQ) / P2 = 1/3 * (P3 + 2 * PQ)
+ pPoints[ nPnt - 3 ].mnX = ( pPoints[ nPnt - 4 ].mnX +
+ ( pPoints[ nPnt - 3 ].mnX << 1 ) ) / 3;
+ pPoints[ nPnt - 3 ].mnY = ( pPoints[ nPnt - 4 ].mnY +
+ ( pPoints[ nPnt - 3 ].mnY << 1 ) ) / 3;
+
+ pPoints[ nPnt - 2 ].mnX = ( pPoints[ nPnt - 1 ].mnX +
+ ( pPoints[ nPnt - 2 ].mnX << 1 ) ) / 3;
+ pPoints[ nPnt - 2 ].mnY = ( pPoints[ nPnt - 1 ].mnY +
+ ( pPoints[ nPnt - 2 ].mnY << 1 ) ) / 3;
+
+ pFlags[ nPnt - 3 ] = pFlags[ nPnt - 2 ] = 2;
+ }
+ }
+
+ // weiter mit naechstem Kurvensegment
+ pCurve = (TTPOLYCURVE*) &pCurve->apfx[ i ];
+ }
+
+ CHECKPOINTS( nPnt );
+ pPoints[nPnt++] = pPoints[0];
+
+ if ( nPnt )
+ {
+ (*ppPolySizes)[ nPolyCount++ ] = nPnt;
+ ImplIncreaseArrays( nTotalCount, &pTotalPoints, &pTotalFlags, nPnt );
+
+ // Polygon senkrecht kippen: TrueType-Y-Koordinaten verlaufen von unten nach oben
+ for ( i = 0; i < nPnt; i++ )
+ {
+ pTotalPoints[ nTotalCount ].mnX = pPoints[i].mnX;
+ pTotalPoints[ nTotalCount ].mnY = nAscent - pPoints[i].mnY;
+ pTotalFlags[ nTotalCount++ ] = pFlags[i];
+ }
+ }
+
+ // naechstes Polygon
+ pHeader = (TTPOLYGONHEADER*) ( (BYTE*) pHeader + pHeader->cb );
+ }
+ }
+
+ delete[] pPoints;
+ delete[] pFlags;
+
+ if ( !nPolyCount )
+ {
+ delete[] pTotalPoints;
+ *ppPoints = NULL;
+ delete[] pTotalFlags;
+ *ppFlags = NULL;
+ delete[] *ppPolySizes;
+ *ppPolySizes = NULL;
+ }
+ else
+ {
+ *ppPoints = pTotalPoints;
+ *ppFlags = pTotalFlags;
+ }
+ }
+
+ delete [] pData;
+ }
+
+ if ( hOldFont )
+ {
+ HFONT hNewFont = SelectFont( maGraphicsData.mhDC, hOldFont );
+ DeleteFont( hNewFont );
+ }
+
+ return nPolyCount;
+}
diff --git a/vcl/win/source/gdi/salogl.cxx b/vcl/win/source/gdi/salogl.cxx
new file mode 100644
index 000000000000..bdd5ccee00e8
--- /dev/null
+++ b/vcl/win/source/gdi/salogl.cxx
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ * $RCSfile: salogl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALOGL_CXX
+
+#ifndef _SV_SALOGL_HXX
+#include <salogl.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+
+// -------------------------------
+// - Additional typedefs for init.
+// -------------------------------
+
+typedef HGLRC ( *OGLFncCreateContext )( HDC hDC );
+typedef BOOL ( *OGLFncDeleteContext )( HGLRC hContext );
+typedef HGLRC ( *OGLFncGetCurrentContext )( VOID );
+typedef void ( *OGLFncMakeCurrent )( HDC hDC, HGLRC hContext );
+
+// ------------
+// - Lib-Name -
+// ------------
+
+#define OGL_LIBNAME "OPENGL32.DLL"
+
+// ----------
+// - Macros -
+// ----------
+
+#define INIT_OGLFNC_WGL( FncName ) static OGLFnc##FncName pImplOpenWGLFnc##FncName = NULL;
+#define GET_OGLFNC_WGL( FncName ) \
+pImplOpenWGLFnc##FncName = (OGLFnc##FncName##) GetProcAddress( hImplOGLLib, "wgl" #FncName ); \
+if( !pImplOpenWGLFnc##FncName ) bRet = FALSE;
+
+// -----------------
+// - Statics init. -
+// -----------------
+
+// Members
+static HINSTANCE hImplOGLLib;
+HGLRC SalOpenGL::mhOGLContext = 0;
+HDC SalOpenGL::mhOGLLastDC = 0;
+ULONG SalOpenGL::mnOGLState = OGL_STATE_UNLOADED;
+
+INIT_OGLFNC_WGL( CreateContext );
+INIT_OGLFNC_WGL( DeleteContext );
+INIT_OGLFNC_WGL( GetCurrentContext );
+INIT_OGLFNC_WGL( MakeCurrent );
+
+// -----------
+// - WndProc -
+// -----------
+
+LRESULT CALLBACK OpenGLWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
+{
+ return DefWindowProc( hWnd, nMsg, nPar1, nPar2 );
+}
+
+// -------------
+// - SalOpenGL -
+// -------------
+
+SalOpenGL::SalOpenGL( SalGraphics* pGraphics )
+{
+ // Set mhOGLLastDC only the first time a
+ // SalOpenGL object is created; we need
+ // this DC in SalOpenGL::Create();
+ if ( OGL_STATE_UNLOADED == mnOGLState )
+ mhOGLLastDC = pGraphics->maGraphicsData.mhDC;
+}
+
+// ------------------------------------------------------------------------
+
+SalOpenGL::~SalOpenGL()
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::Create()
+{
+ BOOL bRet = FALSE;
+
+ if ( OGL_STATE_UNLOADED == mnOGLState )
+ {
+ if( ImplInitLib() )
+ {
+ USHORT nBitCount = GetDeviceCaps( mhOGLLastDC, BITSPIXEL );
+ PIXELFORMATDESCRIPTOR pfd =
+ {
+ sizeof( PIXELFORMATDESCRIPTOR ),
+ 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ (BYTE) nBitCount,
+ 0, 0, 0, 0, 0, 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,
+ 0, 0, 0
+ };
+
+ const int nIndex = ChoosePixelFormat( mhOGLLastDC, &pfd );
+
+ if( nIndex && SetPixelFormat( mhOGLLastDC, nIndex, &pfd ) )
+ {
+ if ( (nBitCount > 8) && ImplInit() &&
+ (mhOGLContext = pImplOpenWGLFncCreateContext( mhOGLLastDC )) != 0 )
+ {
+ WNDCLASS aWc;
+ HWND hDummyWnd;
+
+ SaveDC( mhOGLLastDC );
+ SelectClipRgn( mhOGLLastDC, NULL );
+ pImplOpenWGLFncMakeCurrent( mhOGLLastDC, mhOGLContext );
+ RestoreDC( mhOGLLastDC, -1 );
+ mnOGLState = OGL_STATE_VALID;
+ bRet = TRUE;
+
+ memset( &aWc, 0, sizeof( aWc ) );
+ aWc.hInstance = GetModuleHandle( NULL );
+ aWc.lpfnWndProc = OpenGLWndProc;
+ aWc.lpszClassName = "OpenGLWnd";
+ RegisterClass( &aWc );
+ hDummyWnd = CreateWindow( aWc.lpszClassName, NULL, WS_OVERLAPPED, 0, -50, 1, 1, HWND_DESKTOP, NULL, aWc.hInstance, 0 );
+ ShowWindow( hDummyWnd, SW_SHOW );
+ DestroyWindow( hDummyWnd );
+ UnregisterClass( aWc.lpszClassName, aWc.hInstance );
+ }
+ else
+ {
+ ImplFreeLib();
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ }
+ else
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ else
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ else if( OGL_STATE_VALID == mnOGLState )
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::Release()
+{
+ ImplFreeLib();
+}
+
+// ------------------------------------------------------------------------
+
+void* SalOpenGL::GetOGLFnc( const char* pFncName )
+{
+ if ( hImplOGLLib )
+ return (void*)GetProcAddress( hImplOGLLib, pFncName );
+ else
+ return NULL;
+}
+
+// ------------------------------------------------------------------------
+
+typedef BOOL (WINAPI *MyFuncType)(HDC, HGLRC);
+
+void SalOpenGL::OGLEntry( SalGraphics* pGraphics )
+{
+ if ( pGraphics->maGraphicsData.mhDC != mhOGLLastDC )
+ {
+ PIXELFORMATDESCRIPTOR pfd =
+ {
+ sizeof( PIXELFORMATDESCRIPTOR ),
+ 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ GetDeviceCaps( pGraphics->maGraphicsData.mhDC, BITSPIXEL ),
+ 0, 0, 0, 0, 0, 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,
+ 0, 0, 0
+ };
+
+ const int nIndex = ChoosePixelFormat( pGraphics->maGraphicsData.mhDC, &pfd );
+ if ( nIndex && SetPixelFormat( pGraphics->maGraphicsData.mhDC, nIndex, &pfd ) )
+ {
+ WNDCLASS aWc;
+ HWND hDummyWnd;
+
+ pImplOpenWGLFncDeleteContext( mhOGLContext );
+ mhOGLLastDC = pGraphics->maGraphicsData.mhDC;
+ mhOGLContext = pImplOpenWGLFncCreateContext( mhOGLLastDC );
+
+ SaveDC( mhOGLLastDC );
+ SelectClipRgn( mhOGLLastDC, NULL );
+ pImplOpenWGLFncMakeCurrent( mhOGLLastDC, mhOGLContext );
+ RestoreDC( mhOGLLastDC, -1 );
+
+ memset( &aWc, 0, sizeof( aWc ) );
+ aWc.hInstance = GetModuleHandle( NULL );
+ aWc.lpfnWndProc = OpenGLWndProc;
+ aWc.lpszClassName = "OpenGLWnd";
+ RegisterClass( &aWc );
+ hDummyWnd = CreateWindow( aWc.lpszClassName, NULL, WS_OVERLAPPED, 0, -50, 1, 1, HWND_DESKTOP, NULL, aWc.hInstance, 0 );
+ ShowWindow( hDummyWnd, SW_SHOW );
+ DestroyWindow( hDummyWnd );
+ UnregisterClass( aWc.lpszClassName, aWc.hInstance );
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::OGLExit( SalGraphics* pGraphics )
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::ImplInitLib()
+{
+ return ((hImplOGLLib = LoadLibrary( OGL_LIBNAME )) != NULL);
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::ImplFreeLib()
+{
+ if ( hImplOGLLib )
+ {
+ FreeLibrary( hImplOGLLib );
+ hImplOGLLib = NULL;
+ mnOGLState = OGL_STATE_UNLOADED;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::ImplInit()
+{
+ BOOL bRet = TRUE;
+
+ // Internal use
+ GET_OGLFNC_WGL( CreateContext );
+ GET_OGLFNC_WGL( DeleteContext );
+ GET_OGLFNC_WGL( GetCurrentContext );
+ GET_OGLFNC_WGL( MakeCurrent );
+
+ return bRet;
+}
diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx
new file mode 100644
index 000000000000..e4ac38538b51
--- /dev/null
+++ b/vcl/win/source/gdi/salprn.cxx
@@ -0,0 +1,1424 @@
+/*************************************************************************
+ *
+ * $RCSfile: salprn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALPRN_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALPTYPE_HXX
+#include <salptype.hxx>
+#endif
+#ifndef _SV_SALPRN_HXX
+#include <salprn.hxx>
+#endif
+
+#ifndef _NEW_HXX
+#include <tools/new.hxx>
+#endif
+
+#ifndef _SV_PRINT_H
+#include <print.h>
+#endif
+#ifndef _SV_JOBSET_H
+#include <jobset.h>
+#endif
+
+// =======================================================================
+
+static char aImplWindows[] = "windows";
+static char aImplDevices[] = "devices";
+static char aImplDevice[] = "device";
+
+// =======================================================================
+
+static ULONG ImplWinQueueStatusToSal( DWORD nWinStatus )
+{
+ ULONG nStatus = 0;
+ if ( nWinStatus & PRINTER_STATUS_PAUSED )
+ nStatus |= QUEUE_STATUS_PAUSED;
+ if ( nWinStatus & PRINTER_STATUS_ERROR )
+ nStatus |= QUEUE_STATUS_ERROR;
+ if ( nWinStatus & PRINTER_STATUS_PENDING_DELETION )
+ nStatus |= QUEUE_STATUS_PENDING_DELETION;
+ if ( nWinStatus & PRINTER_STATUS_PAPER_JAM )
+ nStatus |= QUEUE_STATUS_PAPER_JAM;
+ if ( nWinStatus & PRINTER_STATUS_PAPER_OUT )
+ nStatus |= QUEUE_STATUS_PAPER_OUT;
+ if ( nWinStatus & PRINTER_STATUS_MANUAL_FEED )
+ nStatus |= QUEUE_STATUS_MANUAL_FEED;
+ if ( nWinStatus & PRINTER_STATUS_PAPER_PROBLEM )
+ nStatus |= QUEUE_STATUS_PAPER_PROBLEM;
+ if ( nWinStatus & PRINTER_STATUS_OFFLINE )
+ nStatus |= QUEUE_STATUS_OFFLINE;
+ if ( nWinStatus & PRINTER_STATUS_IO_ACTIVE )
+ nStatus |= QUEUE_STATUS_IO_ACTIVE;
+ if ( nWinStatus & PRINTER_STATUS_BUSY )
+ nStatus |= QUEUE_STATUS_BUSY;
+ if ( nWinStatus & PRINTER_STATUS_PRINTING )
+ nStatus |= QUEUE_STATUS_PRINTING;
+ if ( nWinStatus & PRINTER_STATUS_OUTPUT_BIN_FULL )
+ nStatus |= QUEUE_STATUS_OUTPUT_BIN_FULL;
+ if ( nWinStatus & PRINTER_STATUS_WAITING )
+ nStatus |= QUEUE_STATUS_WAITING;
+ if ( nWinStatus & PRINTER_STATUS_PROCESSING )
+ nStatus |= QUEUE_STATUS_PROCESSING;
+ if ( nWinStatus & PRINTER_STATUS_INITIALIZING )
+ nStatus |= QUEUE_STATUS_INITIALIZING;
+ if ( nWinStatus & PRINTER_STATUS_WARMING_UP )
+ nStatus |= QUEUE_STATUS_WARMING_UP;
+ if ( nWinStatus & PRINTER_STATUS_TONER_LOW )
+ nStatus |= QUEUE_STATUS_TONER_LOW;
+ if ( nWinStatus & PRINTER_STATUS_NO_TONER )
+ nStatus |= QUEUE_STATUS_NO_TONER;
+ if ( nWinStatus & PRINTER_STATUS_PAGE_PUNT )
+ nStatus |= QUEUE_STATUS_PAGE_PUNT;
+ if ( nWinStatus & PRINTER_STATUS_USER_INTERVENTION )
+ nStatus |= QUEUE_STATUS_USER_INTERVENTION;
+ if ( nWinStatus & PRINTER_STATUS_OUT_OF_MEMORY )
+ nStatus |= QUEUE_STATUS_OUT_OF_MEMORY;
+ if ( nWinStatus & PRINTER_STATUS_DOOR_OPEN )
+ nStatus |= QUEUE_STATUS_DOOR_OPEN;
+ if ( nWinStatus & PRINTER_STATUS_SERVER_UNKNOWN )
+ nStatus |= QUEUE_STATUS_SERVER_UNKNOWN;
+ if ( nWinStatus & PRINTER_STATUS_POWER_SAVE )
+ nStatus |= QUEUE_STATUS_POWER_SAVE;
+ if ( !nStatus && !(nWinStatus & PRINTER_STATUS_NOT_AVAILABLE) )
+ nStatus |= QUEUE_STATUS_READY;
+ return nStatus;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
+{
+// !!! UNICODE - NT Optimierung !!!
+ DWORD i;
+ DWORD n;
+ DWORD nBytes = 0;
+// DWORD nInfoRet;
+ DWORD nInfoPrn2;
+ BOOL bFound = FALSE;
+ PRINTER_INFO_2* pWinInfo2 = NULL;
+ PRINTER_INFO_2* pGetInfo2;
+ EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoPrn2 );
+ if ( nBytes )
+ {
+ pWinInfo2 = (PRINTER_INFO_2*)new BYTE[nBytes];
+ if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoPrn2 ) )
+ {
+ pGetInfo2 = pWinInfo2;
+ for ( i = 0; i < nInfoPrn2; i++ )
+ {
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+ pInfo->maPrinterName = ImplSalGetUniString( pGetInfo2->pPrinterName );
+ pInfo->maDriver = ImplSalGetUniString( pGetInfo2->pDriverName );
+ XubString aPortName;
+ if ( pGetInfo2->pPortName )
+ aPortName = ImplSalGetUniString( pGetInfo2->pPortName );
+ // pLocation can be 0 (the Windows docu doesn't describe this)
+ if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) )
+ pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation );
+ else
+ pInfo->maLocation = aPortName;
+ // pComment can be 0 (the Windows docu doesn't describe this)
+ if ( pGetInfo2->pComment )
+ pInfo->maComment = ImplSalGetUniString( pGetInfo2->pComment );
+ pInfo->mnStatus = ImplWinQueueStatusToSal( pGetInfo2->Status );
+ pInfo->mnJobs = pGetInfo2->cJobs;
+ pInfo->mpSysData = new XubString( aPortName );
+ pList->Add( pInfo );
+ pGetInfo2++;
+ }
+
+ bFound = TRUE;
+ }
+ }
+
+/* Siehe Kommentar unten !!!
+ EnumPrinters( PRINTER_ENUM_NETWORK | PRINTER_ENUM_REMOTE, NULL, 1, NULL, 0, &nBytes, &nInfoRet );
+ if ( nBytes )
+ {
+ PRINTER_INFO_1* pWinInfo1 = (PRINTER_INFO_1*)new BYTE[nBytes];
+ if ( EnumPrinters( PRINTER_ENUM_NETWORK | PRINTER_ENUM_REMOTE, NULL, 1, (LPBYTE)pWinInfo1, nBytes, &nBytes, &nInfoRet ) )
+ {
+ PRINTER_INFO_1* pGetInfo1 = pWinInfo1;
+ for ( i = 0; i < nInfoRet; i++ )
+ {
+ // Feststellen, ob Printer durch erste Abfrage schon gefunden
+ // wurde
+ BOOL bAdd = TRUE;
+ if ( pWinInfo2 )
+ {
+ pGetInfo2 = pWinInfo2;
+ for ( n = 0; n < nInfoPrn2; n++ )
+ {
+ if ( strcmp( pGetInfo1->pName, pGetInfo2->pPrinterName ) == 0 )
+ {
+ bAdd = FALSE;
+ break;
+ }
+ pGetInfo2++;
+ }
+ }
+ // Wenn neuer Printer, dann aufnehmen
+ if ( bAdd )
+ {
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+ XubString aPrnName( pGetInfo1->pName );
+ pInfo->maPrinterName = aPrnName;
+ pInfo->maDriver = "winspool";
+ pInfo->maComment = pGetInfo1->pComment;
+ pInfo->mnStatus = 0;
+ pInfo->mnJobs = QUEUE_JOBS_DONTKNOW;
+ pInfo->mpSysData = new String();
+ pList->Add( pInfo );
+ }
+ pGetInfo1++;
+ }
+
+ bFound = TRUE;
+ }
+
+ delete pWinInfo1;
+ }
+*/
+
+// if ( bFound )
+// return;
+
+// !!! UNICODE - NT Optimierung !!!
+ // Drucker aus WIN.INI lesen
+ UINT nSize = 4096;
+ char* pBuf = new char[nSize];
+ UINT nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize );
+ while ( nRead >= nSize-2 )
+ {
+ nSize += 2048;
+ delete pBuf;
+ pBuf = new char[nSize];
+ nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize );
+ }
+
+ // Druckernamen aus Buffer extrahieren und Liste aufbauen
+ char* pName = pBuf;
+ while ( *pName )
+ {
+ char* pPortName;
+ char* pTmp;
+ char aPortBuf[256];
+ GetProfileStringA( aImplDevices, pName, "", aPortBuf, sizeof( aPortBuf ) );
+
+ pPortName = aPortBuf;
+
+ // Namen anlegen
+ xub_StrLen nNameLen = strlen( pName );
+ XubString aName( ImplSalGetUniString( pName, nNameLen ) );
+
+ // Treibernamen rausfischen
+ pTmp = pPortName;
+ while ( *pTmp != ',' )
+ pTmp++;
+ XubString aDriver( ImplSalGetUniString( pPortName, (USHORT)(pTmp-pPortName) ) );
+ pPortName = pTmp;
+
+ // Alle Portnamen raussuchen
+ do
+ {
+ pPortName++;
+ pTmp = pPortName;
+ while ( *pTmp && (*pTmp != ',') )
+ pTmp++;
+
+ String aPortName( ImplSalGetUniString( pPortName, (USHORT)(pTmp-pPortName) ) );
+
+ // Neuen Eintrag anlegen
+ // !!! Da ich zu bloeb bin, die Netzwerk-Printer zur 5.0
+ // !!! richtig zu integrieren, gehen wir zusaetzlich
+ // !!! noch ueber das W16-Interface, da uns dort die
+ // !!! Drucker noch einfach und schnell geliefert werden
+ // !!! ohne das wir jetzt zu grossen Aufwand treiben muessen.
+ // !!! Somit sollten wir dann jedenfalls nicht schlechter sein
+ // !!! als in einer 4.0 SP2.
+ // Feststellen, ob Printer durch erste Abfrage schon gefunden
+ // wurde
+ BOOL bAdd = TRUE;
+ if ( pWinInfo2 )
+ {
+ pGetInfo2 = pWinInfo2;
+ for ( n = 0; n < nInfoPrn2; n++ )
+ {
+ if ( aName.EqualsIgnoreCaseAscii( pGetInfo2->pPrinterName ) )
+ {
+ bAdd = FALSE;
+ break;
+ }
+ pGetInfo2++;
+ }
+ }
+ // Wenn neuer Printer, dann aufnehmen
+ if ( bAdd )
+ {
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+ pInfo->maPrinterName = aName;
+ pInfo->maDriver = aDriver;
+ pInfo->maLocation = aPortName;
+ pInfo->mnStatus = 0;
+ pInfo->mnJobs = QUEUE_JOBS_DONTKNOW;
+ pInfo->mpSysData = new XubString( aPortName );
+ pList->Add( pInfo );
+ }
+ }
+ while ( *pTmp == ',' );
+
+ pName += nNameLen + 1;
+ }
+
+ delete pBuf;
+ delete pWinInfo2;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo )
+{
+// !!! UNICODE - NT Optimierung !!!
+ DWORD nBytes = 0;
+ DWORD nInfoRet;
+ PRINTER_INFO_2* pWinInfo2;
+ EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoRet );
+ if ( nBytes )
+ {
+ pWinInfo2 = (PRINTER_INFO_2*)new BYTE[nBytes];
+ if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoRet ) )
+ {
+ PRINTER_INFO_2* pGetInfo2 = pWinInfo2;
+ for ( DWORD i = 0; i < nInfoRet; i++ )
+ {
+ if ( pInfo->maPrinterName.EqualsAscii( pGetInfo2->pPrinterName ) &&
+ pInfo->maDriver.EqualsAscii( pGetInfo2->pDriverName ) )
+ {
+ if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) )
+ pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation );
+ else
+ pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pPortName );
+ pInfo->mnStatus = ImplWinQueueStatusToSal( pGetInfo2->Status );
+ pInfo->mnJobs = pGetInfo2->cJobs;
+ break;
+ }
+
+ pGetInfo2++;
+ }
+ }
+
+ delete pWinInfo2;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
+{
+ delete (String*)(pInfo->mpSysData);
+ delete pInfo;
+}
+
+// -----------------------------------------------------------------------
+
+// !!! UNICODE - NT Optimierung !!!
+XubString SalInstance::GetDefaultPrinter()
+{
+ // Default-Printer-String aus win.ini holen
+ char szBuffer[256];
+ GetProfileStringA( aImplWindows, aImplDevice, "", szBuffer, sizeof( szBuffer ) );
+ if ( szBuffer[0] )
+ {
+ // Printername suchen
+ char* pBuf = szBuffer;
+ char* pTmp = pBuf;
+ while ( *pTmp && (*pTmp != ',') )
+ pTmp++;
+ return ImplSalGetUniString( pBuf, (xub_StrLen)(pTmp-pBuf) );
+ }
+ else
+ return XubString();
+}
+
+// =======================================================================
+
+static DWORD ImplDeviceCaps( SalInfoPrinter* pPrinter, WORD nCaps,
+ LPTSTR pOutput, const ImplJobSetup* pSetupData )
+{
+ DEVMODE* pDevMode;
+ if ( !pSetupData || !pSetupData->mpDriverData )
+ pDevMode = NULL;
+ else
+ pDevMode = SAL_DEVMODE( pSetupData );
+
+// !!! UNICODE - NT Optimierung !!!
+ return DeviceCapabilitiesA( ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ ImplSalGetWinAnsiString( pPrinter->maPrinterData.maPortName, TRUE ).GetBuffer(),
+ nCaps, (LPSTR)pOutput, pDevMode );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplTestSalJobSetup( SalInfoPrinter* pPrinter,
+ ImplJobSetup* pSetupData, BOOL bDelete )
+{
+ if ( pSetupData && pSetupData->mpDriverData )
+ {
+ // Signature und Groesse muss uebereinstimmen, damit wir keine
+ // JobSetup's von anderen Systemen setzen
+ if ( (pSetupData->mnSystem == JOBSETUP_SYSTEM_WINDOWS) &&
+ (pSetupData->mnDriverDataLen > sizeof( SalDriverData )) &&
+ (((SalDriverData*)(pSetupData->mpDriverData))->mnSysSignature == SAL_DRIVERDATA_SYSSIGN) )
+ return TRUE;
+ else if ( bDelete )
+ {
+ delete pSetupData->mpDriverData;
+ pSetupData->mpDriverData = NULL;
+ pSetupData->mnDriverDataLen = 0;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplUpdateSalJobSetup( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData,
+ BOOL bIn, SalFrame* pVisibleDlgParent )
+{
+ HANDLE hPrn;
+// !!! UNICODE - NT Optimierung !!!
+ if ( !OpenPrinterA( (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(), &hPrn, NULL ) )
+ return FALSE;
+
+ LONG nRet;
+ LONG nSysJobSize;
+ HWND hWnd = 0;
+ DWORD nMode = DM_OUT_BUFFER;
+ ULONG nDriverDataLen = 0;
+ SalDriverData* pOutBuffer = NULL;
+ DEVMODE* pInDevBuffer = NULL;
+ DEVMODE* pOutDevBuffer = NULL;
+
+// !!! UNICODE - NT Optimierung !!!
+ nSysJobSize = DocumentPropertiesA( hWnd, hPrn,
+ (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ NULL, NULL, 0 );
+ if ( nSysJobSize < 0 )
+ {
+ ClosePrinter( hPrn );
+ return FALSE;
+ }
+
+ // Outputbuffer anlegen
+ nDriverDataLen = sizeof(SalDriverData)+nSysJobSize-1;
+ pOutBuffer = (SalDriverData*)SvMemAlloc( nDriverDataLen );
+ memset( pOutBuffer, 0, nDriverDataLen );
+ pOutDevBuffer = (LPDEVMODE)(pOutBuffer->maDriverData);
+ pOutBuffer->mnSysSignature = SAL_DRIVERDATA_SYSSIGN;
+ pOutBuffer->mnVersion = SAL_DRIVERDATA_VERSION;
+ pOutBuffer->mnDriverOffset = (USHORT)(((SalDriverData*)NULL)->maDriverData);
+
+ // Testen, ob wir einen geeigneten Inputbuffer haben
+ if ( bIn && ImplTestSalJobSetup( pPrinter, pSetupData, FALSE ) )
+ {
+ pInDevBuffer = SAL_DEVMODE( pSetupData );
+ nMode |= DM_IN_BUFFER;
+ }
+
+ // Testen, ob Dialog angezeigt werden soll
+ if ( pVisibleDlgParent )
+ {
+ hWnd = pVisibleDlgParent->maFrameData.mhWnd;
+ nMode |= DM_IN_PROMPT;
+ }
+
+// !!! UNICODE - NT Optimierung !!!
+ // Release mutex, in the other case we don't get paints and so on
+ ULONG nMutexCount = ImplSalReleaseYieldMutex();
+ nRet = DocumentPropertiesA( hWnd, hPrn,
+ (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ pOutDevBuffer, pInDevBuffer, nMode );
+ ImplSalAcquireYieldMutex( nMutexCount );
+ ClosePrinter( hPrn );
+
+ if ( (nRet < 0) || (pVisibleDlgParent && (nRet == IDCANCEL)) )
+ {
+ SvMemFree( pOutBuffer );
+ return FALSE;
+ }
+
+ // String-Buffer am Ende immer mit 0 initialisieren, damit
+ // die JobSetups nach Moeglichkeit bei memcmp immer
+ // identisch sind
+ if ( pOutDevBuffer->dmSize >= 32 )
+ {
+ USHORT nLen = strlen( (const char*)pOutDevBuffer->dmDeviceName );
+ if ( nLen < sizeof( pOutDevBuffer->dmDeviceName ) )
+ memset( pOutDevBuffer->dmDeviceName+nLen, 0, sizeof( pOutDevBuffer->dmDeviceName )-nLen );
+ }
+ if ( pOutDevBuffer->dmSize >= 102 )
+ {
+ USHORT nLen = strlen( (const char*)pOutDevBuffer->dmFormName );
+ if ( nLen < sizeof( pOutDevBuffer->dmFormName ) )
+ memset( pOutDevBuffer->dmFormName+nLen, 0, sizeof( pOutDevBuffer->dmFormName )-nLen );
+ }
+
+ // Daten updaten
+ if ( pSetupData->mpDriverData )
+ delete pSetupData->mpDriverData;
+ pSetupData->mnDriverDataLen = nDriverDataLen;
+ pSetupData->mpDriverData = (BYTE*)pOutBuffer;
+ pSetupData->mnSystem = JOBSETUP_SYSTEM_WINDOWS;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDevModeToJobSetup( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, ULONG nFlags )
+{
+ if ( !pSetupData || !pSetupData->mpDriverData )
+ return;
+
+ DEVMODE* pDevMode = SAL_DEVMODE( pSetupData );
+
+ // Orientation
+ if ( nFlags & SAL_JOBSET_ORIENTATION )
+ {
+ if ( pDevMode->dmOrientation == DMORIENT_PORTRAIT )
+ pSetupData->meOrientation = ORIENTATION_PORTRAIT;
+ else if ( pDevMode->dmOrientation == DMORIENT_LANDSCAPE )
+ pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
+ }
+
+ // PaperBin
+ if ( nFlags & SAL_JOBSET_PAPERBIN )
+ {
+ ULONG nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData );
+
+ if ( nCount && (nCount != ((ULONG)-1)) )
+ {
+ WORD* pBins = new WORD[nCount];
+ memset( (BYTE*)pBins, 0, nCount*sizeof(WORD) );
+ ImplDeviceCaps( pPrinter, DC_BINS, (LPTSTR)pBins, pSetupData );
+ pSetupData->mnPaperBin = 0;
+
+ // search the right bin and assign index to mnPaperBin
+ for( ULONG i = 0; i < nCount; i++ )
+ {
+ if( pDevMode->dmDefaultSource == pBins[ i ] )
+ {
+ pSetupData->mnPaperBin = (USHORT)i;
+ break;
+ }
+ }
+
+ delete[] pBins;
+ }
+ }
+
+ // PaperSize
+ if ( nFlags & SAL_JOBSET_PAPERSIZE )
+ {
+ pSetupData->mnPaperWidth = pDevMode->dmPaperWidth*10;
+ pSetupData->mnPaperHeight = pDevMode->dmPaperLength*10;
+ switch( pDevMode->dmPaperSize )
+ {
+ case( DMPAPER_A3 ):
+ pSetupData->mePaperFormat = PAPER_A3;
+ break;
+ case( DMPAPER_A4 ):
+ pSetupData->mePaperFormat = PAPER_A4;
+ break;
+ case( DMPAPER_A5 ):
+ pSetupData->mePaperFormat = PAPER_A5;
+ break;
+ case( DMPAPER_B4 ):
+ pSetupData->mePaperFormat = PAPER_B4;
+ break;
+ case( DMPAPER_B5 ):
+ pSetupData->mePaperFormat = PAPER_B5;
+ break;
+ case( DMPAPER_LETTER ):
+ pSetupData->mePaperFormat = PAPER_LETTER;
+ break;
+ case( DMPAPER_LEGAL ):
+ pSetupData->mePaperFormat = PAPER_LEGAL;
+ break;
+ case( DMPAPER_TABLOID ):
+ pSetupData->mePaperFormat = PAPER_TABLOID;
+ break;
+ default:
+ pSetupData->mePaperFormat = PAPER_USER;
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplPaperSizeEqual( short nPaperWidth1, short nPaperHeight1,
+ short nPaperWidth2, short nPaperHeight2 )
+{
+ return (((nPaperWidth1 >= nPaperWidth2-1) && (nPaperWidth1 <= nPaperWidth2+1)) &&
+ ((nPaperHeight1 >= nPaperHeight2-1) && (nPaperHeight1 <= nPaperHeight2+1)));
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplJobSetupToDevMode( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, ULONG nFlags )
+{
+ if ( !pSetupData || !pSetupData->mpDriverData )
+ return;
+
+ DEVMODE* pDevMode = SAL_DEVMODE( pSetupData );
+
+ // Orientation
+ if ( nFlags & SAL_JOBSET_ORIENTATION )
+ {
+ pDevMode->dmFields |= DM_ORIENTATION;
+ if ( pSetupData->meOrientation == ORIENTATION_PORTRAIT )
+ pDevMode->dmOrientation = DMORIENT_PORTRAIT;
+ else
+ pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
+ }
+
+ // PaperBin
+ if ( nFlags & SAL_JOBSET_PAPERBIN )
+ {
+ ULONG nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData );
+
+ if ( nCount && (nCount != ((ULONG)-1)) )
+ {
+ WORD* pBins = new WORD[nCount];
+ memset( pBins, 0, nCount*sizeof(WORD) );
+ ImplDeviceCaps( pPrinter, DC_BINS, (LPTSTR)pBins, pSetupData );
+ pDevMode->dmFields |= DM_DEFAULTSOURCE;
+ pDevMode->dmDefaultSource = pBins[ pSetupData->mnPaperBin ];
+ delete[] pBins;
+ }
+ }
+
+ // PaperSize
+ if ( nFlags & SAL_JOBSET_PAPERSIZE )
+ {
+ pDevMode->dmFields |= DM_PAPERSIZE;
+ pDevMode->dmPaperWidth = 0;
+ pDevMode->dmPaperLength = 0;
+
+ switch( pDevMode->dmPaperSize )
+ {
+ case( PAPER_A3 ):
+ pDevMode->dmPaperSize = DMPAPER_A3;
+ break;
+ case( PAPER_A4 ):
+ pDevMode->dmPaperSize = DMPAPER_A4;
+ break;
+ case( PAPER_A5 ):
+ pDevMode->dmPaperSize = DMPAPER_A5;
+ break;
+ case( PAPER_B4 ):
+ pDevMode->dmPaperSize = DMPAPER_B4;
+ break;
+ case( PAPER_B5 ):
+ pDevMode->dmPaperSize = DMPAPER_B5;
+ break;
+ case( PAPER_LETTER ):
+ pDevMode->dmPaperSize = DMPAPER_LETTER;
+ break;
+ case( PAPER_LEGAL ):
+ pDevMode->dmPaperSize = DMPAPER_LEGAL;
+ break;
+ case( PAPER_TABLOID ):
+ pDevMode->dmPaperSize = DMPAPER_TABLOID;
+ break;
+ default:
+ {
+ short nPaper = 0;
+ ULONG nPaperCount = ImplDeviceCaps( pPrinter, DC_PAPERS, NULL, pSetupData );
+ WORD* pPapers = NULL;
+ ULONG nPaperSizeCount = ImplDeviceCaps( pPrinter, DC_PAPERSIZE, NULL, pSetupData );
+ POINT* pPaperSizes = NULL;
+ if ( nPaperCount && (nPaperCount != ((ULONG)-1)) )
+ {
+ pPapers = new WORD[nPaperCount];
+ memset( pPapers, 0, nPaperCount*sizeof(WORD) );
+ ImplDeviceCaps( pPrinter, DC_PAPERS, (LPTSTR)pPapers, pSetupData );
+ }
+ if ( nPaperSizeCount && (nPaperSizeCount != ((ULONG)-1)) )
+ {
+ pPaperSizes = new POINT[nPaperSizeCount];
+ memset( pPaperSizes, 0, nPaperSizeCount*sizeof(POINT) );
+ ImplDeviceCaps( pPrinter, DC_PAPERSIZE, (LPTSTR)pPaperSizes, pSetupData );
+ }
+ if ( (nPaperSizeCount == nPaperCount) && pPapers && pPaperSizes )
+ {
+ // Alle Papierformate vergleichen und ein passendes
+ // raussuchen
+ for ( ULONG i = 0; i < nPaperCount; i++ )
+ {
+ if ( ImplPaperSizeEqual( (short)(pSetupData->mnPaperWidth/10),
+ (short)(pSetupData->mnPaperHeight/10),
+ (short)pPaperSizes[i].x,
+ (short)pPaperSizes[i].y ) )
+ {
+ nPaper = pPapers[i];
+ break;
+ }
+ }
+ }
+ if ( pPapers )
+ delete pPapers;
+ if ( pPaperSizes )
+ delete pPaperSizes;
+
+ if ( nPaper )
+ pDevMode->dmPaperSize = nPaper;
+ else
+ {
+ pDevMode->dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH;
+ pDevMode->dmPaperSize = DMPAPER_USER;
+ pDevMode->dmPaperWidth = pSetupData->mnPaperWidth/10;
+ pDevMode->dmPaperLength = pSetupData->mnPaperHeight/10;
+ }
+ }
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static HDC ImplCreateSalPrnIC( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData )
+{
+ LPDEVMODE pDevMode;
+ if ( pSetupData && pSetupData->mpDriverData )
+ pDevMode = SAL_DEVMODE( pSetupData );
+ else
+ pDevMode = NULL;
+// !!! UNICODE - NT Optimierung !!!
+ HDC hDC = CreateICA( ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDriverName, TRUE ).GetBuffer(),
+ ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ 0,
+ (LPDEVMODE)pDevMode );
+ return hDC;
+}
+
+// -----------------------------------------------------------------------
+
+static SalGraphics* ImplCreateSalPrnGraphics( HDC hDC )
+{
+ SalGraphics* pGraphics = new SalGraphics;
+ pGraphics->maGraphicsData.mhDC = hDC;
+ pGraphics->maGraphicsData.mhWnd = 0;
+ pGraphics->maGraphicsData.mbPrinter = TRUE;
+ pGraphics->maGraphicsData.mbVirDev = FALSE;
+ pGraphics->maGraphicsData.mbWindow = FALSE;
+ pGraphics->maGraphicsData.mbScreen = FALSE;
+ ImplSalInitGraphics( &(pGraphics->maGraphicsData) );
+ return pGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplUpdateSalPrnIC( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData )
+{
+ HDC hNewDC = ImplCreateSalPrnIC( pPrinter, pSetupData );
+ if ( !hNewDC )
+ return FALSE;
+
+ if ( pPrinter->maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) );
+ DeleteDC( pPrinter->maPrinterData.mpGraphics->maGraphicsData.mhDC );
+ delete pPrinter->maPrinterData.mpGraphics;
+ }
+
+ SalGraphics* pGraphics = ImplCreateSalPrnGraphics( hNewDC );
+ pPrinter->maPrinterData.mhDC = hNewDC;
+ pPrinter->maPrinterData.mpGraphics = pGraphics;
+
+ return TRUE;
+}
+
+// =======================================================================
+
+SalInfoPrinter* SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
+ ImplJobSetup* pSetupData )
+{
+ SalInfoPrinter* pPrinter = new SalInfoPrinter;
+ pPrinter->maPrinterData.maDriverName = pQueueInfo->maDriver;
+ pPrinter->maPrinterData.maDeviceName = pQueueInfo->maPrinterName;
+ pPrinter->maPrinterData.maPortName = *(String*)(pQueueInfo->mpSysData);
+
+ // Testen, ob Setupdaten zum Drucker gehoeren (erst aufrufen, nachdem
+ // die Member gesetzt sind, da diese in dieser Routine abgefragt werden)
+ ImplTestSalJobSetup( pPrinter, pSetupData, TRUE );
+
+ HDC hDC = ImplCreateSalPrnIC( pPrinter, pSetupData );
+ if ( !hDC )
+ {
+ delete pPrinter;
+ return NULL;
+ }
+
+ SalGraphics* pGraphics = ImplCreateSalPrnGraphics( hDC );
+ pPrinter->maPrinterData.mhDC = hDC;
+ pPrinter->maPrinterData.mpGraphics = pGraphics;
+ if ( !pSetupData->mpDriverData )
+ ImplUpdateSalJobSetup( pPrinter, pSetupData, FALSE, NULL );
+ ImplDevModeToJobSetup( pPrinter, pSetupData, SAL_JOBSET_ALL );
+ pSetupData->mnSystem = JOBSETUP_SYSTEM_WINDOWS;
+
+ return pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
+{
+ delete pPrinter;
+}
+
+// =======================================================================
+
+SalInfoPrinter::SalInfoPrinter()
+{
+ maPrinterData.mhDC = 0;
+ maPrinterData.mpGraphics = NULL;
+ maPrinterData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SalInfoPrinter::~SalInfoPrinter()
+{
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ DeleteDC( maPrinterData.mpGraphics->maGraphicsData.mhDC );
+ delete maPrinterData.mpGraphics;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalInfoPrinter::GetGraphics()
+{
+ if ( maPrinterData.mbGraphics )
+ return NULL;
+
+ if ( maPrinterData.mpGraphics )
+ maPrinterData.mbGraphics = TRUE;
+
+ return maPrinterData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInfoPrinter::ReleaseGraphics( SalGraphics* )
+{
+ maPrinterData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData )
+{
+ if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, pFrame ) )
+ {
+ ImplDevModeToJobSetup( this, pSetupData, SAL_JOBSET_ALL );
+ return ImplUpdateSalPrnIC( this, pSetupData );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::SetPrinterData( ImplJobSetup* pSetupData )
+{
+ if ( !ImplTestSalJobSetup( this, pSetupData, FALSE ) )
+ return FALSE;
+ return ImplUpdateSalPrnIC( this, pSetupData );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::SetData( ULONG nFlags, ImplJobSetup* pSetupData )
+{
+ ImplJobSetupToDevMode( this, pSetupData, nFlags );
+ if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, NULL ) )
+ {
+ ImplDevModeToJobSetup( this, pSetupData, nFlags );
+ return ImplUpdateSalPrnIC( this, pSetupData );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pSetupData )
+{
+ DWORD nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return nRet;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pSetupData, ULONG nPaperBin )
+{
+// !!! UNICODE - NT Optimierung !!!
+ XubString aPaperBinName;
+
+ DWORD nBins = ImplDeviceCaps( this, DC_BINNAMES, NULL, pSetupData );
+ if ( (nPaperBin < nBins) && (nBins != ((ULONG)-1)) )
+ {
+ char* pBuffer = new char[nBins*24];
+ DWORD nRet = ImplDeviceCaps( this, DC_BINNAMES, pBuffer, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ aPaperBinName = ImplSalGetUniString( (const char*)(pBuffer + (nPaperBin*24)) );
+ delete pBuffer;
+ }
+
+ return aPaperBinName;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInfoPrinter::GetCapabilities( const ImplJobSetup* pSetupData, USHORT nType )
+{
+ DWORD nRet;
+
+ switch ( nType )
+ {
+ case PRINTER_CAPABILITIES_SUPPORTDIALOG:
+ return TRUE;
+ case PRINTER_CAPABILITIES_COPIES:
+ nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return nRet;
+ return 0;
+ case PRINTER_CAPABILITIES_COLLATECOPIES:
+ if ( aSalShlData.mbW40 )
+ {
+ nRet = ImplDeviceCaps( this, DC_COLLATE, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ {
+ nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return nRet;
+ }
+ }
+ return 0;
+
+ case PRINTER_CAPABILITIES_SETORIENTATION:
+ nRet = ImplDeviceCaps( this, DC_ORIENTATION, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return TRUE;
+ return FALSE;
+
+ case PRINTER_CAPABILITIES_SETPAPERBIN:
+ nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return TRUE;
+ return FALSE;
+
+ case PRINTER_CAPABILITIES_SETPAPERSIZE:
+ case PRINTER_CAPABILITIES_SETPAPER:
+ nRet = ImplDeviceCaps( this, DC_PAPERS, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return TRUE;
+ return FALSE;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInfoPrinter::GetPageInfo( const ImplJobSetup*,
+ long& rOutWidth, long& rOutHeight,
+ long& rPageOffX, long& rPageOffY,
+ long& rPageWidth, long& rPageHeight )
+{
+ HDC hDC = maPrinterData.mhDC;
+
+ rOutWidth = GetDeviceCaps( hDC, HORZRES );
+ rOutHeight = GetDeviceCaps( hDC, VERTRES );
+
+ rPageOffX = GetDeviceCaps( hDC, PHYSICALOFFSETX );
+ rPageOffY = GetDeviceCaps( hDC, PHYSICALOFFSETY );
+ rPageWidth = GetDeviceCaps( hDC, PHYSICALWIDTH );
+ rPageHeight = GetDeviceCaps( hDC, PHYSICALHEIGHT );
+}
+
+// =======================================================================
+
+SalPrinter* SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
+{
+ SalPrinter* pPrinter = new SalPrinter;
+ pPrinter->maPrinterData.mpInfoPrinter = pInfoPrinter;
+ return pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyPrinter( SalPrinter* pPrinter )
+{
+ delete pPrinter;
+}
+
+// =======================================================================
+
+WIN_BOOL CALLBACK SalPrintAbortProc( HDC hPrnDC, int /* nError */ )
+{
+ SalData* pSalData = GetSalData();
+ SalPrinter* pPrinter;
+ BOOL bWhile = TRUE;
+ int i = 0;
+
+ do
+ {
+ // Messages verarbeiten
+ MSG aMsg;
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplDispatchMessage( &aMsg );
+ i++;
+ if ( i > 15 )
+ bWhile = FALSE;
+ }
+ else
+ bWhile = FALSE;
+
+ pPrinter = pSalData->mpFirstPrinter;
+ while ( pPrinter )
+ {
+ if( pPrinter->maPrinterData.mhDC == hPrnDC )
+ break;
+
+ pPrinter = pPrinter->maPrinterData.mpNextPrinter;
+ }
+
+ if ( !pPrinter || pPrinter->maPrinterData.mbAbort )
+ return FALSE;
+ }
+ while ( bWhile );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+static LPDEVMODE ImplSalSetCopies( LPDEVMODE pDevMode, ULONG nCopies, BOOL bCollate )
+{
+ LPDEVMODE pNewDevMode = pDevMode;
+ if ( pDevMode && (nCopies > 1) )
+ {
+ if ( nCopies > 32765 )
+ nCopies = 32765;
+ ULONG nDevSize = pDevMode->dmSize+pDevMode->dmDriverExtra;
+ pNewDevMode = (LPDEVMODE)new BYTE[nDevSize];
+ memcpy( pNewDevMode, pDevMode, nDevSize );
+ pDevMode = pNewDevMode;
+ pDevMode->dmFields |= DM_COPIES;
+ pDevMode->dmCopies = (short)(USHORT)nCopies;
+ if ( aSalShlData.mbW40 )
+ {
+ pDevMode->dmFields |= DM_COLLATE;
+ if ( bCollate )
+ pDevMode->dmCollate = DMCOLLATE_TRUE;
+ else
+ pDevMode->dmCollate = DMCOLLATE_FALSE;
+ }
+ }
+
+ return pNewDevMode;
+}
+
+// -----------------------------------------------------------------------
+
+SalPrinter::SalPrinter()
+{
+ SalData* pSalData = GetSalData();
+
+ maPrinterData.mhDC = 0;
+ maPrinterData.mpGraphics = NULL;
+ maPrinterData.mbAbort = FALSE;
+ maPrinterData.mnCopies = 0;
+ maPrinterData.mbCollate = FALSE;
+
+ // insert frame in framelist
+ maPrinterData.mpNextPrinter = pSalData->mpFirstPrinter;
+ pSalData->mpFirstPrinter = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalPrinter::~SalPrinter()
+{
+ SalData* pSalData = GetSalData();
+
+ // DC freigeben, wenn er noch durch ein AbortJob existiert
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC )
+ {
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ }
+
+ DeleteDC( hDC );
+ }
+
+ // remove printer from printerlist
+ if ( this == pSalData->mpFirstPrinter )
+ pSalData->mpFirstPrinter = maPrinterData.mpNextPrinter;
+ else
+ {
+ SalPrinter* pTempPrinter = pSalData->mpFirstPrinter;
+
+ while( pTempPrinter->maPrinterData.mpNextPrinter != this )
+ pTempPrinter = pTempPrinter->maPrinterData.mpNextPrinter;
+
+ pTempPrinter->maPrinterData.mpNextPrinter = maPrinterData.mpNextPrinter;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::StartJob( const XubString* pFileName,
+ const XubString& rJobName,
+ const XubString&,
+ ULONG nCopies, BOOL bCollate,
+ ImplJobSetup* pSetupData )
+{
+ maPrinterData.mnError = 0;
+ maPrinterData.mbAbort = FALSE;
+ maPrinterData.mnCopies = nCopies;
+ maPrinterData.mbCollate = bCollate;
+
+ LPDEVMODE pOrgDevMode = NULL;
+ LPDEVMODE pDevMode;
+ BOOL bOwnDevMode = FALSE;
+ if ( pSetupData && pSetupData->mpDriverData )
+ {
+ pOrgDevMode = SAL_DEVMODE( pSetupData );
+ pDevMode = ImplSalSetCopies( pOrgDevMode, nCopies, bCollate );
+ }
+ else
+ pDevMode = NULL;
+
+// !!! UNICODE - NT Optimierung !!!
+ HDC hDC = CreateDCA( ImplSalGetWinAnsiString( maPrinterData.mpInfoPrinter->maPrinterData.maDriverName, TRUE ).GetBuffer(),
+ ImplSalGetWinAnsiString( maPrinterData.mpInfoPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ 0,
+ (LPDEVMODEA)pDevMode );
+
+ if ( pDevMode != pOrgDevMode )
+ delete pDevMode;
+
+ if ( !hDC )
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ if ( SetAbortProc( hDC, SalPrintAbortProc ) <= 0 )
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ maPrinterData.mnError = 0;
+ maPrinterData.mbAbort = FALSE;
+
+// !!! UNICODE - NT Optimierung !!!
+ // Both strings must be exist, if StartJob() is called
+ ByteString aJobName( ImplSalGetWinAnsiString( rJobName, TRUE ) );
+ ByteString aFileName;
+
+ DOCINFO aInfo;
+ memset( &aInfo, 0, sizeof( DOCINFO ) );
+ aInfo.cbSize = sizeof( aInfo );
+ aInfo.lpszDocName = (LPCSTR)aJobName.GetBuffer();
+ if ( pFileName )
+ {
+ if ( pFileName->Len() )
+ {
+ aFileName = ImplSalGetWinAnsiString( *pFileName, TRUE );
+ aInfo.lpszOutput = (LPCSTR)aFileName.GetBuffer();
+ }
+ else
+ aInfo.lpszOutput = "FILE:";
+ }
+ else
+ aInfo.lpszOutput = NULL;
+
+ // Wegen Telocom Balloon Fax-Treiber, der uns unsere Messages
+ // ansonsten oefters schickt, versuchen wir vorher alle
+ // zu verarbeiten und dann eine Dummy-Message reinstellen
+ BOOL bWhile = TRUE;
+ int i = 0;
+ do
+ {
+ // Messages verarbeiten
+ MSG aMsg;
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplDispatchMessage( &aMsg );
+ i++;
+ if ( i > 15 )
+ bWhile = FALSE;
+ }
+ else
+ bWhile = FALSE;
+ }
+ while ( bWhile );
+ ImplPostMessage( GetSalData()->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_DUMMY, 0, 0 );
+
+ // Job starten
+ int nRet = ::StartDoc( hDC, &aInfo );
+ if ( nRet <= 0 )
+ {
+ if ( (nRet == SP_USERABORT) || (nRet == SP_APPABORT) || (GetLastError() == ERROR_PRINT_CANCELLED) )
+ maPrinterData.mnError = SAL_PRINTER_ERROR_ABORT;
+ else
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ maPrinterData.mhDC = hDC;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::EndJob()
+{
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC )
+ {
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ maPrinterData.mpGraphics = NULL;
+ }
+
+ ::EndDoc( hDC );
+ DeleteDC( hDC );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::AbortJob()
+{
+ maPrinterData.mbAbort = TRUE;
+
+ // Abort asyncron ausloesen
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC )
+ {
+ SalData* pSalData = GetSalData();
+ ImplPostMessage( pSalData->mpFirstInstance->maInstData.mhComWnd,
+ SAL_MSG_PRINTABORTJOB, (WPARAM)hDC, 0 );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalPrinterAbortJobAsync( HDC hPrnDC )
+{
+ SalData* pSalData = GetSalData();
+ SalPrinter* pPrinter = pSalData->mpFirstPrinter;
+
+ // Feststellen, ob Printer noch existiert
+ while ( pPrinter )
+ {
+ if ( pPrinter->maPrinterData.mhDC == hPrnDC )
+ break;
+
+ pPrinter = pPrinter->maPrinterData.mpNextPrinter;
+ }
+
+ // Wenn Printer noch existiert, dann den Job abbrechen
+ if ( pPrinter )
+ {
+ HDC hDC = pPrinter->maPrinterData.mhDC;
+ if ( hDC )
+ {
+ if ( pPrinter->maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) );
+ delete pPrinter->maPrinterData.mpGraphics;
+ pPrinter->maPrinterData.mpGraphics = NULL;
+ }
+
+ ::AbortDoc( hDC );
+ DeleteDC( hDC );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalPrinter::StartPage( ImplJobSetup* pSetupData, BOOL bNewJobData )
+{
+ HDC hDC = maPrinterData.mhDC;
+ if ( pSetupData && pSetupData->mpDriverData && bNewJobData )
+ {
+ LPDEVMODE pOrgDevMode;
+ LPDEVMODE pDevMode;
+ pOrgDevMode = SAL_DEVMODE( pSetupData );
+ pDevMode = ImplSalSetCopies( pOrgDevMode, maPrinterData.mnCopies, maPrinterData.mbCollate );
+ ResetDC( hDC, pDevMode );
+ if ( pDevMode != pOrgDevMode )
+ delete pDevMode;
+ }
+ int nRet = ::StartPage( hDC );
+ if ( nRet <= 0 )
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return NULL;
+ }
+
+ // Hack, damit alte PS-Treiber Leerseiten nicht wegoptimieren
+ HPEN hTempPen = SelectPen( hDC, GetStockPen( NULL_PEN ) );
+ HBRUSH hTempBrush = SelectBrush( hDC, GetStockBrush( NULL_BRUSH ) );
+ WIN_Rectangle( hDC, -8000, -8000, -7999, -7999 );
+ SelectPen( hDC, hTempPen );
+ SelectBrush( hDC, hTempBrush );
+
+ SalGraphics* pGraphics = new SalGraphics;
+ pGraphics->maGraphicsData.mhDC = hDC;
+ pGraphics->maGraphicsData.mhWnd = 0;
+ pGraphics->maGraphicsData.mbPrinter = TRUE;
+ pGraphics->maGraphicsData.mbVirDev = FALSE;
+ pGraphics->maGraphicsData.mbWindow = FALSE;
+ pGraphics->maGraphicsData.mbScreen = FALSE;
+ ImplSalInitGraphics( &(pGraphics->maGraphicsData) );
+ maPrinterData.mpGraphics = pGraphics;
+ return pGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::EndPage()
+{
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC && maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ maPrinterData.mpGraphics = NULL;
+ }
+ int nRet = ::EndPage( hDC );
+ if ( nRet > 0 )
+ return TRUE;
+ else
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalPrinter::GetErrorCode()
+{
+ return maPrinterData.mnError;
+}
diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx
new file mode 100644
index 000000000000..d9f79ce479a8
--- /dev/null
+++ b/vcl/win/source/gdi/salvd.cxx
@@ -0,0 +1,226 @@
+/*************************************************************************
+ *
+ * $RCSfile: salvd.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALVD_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+
+// =======================================================================
+
+static HBITMAP ImplCreateVirDevBitmap( HDC hDC, long nDX, long nDY,
+ USHORT nBitCount )
+{
+ HBITMAP hBitmap;
+
+ if ( nBitCount == 1 )
+ hBitmap = CreateBitmap( (int)nDX, (int)nDY, 1, 1, NULL );
+ else
+ hBitmap = CreateCompatibleBitmap( hDC, (int)nDX, (int)nDY );
+
+ return hBitmap;
+}
+
+// =======================================================================
+
+SalVirtualDevice* SalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ USHORT nBitCount )
+{
+ HDC hDC = CreateCompatibleDC( pGraphics->maGraphicsData.mhDC );
+ HBITMAP hBmp = ImplCreateVirDevBitmap( pGraphics->maGraphicsData.mhDC,
+ nDX, nDY, nBitCount );
+
+ if ( hDC && hBmp )
+ {
+ SalVirtualDevice* pVDev = new SalVirtualDevice;
+ SalData* pSalData = GetSalData();
+ SalGraphics* pVirGraphics = new SalGraphics;
+ pVirGraphics->maGraphicsData.mhDC = hDC;
+ pVirGraphics->maGraphicsData.mhWnd = 0;
+ pVirGraphics->maGraphicsData.mbPrinter = FALSE;
+ pVirGraphics->maGraphicsData.mbVirDev = TRUE;
+ pVirGraphics->maGraphicsData.mbWindow = FALSE;
+ pVirGraphics->maGraphicsData.mbScreen = pGraphics->maGraphicsData.mbScreen;
+ if ( pSalData->mhDitherPal && pVirGraphics->maGraphicsData.mbScreen )
+ {
+ pVirGraphics->maGraphicsData.mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( hDC );
+ }
+ ImplSalInitGraphics( &(pVirGraphics->maGraphicsData) );
+
+ pVDev->maVirDevData.mhDC = hDC;
+ pVDev->maVirDevData.mhBmp = hBmp;
+ pVDev->maVirDevData.mhDefBmp = SelectBitmap( hDC, hBmp );
+ pVDev->maVirDevData.mpGraphics = pVirGraphics;
+ pVDev->maVirDevData.mnBitCount = nBitCount;
+ pVDev->maVirDevData.mbGraphics = FALSE;
+
+ // insert VirDev in VirDevList
+ pVDev->maVirDevData.mpNext = pSalData->mpFirstVD;
+ pSalData->mpFirstVD = pVDev;
+
+ return pVDev;
+ }
+ else
+ {
+ if ( hDC )
+ DeleteDC( hDC );
+ if ( hBmp )
+ DeleteBitmap( hBmp );
+ return NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
+{
+ delete pDevice;
+}
+
+// =======================================================================
+
+SalVirtualDevice::SalVirtualDevice()
+{
+}
+
+// -----------------------------------------------------------------------
+
+SalVirtualDevice::~SalVirtualDevice()
+{
+ SalData* pSalData = GetSalData();
+
+ // destroy saved DC
+ if ( maVirDevData.mpGraphics->maGraphicsData.mhDefPal )
+ SelectPalette( maVirDevData.mpGraphics->maGraphicsData.mhDC, maVirDevData.mpGraphics->maGraphicsData.mhDefPal, TRUE );
+ ImplSalDeInitGraphics( &(maVirDevData.mpGraphics->maGraphicsData) );
+ SelectBitmap( maVirDevData.mpGraphics->maGraphicsData.mhDC, maVirDevData.mhDefBmp );
+ DeleteDC( maVirDevData.mpGraphics->maGraphicsData.mhDC );
+ DeleteBitmap( maVirDevData.mhBmp );
+ delete maVirDevData.mpGraphics;
+
+ // remove VirDev from VirDevList
+ if ( this == pSalData->mpFirstVD )
+ pSalData->mpFirstVD = maVirDevData.mpNext;
+ else
+ {
+ SalVirtualDevice* pTempVD = pSalData->mpFirstVD;
+ while ( pTempVD->maVirDevData.mpNext != this )
+ pTempVD = pTempVD->maVirDevData.mpNext;
+
+ pTempVD->maVirDevData.mpNext = maVirDevData.mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalVirtualDevice::GetGraphics()
+{
+ if ( maVirDevData.mbGraphics )
+ return NULL;
+
+ if ( maVirDevData.mpGraphics )
+ maVirDevData.mbGraphics = TRUE;
+
+ return maVirDevData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{
+ maVirDevData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalVirtualDevice::SetSize( long nDX, long nDY )
+{
+ HBITMAP hNewBmp = ImplCreateVirDevBitmap( maVirDevData.mhDC, nDX, nDY,
+ maVirDevData.mnBitCount );
+ if ( hNewBmp )
+ {
+ SelectBitmap( maVirDevData.mhDC, hNewBmp );
+ DeleteBitmap( maVirDevData.mhBmp );
+ maVirDevData.mhBmp = hNewBmp;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
diff --git a/vcl/win/source/gdi/wntgdi.cxx b/vcl/win/source/gdi/wntgdi.cxx
new file mode 100644
index 000000000000..0bd7751c97e9
--- /dev/null
+++ b/vcl/win/source/gdi/wntgdi.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * $RCSfile: wntgdi.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <windows.h>
+
+// -----------------------------------------------------------------------
+
+extern "C"
+{
+BOOL WINAPI WIN_Rectangle( HDC hDC, int X1, int Y1, int X2, int Y2 )
+{
+ return Rectangle( hDC, X1, Y1, X2, Y2 );
+}
+}
+
+// -----------------------------------------------------------------------
+
+extern "C"
+{
+BOOL WINAPI WIN_Polygon( HDC hDC, CONST POINT * ppt, int ncnt )
+{
+ return Polygon( hDC, ppt, ncnt );
+}
+}
+
+// -----------------------------------------------------------------------
+
+extern "C"
+{
+BOOL WINAPI WIN_PolyPolygon( HDC hDC, CONST POINT * ppt, LPINT npcnt, int ncnt )
+{
+ return PolyPolygon( hDC, ppt, npcnt, ncnt );
+}
+}
diff --git a/vcl/win/source/src/50.bmp b/vcl/win/source/src/50.bmp
new file mode 100644
index 000000000000..b9d56fcd14c1
--- /dev/null
+++ b/vcl/win/source/src/50.bmp
Binary files differ
diff --git a/vcl/win/source/src/MAKEFILE.MK b/vcl/win/source/src/MAKEFILE.MK
new file mode 100644
index 000000000000..463741b23bb7
--- /dev/null
+++ b/vcl/win/source/src/MAKEFILE.MK
@@ -0,0 +1,106 @@
+#*************************************************************************
+#*
+#* $Workfile: makefile. $
+#*
+#* Ersterstellung TH 01.04.97
+#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:49 $
+#* $Revision: 1.1.1.1 $
+#*
+#* $Logfile: T:/vcl/win/source/src/makefile.__v $
+#*
+#* Copyright (c) 1990 - 2000, STAR DIVISION
+#*
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salsrc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+RCDEPN= nullptr.cur \
+ help.cur \
+ hsize.cur \
+ vsize.cur \
+ neswsize.cur \
+ nwsesize.cur \
+ cross.cur \
+ move.cur \
+ hsplit.cur \
+ vsplit.cur \
+ hsizebar.cur \
+ vsizebar.cur \
+ hand.cur \
+ refhand.cur \
+ pen.cur \
+ magnify.cur \
+ fill.cur \
+ rotate.cur \
+ hshear.cur \
+ vshear.cur \
+ mirror.cur \
+ crook.cur \
+ crop.cur \
+ movept.cur \
+ movebw.cur \
+ movedata.cur \
+ copydata.cur \
+ linkdata.cur \
+ movedlnk.cur \
+ copydlnk.cur \
+ movef.cur \
+ copyf.cur \
+ linkf.cur \
+ moveflnk.cur \
+ copyflnk.cur \
+ movef2.cur \
+ copyf2.cur \
+ notallow.cur \
+ dline.cur \
+ drect.cur \
+ dpolygon.cur \
+ dbezier.cur \
+ darc.cur \
+ dpie.cur \
+ dcirccut.cur \
+ dellipse.cur \
+ dfree.cur \
+ dconnect.cur \
+ dtext.cur \
+ dcapt.cur \
+ chart.cur \
+ detectiv.cur \
+ pivotcol.cur \
+ pivotrow.cur \
+ pivotfld.cur \
+ chain.cur \
+ chainnot.cur \
+ timemove.cur \
+ timesize.cur \
+ asn.cur \
+ ass.cur \
+ asw.cur \
+ ase.cur \
+ asnw.cur \
+ asne.cur \
+ assw.cur \
+ asse.cur \
+ asns.cur \
+ aswe.cur \
+ asnswe.cur \
+ airbrush.cur \
+ 50.bmp \
+ sd.ico
+
+RCFILES= salsrc.rc
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/win/source/src/airbrush.cur b/vcl/win/source/src/airbrush.cur
new file mode 100644
index 000000000000..f6a684e6fcbd
--- /dev/null
+++ b/vcl/win/source/src/airbrush.cur
Binary files differ
diff --git a/vcl/win/source/src/ase.cur b/vcl/win/source/src/ase.cur
new file mode 100755
index 000000000000..7634a7d34a7b
--- /dev/null
+++ b/vcl/win/source/src/ase.cur
Binary files differ
diff --git a/vcl/win/source/src/asn.cur b/vcl/win/source/src/asn.cur
new file mode 100755
index 000000000000..e444e42bf37e
--- /dev/null
+++ b/vcl/win/source/src/asn.cur
Binary files differ
diff --git a/vcl/win/source/src/asne.cur b/vcl/win/source/src/asne.cur
new file mode 100755
index 000000000000..e92cc65e7eb1
--- /dev/null
+++ b/vcl/win/source/src/asne.cur
Binary files differ
diff --git a/vcl/win/source/src/asns.cur b/vcl/win/source/src/asns.cur
new file mode 100755
index 000000000000..04d0b09c353e
--- /dev/null
+++ b/vcl/win/source/src/asns.cur
Binary files differ
diff --git a/vcl/win/source/src/asnswe.cur b/vcl/win/source/src/asnswe.cur
new file mode 100755
index 000000000000..a0e25b16de1f
--- /dev/null
+++ b/vcl/win/source/src/asnswe.cur
Binary files differ
diff --git a/vcl/win/source/src/asnw.cur b/vcl/win/source/src/asnw.cur
new file mode 100755
index 000000000000..20322bc97b16
--- /dev/null
+++ b/vcl/win/source/src/asnw.cur
Binary files differ
diff --git a/vcl/win/source/src/ass.cur b/vcl/win/source/src/ass.cur
new file mode 100755
index 000000000000..7166636a1a77
--- /dev/null
+++ b/vcl/win/source/src/ass.cur
Binary files differ
diff --git a/vcl/win/source/src/asse.cur b/vcl/win/source/src/asse.cur
new file mode 100755
index 000000000000..8cb71234b0a9
--- /dev/null
+++ b/vcl/win/source/src/asse.cur
Binary files differ
diff --git a/vcl/win/source/src/assw.cur b/vcl/win/source/src/assw.cur
new file mode 100755
index 000000000000..fddaf3f57cbf
--- /dev/null
+++ b/vcl/win/source/src/assw.cur
Binary files differ
diff --git a/vcl/win/source/src/asw.cur b/vcl/win/source/src/asw.cur
new file mode 100755
index 000000000000..0ccac50f4596
--- /dev/null
+++ b/vcl/win/source/src/asw.cur
Binary files differ
diff --git a/vcl/win/source/src/aswe.cur b/vcl/win/source/src/aswe.cur
new file mode 100755
index 000000000000..c238b7e10aef
--- /dev/null
+++ b/vcl/win/source/src/aswe.cur
Binary files differ
diff --git a/vcl/win/source/src/chain.cur b/vcl/win/source/src/chain.cur
new file mode 100755
index 000000000000..02abb7ab714f
--- /dev/null
+++ b/vcl/win/source/src/chain.cur
Binary files differ
diff --git a/vcl/win/source/src/chainnot.cur b/vcl/win/source/src/chainnot.cur
new file mode 100755
index 000000000000..938ece03f329
--- /dev/null
+++ b/vcl/win/source/src/chainnot.cur
Binary files differ
diff --git a/vcl/win/source/src/chart.cur b/vcl/win/source/src/chart.cur
new file mode 100644
index 000000000000..25fe85b76039
--- /dev/null
+++ b/vcl/win/source/src/chart.cur
Binary files differ
diff --git a/vcl/win/source/src/copydata.cur b/vcl/win/source/src/copydata.cur
new file mode 100644
index 000000000000..d3c4bc93afd5
--- /dev/null
+++ b/vcl/win/source/src/copydata.cur
Binary files differ
diff --git a/vcl/win/source/src/copydlnk.cur b/vcl/win/source/src/copydlnk.cur
new file mode 100644
index 000000000000..495fd5e17776
--- /dev/null
+++ b/vcl/win/source/src/copydlnk.cur
Binary files differ
diff --git a/vcl/win/source/src/copyf.cur b/vcl/win/source/src/copyf.cur
new file mode 100644
index 000000000000..450c09443a84
--- /dev/null
+++ b/vcl/win/source/src/copyf.cur
Binary files differ
diff --git a/vcl/win/source/src/copyf2.cur b/vcl/win/source/src/copyf2.cur
new file mode 100644
index 000000000000..ac8de5da6ba5
--- /dev/null
+++ b/vcl/win/source/src/copyf2.cur
Binary files differ
diff --git a/vcl/win/source/src/copyflnk.cur b/vcl/win/source/src/copyflnk.cur
new file mode 100644
index 000000000000..e67f0539fa43
--- /dev/null
+++ b/vcl/win/source/src/copyflnk.cur
Binary files differ
diff --git a/vcl/win/source/src/crook.cur b/vcl/win/source/src/crook.cur
new file mode 100644
index 000000000000..c40cf591e261
--- /dev/null
+++ b/vcl/win/source/src/crook.cur
Binary files differ
diff --git a/vcl/win/source/src/crop.cur b/vcl/win/source/src/crop.cur
new file mode 100644
index 000000000000..327fb06976c2
--- /dev/null
+++ b/vcl/win/source/src/crop.cur
Binary files differ
diff --git a/vcl/win/source/src/cross.cur b/vcl/win/source/src/cross.cur
new file mode 100644
index 000000000000..8fd9762386b1
--- /dev/null
+++ b/vcl/win/source/src/cross.cur
Binary files differ
diff --git a/vcl/win/source/src/darc.cur b/vcl/win/source/src/darc.cur
new file mode 100644
index 000000000000..38504fa23c4a
--- /dev/null
+++ b/vcl/win/source/src/darc.cur
Binary files differ
diff --git a/vcl/win/source/src/dbezier.cur b/vcl/win/source/src/dbezier.cur
new file mode 100644
index 000000000000..f630b837ddf8
--- /dev/null
+++ b/vcl/win/source/src/dbezier.cur
Binary files differ
diff --git a/vcl/win/source/src/dcapt.cur b/vcl/win/source/src/dcapt.cur
new file mode 100644
index 000000000000..10dd5ba0d676
--- /dev/null
+++ b/vcl/win/source/src/dcapt.cur
Binary files differ
diff --git a/vcl/win/source/src/dcirccut.cur b/vcl/win/source/src/dcirccut.cur
new file mode 100644
index 000000000000..b19d3f8257f4
--- /dev/null
+++ b/vcl/win/source/src/dcirccut.cur
Binary files differ
diff --git a/vcl/win/source/src/dconnect.cur b/vcl/win/source/src/dconnect.cur
new file mode 100644
index 000000000000..5318d8f22d8b
--- /dev/null
+++ b/vcl/win/source/src/dconnect.cur
Binary files differ
diff --git a/vcl/win/source/src/dellipse.cur b/vcl/win/source/src/dellipse.cur
new file mode 100644
index 000000000000..c489a640335e
--- /dev/null
+++ b/vcl/win/source/src/dellipse.cur
Binary files differ
diff --git a/vcl/win/source/src/detectiv.cur b/vcl/win/source/src/detectiv.cur
new file mode 100644
index 000000000000..30e5685b64b2
--- /dev/null
+++ b/vcl/win/source/src/detectiv.cur
Binary files differ
diff --git a/vcl/win/source/src/dfree.cur b/vcl/win/source/src/dfree.cur
new file mode 100644
index 000000000000..3ff56d007648
--- /dev/null
+++ b/vcl/win/source/src/dfree.cur
Binary files differ
diff --git a/vcl/win/source/src/dline.cur b/vcl/win/source/src/dline.cur
new file mode 100644
index 000000000000..623c33ac2351
--- /dev/null
+++ b/vcl/win/source/src/dline.cur
Binary files differ
diff --git a/vcl/win/source/src/dpie.cur b/vcl/win/source/src/dpie.cur
new file mode 100644
index 000000000000..3b911cd01e43
--- /dev/null
+++ b/vcl/win/source/src/dpie.cur
Binary files differ
diff --git a/vcl/win/source/src/dpolygon.cur b/vcl/win/source/src/dpolygon.cur
new file mode 100644
index 000000000000..9467f1e286aa
--- /dev/null
+++ b/vcl/win/source/src/dpolygon.cur
Binary files differ
diff --git a/vcl/win/source/src/drect.cur b/vcl/win/source/src/drect.cur
new file mode 100644
index 000000000000..60a5242c203c
--- /dev/null
+++ b/vcl/win/source/src/drect.cur
Binary files differ
diff --git a/vcl/win/source/src/dtext.cur b/vcl/win/source/src/dtext.cur
new file mode 100644
index 000000000000..01e7d31eae7e
--- /dev/null
+++ b/vcl/win/source/src/dtext.cur
Binary files differ
diff --git a/vcl/win/source/src/fill.cur b/vcl/win/source/src/fill.cur
new file mode 100644
index 000000000000..78f5fad87ad0
--- /dev/null
+++ b/vcl/win/source/src/fill.cur
Binary files differ
diff --git a/vcl/win/source/src/hand.cur b/vcl/win/source/src/hand.cur
new file mode 100644
index 000000000000..fc0e53b474e2
--- /dev/null
+++ b/vcl/win/source/src/hand.cur
Binary files differ
diff --git a/vcl/win/source/src/help.cur b/vcl/win/source/src/help.cur
new file mode 100644
index 000000000000..e59ee97992b3
--- /dev/null
+++ b/vcl/win/source/src/help.cur
Binary files differ
diff --git a/vcl/win/source/src/hshear.cur b/vcl/win/source/src/hshear.cur
new file mode 100644
index 000000000000..5cf2211458c3
--- /dev/null
+++ b/vcl/win/source/src/hshear.cur
Binary files differ
diff --git a/vcl/win/source/src/hsize.cur b/vcl/win/source/src/hsize.cur
new file mode 100644
index 000000000000..571dd0ef703c
--- /dev/null
+++ b/vcl/win/source/src/hsize.cur
Binary files differ
diff --git a/vcl/win/source/src/hsizebar.cur b/vcl/win/source/src/hsizebar.cur
new file mode 100644
index 000000000000..dda3483bb5d4
--- /dev/null
+++ b/vcl/win/source/src/hsizebar.cur
Binary files differ
diff --git a/vcl/win/source/src/hsplit.cur b/vcl/win/source/src/hsplit.cur
new file mode 100644
index 000000000000..f2f0be363d3a
--- /dev/null
+++ b/vcl/win/source/src/hsplit.cur
Binary files differ
diff --git a/vcl/win/source/src/linkdata.cur b/vcl/win/source/src/linkdata.cur
new file mode 100644
index 000000000000..e47c1dea2cec
--- /dev/null
+++ b/vcl/win/source/src/linkdata.cur
Binary files differ
diff --git a/vcl/win/source/src/linkf.cur b/vcl/win/source/src/linkf.cur
new file mode 100644
index 000000000000..6cc498a02610
--- /dev/null
+++ b/vcl/win/source/src/linkf.cur
Binary files differ
diff --git a/vcl/win/source/src/mirror.cur b/vcl/win/source/src/mirror.cur
new file mode 100644
index 000000000000..e05eb836eb5d
--- /dev/null
+++ b/vcl/win/source/src/mirror.cur
Binary files differ
diff --git a/vcl/win/source/src/move.cur b/vcl/win/source/src/move.cur
new file mode 100644
index 000000000000..a407a1298ad5
--- /dev/null
+++ b/vcl/win/source/src/move.cur
Binary files differ
diff --git a/vcl/win/source/src/movebw.cur b/vcl/win/source/src/movebw.cur
new file mode 100644
index 000000000000..d079eb9fe20d
--- /dev/null
+++ b/vcl/win/source/src/movebw.cur
Binary files differ
diff --git a/vcl/win/source/src/movedata.cur b/vcl/win/source/src/movedata.cur
new file mode 100644
index 000000000000..4d67cbe47149
--- /dev/null
+++ b/vcl/win/source/src/movedata.cur
Binary files differ
diff --git a/vcl/win/source/src/movedlnk.cur b/vcl/win/source/src/movedlnk.cur
new file mode 100644
index 000000000000..1bb7b0306406
--- /dev/null
+++ b/vcl/win/source/src/movedlnk.cur
Binary files differ
diff --git a/vcl/win/source/src/movef.cur b/vcl/win/source/src/movef.cur
new file mode 100644
index 000000000000..6abee2381dcf
--- /dev/null
+++ b/vcl/win/source/src/movef.cur
Binary files differ
diff --git a/vcl/win/source/src/movef2.cur b/vcl/win/source/src/movef2.cur
new file mode 100644
index 000000000000..d044981a3ffd
--- /dev/null
+++ b/vcl/win/source/src/movef2.cur
Binary files differ
diff --git a/vcl/win/source/src/moveflnk.cur b/vcl/win/source/src/moveflnk.cur
new file mode 100644
index 000000000000..630fa1bc3e4e
--- /dev/null
+++ b/vcl/win/source/src/moveflnk.cur
Binary files differ
diff --git a/vcl/win/source/src/movept.cur b/vcl/win/source/src/movept.cur
new file mode 100644
index 000000000000..81d3af5a05c4
--- /dev/null
+++ b/vcl/win/source/src/movept.cur
Binary files differ
diff --git a/vcl/win/source/src/neswsize.cur b/vcl/win/source/src/neswsize.cur
new file mode 100644
index 000000000000..c38501ee15a8
--- /dev/null
+++ b/vcl/win/source/src/neswsize.cur
Binary files differ
diff --git a/vcl/win/source/src/notallow.cur b/vcl/win/source/src/notallow.cur
new file mode 100644
index 000000000000..90c1dfbb3a97
--- /dev/null
+++ b/vcl/win/source/src/notallow.cur
Binary files differ
diff --git a/vcl/win/source/src/nullptr.cur b/vcl/win/source/src/nullptr.cur
new file mode 100644
index 000000000000..28dbb2a903f2
--- /dev/null
+++ b/vcl/win/source/src/nullptr.cur
Binary files differ
diff --git a/vcl/win/source/src/nwsesize.cur b/vcl/win/source/src/nwsesize.cur
new file mode 100644
index 000000000000..570cbbb571cc
--- /dev/null
+++ b/vcl/win/source/src/nwsesize.cur
Binary files differ
diff --git a/vcl/win/source/src/pen.cur b/vcl/win/source/src/pen.cur
new file mode 100644
index 000000000000..040c5dc703e9
--- /dev/null
+++ b/vcl/win/source/src/pen.cur
Binary files differ
diff --git a/vcl/win/source/src/refhand.cur b/vcl/win/source/src/refhand.cur
new file mode 100644
index 000000000000..a654974c6f8b
--- /dev/null
+++ b/vcl/win/source/src/refhand.cur
Binary files differ
diff --git a/vcl/win/source/src/rotate.cur b/vcl/win/source/src/rotate.cur
new file mode 100644
index 000000000000..43c2a54a10ac
--- /dev/null
+++ b/vcl/win/source/src/rotate.cur
Binary files differ
diff --git a/vcl/win/source/src/salsrc.rc b/vcl/win/source/src/salsrc.rc
new file mode 100644
index 000000000000..d7785d3ee734
--- /dev/null
+++ b/vcl/win/source/src/salsrc.rc
@@ -0,0 +1,148 @@
+/*************************************************************************
+*
+* $RCSfile: salsrc.rc,v $
+*
+* $Revision: 1.1.1.1 $
+*
+* last change: $Author: hr $ $Date: 2000-09-18 17:05:50 $
+*
+* The Contents of this file are made available subject to the terms of
+* either of the following licenses
+*
+* - GNU Lesser General Public License Version 2.1
+* - Sun Industry Standards Source License Version 1.1
+*
+* Sun Microsystems Inc., October, 2000
+*
+* GNU Lesser General Public License Version 2.1
+* =============================================
+* Copyright 2000 by Sun Microsystems, Inc.
+* 901 San Antonio Road, Palo Alto, CA 94303, USA
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License version 2.1, as published by the Free Software Foundation.
+*
+* This library 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+* MA 02111-1307 USA
+*
+*
+* Sun Industry Standards Source License Version 1.1
+* =================================================
+* The contents of this file are subject to the Sun Industry Standards
+* Source License Version 1.1 (the "License"); You may not use this file
+* except in compliance with the License. You may obtain a copy of the
+* License at http://www.openoffice.org/license.html.
+*
+* Software provided under this License is provided on an "AS IS" basis,
+* WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+* WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+* See the License for the specific provisions governing your rights and
+* obligations concerning the Software.
+*
+* The Initial Developer of the Original Code is: Sun Microsystems, Inc..
+*
+* Copyright: 2000 by Sun Microsystems, Inc.
+*
+* All Rights Reserved.
+*
+* Contributor(s): _______________________________________
+*
+*
+*
+**************************************************************************/
+
+// for WINVER
+#include <windows.h>
+
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+
+SAL_RESID_POINTER_NULL CURSOR NULLPTR.CUR
+#if ( WINVER < 0x0400 )
+SAL_RESID_POINTER_HELP CURSOR HELP.CUR
+#endif
+#ifndef WNT
+SAL_RESID_POINTER_HSIZE CURSOR HSIZE.CUR
+SAL_RESID_POINTER_VSIZE CURSOR VSIZE.CUR
+SAL_RESID_POINTER_NESWSIZE CURSOR NESWSIZE.CUR
+SAL_RESID_POINTER_NWSESIZE CURSOR NWSESIZE.CUR
+#endif
+SAL_RESID_POINTER_CROSS CURSOR CROSS.CUR
+SAL_RESID_POINTER_MOVE CURSOR MOVE.CUR
+SAL_RESID_POINTER_HSPLIT CURSOR HSPLIT.CUR
+SAL_RESID_POINTER_VSPLIT CURSOR VSPLIT.CUR
+SAL_RESID_POINTER_HSIZEBAR CURSOR HSIZEBAR.CUR
+SAL_RESID_POINTER_VSIZEBAR CURSOR VSIZEBAR.CUR
+SAL_RESID_POINTER_HAND CURSOR HAND.CUR
+SAL_RESID_POINTER_REFHAND CURSOR REFHAND.CUR
+SAL_RESID_POINTER_PEN CURSOR PEN.CUR
+SAL_RESID_POINTER_MAGNIFY CURSOR MAGNIFY.CUR
+SAL_RESID_POINTER_FILL CURSOR FILL.CUR
+SAL_RESID_POINTER_ROTATE CURSOR ROTATE.CUR
+SAL_RESID_POINTER_HSHEAR CURSOR HSHEAR.CUR
+SAL_RESID_POINTER_VSHEAR CURSOR VSHEAR.CUR
+SAL_RESID_POINTER_MIRROR CURSOR MIRROR.CUR
+SAL_RESID_POINTER_CROOK CURSOR CROOK.CUR
+SAL_RESID_POINTER_CROP CURSOR CROP.CUR
+SAL_RESID_POINTER_MOVEPOINT CURSOR MOVEPT.CUR
+SAL_RESID_POINTER_MOVEBEZIERWEIGHT CURSOR MOVEBW.CUR
+SAL_RESID_POINTER_MOVEDATA CURSOR MOVEDATA.CUR
+SAL_RESID_POINTER_COPYDATA CURSOR COPYDATA.CUR
+SAL_RESID_POINTER_LINKDATA CURSOR LINKDATA.CUR
+SAL_RESID_POINTER_MOVEDATALINK CURSOR MOVEDLNK.CUR
+SAL_RESID_POINTER_COPYDATALINK CURSOR COPYDLNK.CUR
+SAL_RESID_POINTER_MOVEFILE CURSOR MOVEF.CUR
+SAL_RESID_POINTER_COPYFILE CURSOR COPYF.CUR
+SAL_RESID_POINTER_LINKFILE CURSOR LINKF.CUR
+SAL_RESID_POINTER_MOVEFILELINK CURSOR MOVEFLNK.CUR
+SAL_RESID_POINTER_COPYFILELINK CURSOR COPYFLNK.CUR
+SAL_RESID_POINTER_MOVEFILES CURSOR MOVEF2.CUR
+SAL_RESID_POINTER_COPYFILES CURSOR COPYF2.CUR
+SAL_RESID_POINTER_NOTALLOWED CURSOR NOTALLOW.CUR
+SAL_RESID_POINTER_DRAW_LINE CURSOR DLINE.CUR
+SAL_RESID_POINTER_DRAW_RECT CURSOR DRECT.CUR
+SAL_RESID_POINTER_DRAW_POLYGON CURSOR DPOLYGON.CUR
+SAL_RESID_POINTER_DRAW_BEZIER CURSOR DBEZIER.CUR
+SAL_RESID_POINTER_DRAW_ARC CURSOR DARC.CUR
+SAL_RESID_POINTER_DRAW_PIE CURSOR DPIE.CUR
+SAL_RESID_POINTER_DRAW_CIRCLECUT CURSOR DCIRCCUT.CUR
+SAL_RESID_POINTER_DRAW_ELLIPSE CURSOR DELLIPSE.CUR
+SAL_RESID_POINTER_DRAW_FREEHAND CURSOR DFREE.CUR
+SAL_RESID_POINTER_DRAW_CONNECT CURSOR DCONNECT.CUR
+SAL_RESID_POINTER_DRAW_TEXT CURSOR DTEXT.CUR
+SAL_RESID_POINTER_DRAW_CAPTION CURSOR DCAPT.CUR
+SAL_RESID_POINTER_CHART CURSOR CHART.CUR
+SAL_RESID_POINTER_DETECTIVE CURSOR DETECTIV.CUR
+SAL_RESID_POINTER_PIVOT_COL CURSOR PIVOTCOL.CUR
+SAL_RESID_POINTER_PIVOT_ROW CURSOR PIVOTROW.CUR
+SAL_RESID_POINTER_PIVOT_FIELD CURSOR PIVOTFLD.CUR
+SAL_RESID_POINTER_CHAIN CURSOR CHAIN.CUR
+SAL_RESID_POINTER_CHAIN_NOTALLOWED CURSOR CHAINNOT.CUR
+SAL_RESID_POINTER_TIMEEVENT_MOVE CURSOR TIMEMOVE.CUR
+SAL_RESID_POINTER_TIMEEVENT_SIZE CURSOR TIMESIZE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_N CURSOR ASN.CUR
+SAL_RESID_POINTER_AUTOSCROLL_S CURSOR ASS.CUR
+SAL_RESID_POINTER_AUTOSCROLL_W CURSOR ASW.CUR
+SAL_RESID_POINTER_AUTOSCROLL_E CURSOR ASE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_NW CURSOR ASNW.CUR
+SAL_RESID_POINTER_AUTOSCROLL_NE CURSOR ASNE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_SW CURSOR ASSW.CUR
+SAL_RESID_POINTER_AUTOSCROLL_SE CURSOR ASSE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_NS CURSOR ASNS.CUR
+SAL_RESID_POINTER_AUTOSCROLL_WE CURSOR ASWE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_NSWE CURSOR ASNSWE.CUR
+SAL_RESID_POINTER_AIRBRUSH CURSOR AIRBRUSH.CUR
+
+SAL_RESID_BITMAP_50 BITMAP 50.BMP
+
+SAL_RESID_ICON_DEFAULT ICON SD.ICO
diff --git a/vcl/win/source/src/sd.ico b/vcl/win/source/src/sd.ico
new file mode 100644
index 000000000000..b2a0a07a67c3
--- /dev/null
+++ b/vcl/win/source/src/sd.ico
Binary files differ
diff --git a/vcl/win/source/src/timemove.cur b/vcl/win/source/src/timemove.cur
new file mode 100755
index 000000000000..319b6edc5774
--- /dev/null
+++ b/vcl/win/source/src/timemove.cur
Binary files differ
diff --git a/vcl/win/source/src/timesize.cur b/vcl/win/source/src/timesize.cur
new file mode 100755
index 000000000000..1ec23de05b71
--- /dev/null
+++ b/vcl/win/source/src/timesize.cur
Binary files differ
diff --git a/vcl/win/source/src/vshear.cur b/vcl/win/source/src/vshear.cur
new file mode 100644
index 000000000000..a4bbf7e8eb00
--- /dev/null
+++ b/vcl/win/source/src/vshear.cur
Binary files differ
diff --git a/vcl/win/source/src/vsize.cur b/vcl/win/source/src/vsize.cur
new file mode 100644
index 000000000000..76449be89d0a
--- /dev/null
+++ b/vcl/win/source/src/vsize.cur
Binary files differ
diff --git a/vcl/win/source/src/vsizebar.cur b/vcl/win/source/src/vsizebar.cur
new file mode 100644
index 000000000000..a87811cb474d
--- /dev/null
+++ b/vcl/win/source/src/vsizebar.cur
Binary files differ
diff --git a/vcl/win/source/src/vsplit.cur b/vcl/win/source/src/vsplit.cur
new file mode 100644
index 000000000000..a4260808fadc
--- /dev/null
+++ b/vcl/win/source/src/vsplit.cur
Binary files differ
diff --git a/vcl/win/source/window/MAKEFILE.MK b/vcl/win/source/window/MAKEFILE.MK
new file mode 100644
index 000000000000..c370e52b2bb9
--- /dev/null
+++ b/vcl/win/source/window/MAKEFILE.MK
@@ -0,0 +1,38 @@
+#*************************************************************************
+#*
+#* $Workfile: makefile. $
+#*
+#* Ersterstellung TH 01.04.97
+#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:50 $
+#* $Revision: 1.1.1.1 $
+#*
+#* $Logfile: T:/sv2/win/source/window/makefile.__v $
+#*
+#* Copyright (c) 1990 - 1998, STAR DIVISION
+#*
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salwin
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/salframe.obj \
+ $(SLO)$/salobj.obj
+
+.IF "$(UPDATER)"=="YES"
+OBJFILES= $(OBJ)$/salframe.obj \
+ $(OBJ)$/salobj.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx
new file mode 100644
index 000000000000..48d964af3ab6
--- /dev/null
+++ b/vcl/win/source/window/salframe.cxx
@@ -0,0 +1,3901 @@
+/*************************************************************************
+ *
+ * $RCSfile: salframe.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:50 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <limits.h>
+
+#ifdef DBG_UTIL
+#include <stdio.h>
+#endif
+
+#ifndef _SVWIN_HXX
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALFRAME_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#define private public
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_KEYCOES_HXX
+#include <keycodes.hxx>
+#endif
+
+// =======================================================================
+
+// Wegen Fehler in Windows-Headerfiles
+#ifndef IMN_OPENCANDIDATE
+#define IMN_OPENCANDIDATE 0x0005
+#endif
+#ifndef IMN_CLOSECANDIDATE
+#define IMN_CLOSECANDIDATE 0x0004
+#endif
+
+// =======================================================================
+
+static void ImplSaveFrameState( SalFrame* pFrame )
+{
+ // Position, Groesse und Status fuer GetWindowState() merken
+ if ( !pFrame->maFrameData.mbFullScreen )
+ {
+ BOOL bVisible = (GetWindowStyle( pFrame->maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( IsIconic( pFrame->maFrameData.mhWnd ) )
+ {
+ pFrame->maFrameData.maState.mnState |= SAL_FRAMESTATE_MINIMIZED;
+ if ( bVisible )
+ pFrame->maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ }
+ else if ( IsZoomed( pFrame->maFrameData.mhWnd ) )
+ {
+ pFrame->maFrameData.maState.mnState &= ~SAL_FRAMESTATE_MINIMIZED;
+ pFrame->maFrameData.maState.mnState |= SAL_FRAMESTATE_MAXIMIZED;
+ if ( bVisible )
+ pFrame->maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ pFrame->maFrameData.mbRestoreMaximize = TRUE;
+ }
+ else
+ {
+ RECT aRect;
+ GetWindowRect( pFrame->maFrameData.mhWnd, &aRect );
+ pFrame->maFrameData.maState.mnState &= ~(SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED);
+ pFrame->maFrameData.maState.mnX = aRect.left;
+ pFrame->maFrameData.maState.mnY = aRect.top;
+ pFrame->maFrameData.maState.mnWidth = aRect.right-aRect.left;
+ pFrame->maFrameData.maState.mnHeight = aRect.bottom-aRect.top;
+ if ( bVisible )
+ pFrame->maFrameData.mnShowState = SW_SHOWNORMAL;
+ pFrame->maFrameData.mbRestoreMaximize = FALSE;
+ }
+ }
+}
+
+// =======================================================================
+
+SalFrame* ImplSalCreateFrame( SalInstance* pInst,
+ HWND hWndParent, ULONG nSalFrameStyle )
+{
+ SalFrame* pFrame = new SalFrame;
+ HWND hWnd;
+ DWORD nSysStyle = 0;
+ DWORD nExSysStyle = 0;
+ BOOL bSaveBits = FALSE;
+
+ // determine creation data
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_CHILD )
+ nSysStyle |= WS_CHILD;
+ else if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
+ {
+ pFrame->maFrameData.mbCaption = TRUE;
+ nSysStyle |= WS_OVERLAPPED;
+#if ( WINVER >= 0x0400 )
+ nExSysStyle |= WS_EX_APPWINDOW;
+#endif
+ }
+ else
+ nSysStyle |= WS_POPUP;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE )
+ {
+ pFrame->maFrameData.mbSizeBorder = TRUE;
+ nSysStyle |= WS_THICKFRAME | WS_SYSMENU;
+ }
+ else if ( nSalFrameStyle & SAL_FRAME_STYLE_BORDER )
+ {
+ pFrame->maFrameData.mbBorder = TRUE;
+ nSysStyle |= WS_BORDER;
+ }
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE )
+ {
+ pFrame->maFrameData.mbCaption = TRUE;
+ nSysStyle |= WS_CAPTION | WS_SYSMENU;
+ }
+#if ( WINVER >= 0x0400 )
+ else
+ nExSysStyle |= WS_EX_TOOLWINDOW;
+#endif
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MINABLE )
+ nSysStyle |= WS_MINIMIZEBOX | WS_SYSMENU;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MAXABLE )
+ nSysStyle |= WS_MAXIMIZEBOX | WS_SYSMENU;
+
+ // init frame data
+ pFrame->maFrameData.mnStyle = nSalFrameStyle;
+
+ // determine show style
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
+ {
+ SalData* pSalData = GetSalData();
+ pFrame->maFrameData.mnShowState = pSalData->mnCmdShow;
+ if ( (pFrame->maFrameData.mnShowState != SW_SHOWMINIMIZED) &&
+ (pFrame->maFrameData.mnShowState != SW_MINIMIZE) &&
+ (pFrame->maFrameData.mnShowState != SW_SHOWMINNOACTIVE) )
+ {
+ if ( (pFrame->maFrameData.mnShowState == SW_SHOWMAXIMIZED) ||
+ (pFrame->maFrameData.mnShowState == SW_MAXIMIZE) )
+ pFrame->maFrameData.mbOverwriteState = FALSE;
+ pFrame->maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ }
+ else
+ pFrame->maFrameData.mbOverwriteState = FALSE;
+ }
+ else
+ pFrame->maFrameData.mnShowState = SW_SHOWNORMAL;
+
+ // create frame
+ if ( aSalShlData.mbWNT )
+ {
+ LPCWSTR pClassName;
+ if ( bSaveBits )
+ pClassName = SAL_FRAME_CLASSNAME_SBW;
+ else
+ pClassName = SAL_FRAME_CLASSNAMEW;
+ hWnd = CreateWindowExW( nExSysStyle, pClassName, L"", nSysStyle,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ hWndParent, 0, pInst->maInstData.mhInst, (void*)pFrame );
+ }
+ else
+ {
+ LPCSTR pClassName;
+ if ( bSaveBits )
+ pClassName = SAL_FRAME_CLASSNAME_SBA;
+ else
+ pClassName = SAL_FRAME_CLASSNAMEA;
+ hWnd = CreateWindowExA( nExSysStyle, pClassName, "", nSysStyle,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ hWndParent, 0, pInst->maInstData.mhInst, (void*)pFrame );
+ }
+ if ( !hWnd )
+ {
+ delete pFrame;
+ return NULL;
+ }
+
+ // disable close
+ if ( !(nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE) )
+ {
+ HMENU hSysMenu = GetSystemMenu( hWnd, FALSE );
+ if ( hSysMenu )
+ EnableMenuItem( hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED );
+ }
+
+ // reset input context
+ pFrame->maFrameData.mhDefIMEContext = ImmAssociateContext( hWnd, 0 );
+
+ // determine output size and state
+ RECT aRect;
+ GetClientRect( hWnd, &aRect );
+ pFrame->maFrameData.mnWidth = aRect.right;
+ pFrame->maFrameData.mnHeight = aRect.bottom;
+ ImplSaveFrameState( pFrame );
+ pFrame->maFrameData.mbDefPos = TRUE;
+
+ // CreateHDC in the main thread
+ pFrame->ReleaseGraphics( pFrame->GetGraphics() );
+
+ return pFrame;
+}
+
+// =======================================================================
+
+// Uebersetzungstabelle von System-Keycodes in StarView-Keycodes
+#define KEY_TAB_SIZE 146
+
+static USHORT aImplTranslateKeyTab[KEY_TAB_SIZE] =
+{
+ // StarView-Code System-Code Index
+ 0, // 0
+ 0, // VK_LBUTTON 1
+ 0, // VK_RBUTTON 2
+ 0, // VK_CANCEL 3
+ 0, // VK_MBUTTON 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ KEY_BACKSPACE, // VK_BACK 8
+ KEY_TAB, // VK_TAB 9
+ 0, // 10
+ 0, // 11
+ 0, // VK_CLEAR 12
+ KEY_RETURN, // VK_RETURN 13
+ 0, // 14
+ 0, // 15
+ 0, // VK_SHIFT 16
+ 0, // VK_CONTROL 17
+ 0, // VK_MENU 18
+ 0, // VK_PAUSE 19
+ 0, // VK_CAPITAL 20
+ 0, // 21
+ 0, // 22
+ 0, // 23
+ 0, // 24
+ 0, // 25
+ 0, // 26
+ KEY_ESCAPE, // VK_ESCAPE 27
+ 0, // 28
+ 0, // 29
+ 0, // 30
+ 0, // 31
+ KEY_SPACE, // VK_SPACE 32
+ KEY_PAGEUP, // VK_PRIOR 33
+ KEY_PAGEDOWN, // VK_NEXT 34
+ KEY_END, // VK_END 35
+ KEY_HOME, // VK_HOME 36
+ KEY_LEFT, // VK_LEFT 37
+ KEY_UP, // VK_UP 38
+ KEY_RIGHT, // VK_RIGHT 39
+ KEY_DOWN, // VK_DOWN 40
+ 0, // VK_SELECT 41
+ 0, // VK_PRINT 42
+ 0, // VK_EXECUTE 43
+ 0, // VK_SNAPSHOT 44
+ KEY_INSERT, // VK_INSERT 45
+ KEY_DELETE, // VK_DELETE 46
+ KEY_HELP, // VK_HELP 47
+ KEY_0, // 48
+ KEY_1, // 49
+ KEY_2, // 50
+ KEY_3, // 51
+ KEY_4, // 52
+ KEY_5, // 53
+ KEY_6, // 54
+ KEY_7, // 55
+ KEY_8, // 56
+ KEY_9, // 57
+ 0, // 58
+ 0, // 59
+ 0, // 60
+ 0, // 61
+ 0, // 62
+ 0, // 63
+ 0, // 64
+ KEY_A, // 65
+ KEY_B, // 66
+ KEY_C, // 67
+ KEY_D, // 68
+ KEY_E, // 69
+ KEY_F, // 70
+ KEY_G, // 71
+ KEY_H, // 72
+ KEY_I, // 73
+ KEY_J, // 74
+ KEY_K, // 75
+ KEY_L, // 76
+ KEY_M, // 77
+ KEY_N, // 78
+ KEY_O, // 79
+ KEY_P, // 80
+ KEY_Q, // 81
+ KEY_R, // 82
+ KEY_S, // 83
+ KEY_T, // 84
+ KEY_U, // 85
+ KEY_V, // 86
+ KEY_W, // 87
+ KEY_X, // 88
+ KEY_Y, // 89
+ KEY_Z, // 90
+ 0, // VK_LWIN 91
+ 0, // VK_RWIN 92
+ KEY_CONTEXTMENU, // VK_APPS 93
+ 0, // 94
+ 0, // 95
+ KEY_0, // VK_NUMPAD0 96
+ KEY_1, // VK_NUMPAD1 97
+ KEY_2, // VK_NUMPAD2 98
+ KEY_3, // VK_NUMPAD3 99
+ KEY_4, // VK_NUMPAD4 100
+ KEY_5, // VK_NUMPAD5 101
+ KEY_6, // VK_NUMPAD6 102
+ KEY_7, // VK_NUMPAD7 103
+ KEY_8, // VK_NUMPAD8 104
+ KEY_9, // VK_NUMPAD9 105
+ KEY_MULTIPLY, // VK_MULTIPLY 106
+ KEY_ADD, // VK_ADD 107
+ KEY_COMMA, // VK_SEPARATOR 108
+ KEY_SUBTRACT, // VK_SUBTRACT 109
+ KEY_POINT, // VK_DECIMAL 110
+ KEY_DIVIDE, // VK_DIVIDE 111
+ KEY_F1, // VK_F1 112
+ KEY_F2, // VK_F2 113
+ KEY_F3, // VK_F3 114
+ KEY_F4, // VK_F4 115
+ KEY_F5, // VK_F5 116
+ KEY_F6, // VK_F6 117
+ KEY_F7, // VK_F7 118
+ KEY_F8, // VK_F8 119
+ KEY_F9, // VK_F9 120
+ KEY_F10, // VK_F10 121
+ KEY_F11, // VK_F11 122
+ KEY_F12, // VK_F12 123
+ KEY_F13, // VK_F13 124
+ KEY_F14, // VK_F14 125
+ KEY_F15, // VK_F15 126
+ KEY_F16, // VK_F16 127
+ KEY_F17, // VK_F17 128
+ KEY_F18, // VK_F18 129
+ KEY_F19, // VK_F19 130
+ KEY_F20, // VK_F20 131
+ KEY_F21, // VK_F21 132
+ KEY_F22, // VK_F22 133
+ KEY_F23, // VK_F23 134
+ KEY_F24, // VK_F24 135
+ 0, // 136
+ 0, // 137
+ 0, // 138
+ 0, // 139
+ 0, // 140
+ 0, // 141
+ 0, // 142
+ 0, // 143
+ 0, // NUMLOCK 144
+ 0 // SCROLLLOCK 145
+};
+
+// =======================================================================
+
+long ImplSalCallbackDummy( void*, SalFrame*, USHORT, const void* )
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static UINT ImplSalGetWheelScrollLines()
+{
+ UINT nScrLines = 0;
+ HWND hWndMsWheel = WIN_FindWindow( MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE );
+ if ( hWndMsWheel )
+ {
+ UINT nGetScrollLinesMsgId = RegisterWindowMessage( MSH_SCROLL_LINES );
+ nScrLines = (UINT)ImplSendMessage( hWndMsWheel, nGetScrollLinesMsgId, 0, 0 );
+ }
+
+ if ( !nScrLines )
+ nScrLines = SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &nScrLines, 0 );
+
+ if ( !nScrLines )
+ nScrLines = 3;
+
+ return nScrLines;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalCalcFullScreenSize( const SalFrame* pFrame,
+ int& rX, int& rY, int& rDX, int& rDY )
+{
+ // set window to screen size
+ int nFrameX;
+ int nFrameY;
+ int nCaptionY;
+ int nScreenDX;
+ int nScreenDY;
+
+ if ( pFrame->maFrameData.mbSizeBorder )
+ {
+ nFrameX = GetSystemMetrics( SM_CXFRAME );
+ nFrameY = GetSystemMetrics( SM_CYFRAME );
+ }
+ else if ( pFrame->maFrameData.mbBorder )
+ {
+ nFrameX = GetSystemMetrics( SM_CXBORDER );
+ nFrameY = GetSystemMetrics( SM_CYBORDER );
+ }
+ else
+ {
+ nFrameX = 0;
+ nFrameY = 0;
+ }
+ if ( pFrame->maFrameData.mbCaption )
+ nCaptionY = GetSystemMetrics( SM_CYCAPTION );
+ else
+ nCaptionY = 0;
+
+ nScreenDX = GetSystemMetrics( SM_CXSCREEN );
+ nScreenDY = GetSystemMetrics( SM_CYSCREEN );
+
+ rX = -nFrameX;
+ rY = -(nFrameY+nCaptionY);
+ rDX = nScreenDX+(nFrameX*2);
+ rDY = nScreenDY+(nFrameY*2)+nCaptionY;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalFrameFullScreenPos( SalFrame* pFrame, BOOL bAlways = FALSE )
+{
+ if ( bAlways || !IsIconic( pFrame->maFrameData.mhWnd ) )
+ {
+ // set window to screen size
+ int nX;
+ int nY;
+ int nWidth;
+ int nHeight;
+ ImplSalCalcFullScreenSize( pFrame, nX, nY, nWidth, nHeight );
+ SetWindowPos( pFrame->maFrameData.mhWnd, 0,
+ nX, nY, nWidth, nHeight,
+ SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame::SalFrame()
+{
+ SalData* pSalData = GetSalData();
+
+ maFrameData.mhWnd = 0;
+ maFrameData.mhCursor = LoadCursor( 0, IDC_ARROW );
+ maFrameData.mhDefIMEContext = 0;
+ maFrameData.mpGraphics = NULL;
+ maFrameData.mpInst = NULL;
+ maFrameData.mpProc = ImplSalCallbackDummy;
+ maFrameData.mnInputLang = 0;
+ maFrameData.mnInputCodePage = 0;
+ maFrameData.mbGraphics = FALSE;
+ maFrameData.mbCaption = FALSE;
+ maFrameData.mbBorder = FALSE;
+ maFrameData.mbSizeBorder = FALSE;
+ maFrameData.mbFullScreen = FALSE;
+ maFrameData.mbPresentation = FALSE;
+ maFrameData.mbInShow = FALSE;
+ maFrameData.mbRestoreMaximize = FALSE;
+ maFrameData.mbInMoveMsg = FALSE;
+ maFrameData.mbInSizeMsg = FALSE;
+ maFrameData.mbFullScreenToolWin = FALSE;
+ maFrameData.mbDefPos = TRUE;
+ maFrameData.mbOverwriteState = TRUE;
+ maFrameData.mbIME = FALSE;
+ maFrameData.mbHandleIME = FALSE;
+ maFrameData.mbSpezIME = FALSE;
+ maFrameData.mbAtCursorIME = FALSE;
+ maFrameData.mbCompositionMode = FALSE;
+ maFrameData.mbCandidateMode = FALSE;
+ memset( &maFrameData.maState, 0, sizeof( SalFrameState ) );
+ maFrameData.maSysData.nSize = sizeof( SystemEnvData );
+
+ // Daten ermitteln, wenn erster Frame angelegt wird
+ if ( !pSalData->mpFirstFrame )
+ {
+ if ( !aSalShlData.mnWheelMsgId )
+ aSalShlData.mnWheelMsgId = RegisterWindowMessage( MSH_MOUSEWHEEL );
+ if ( !aSalShlData.mnWheelScrollLines )
+ aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines();
+ }
+
+ // insert frame in framelist
+ maFrameData.mpNextFrame = pSalData->mpFirstFrame;
+ pSalData->mpFirstFrame = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame::~SalFrame()
+{
+ SalData* pSalData = GetSalData();
+
+ // destroy saved DC
+ if ( maFrameData.mpGraphics )
+ {
+ if ( maFrameData.mpGraphics->maGraphicsData.mhDefPal )
+ SelectPalette( maFrameData.mpGraphics->maGraphicsData.mhDC, maFrameData.mpGraphics->maGraphicsData.mhDefPal, TRUE );
+ ImplSalDeInitGraphics( &(maFrameData.mpGraphics->maGraphicsData) );
+ ReleaseDC( maFrameData.mhWnd, maFrameData.mpGraphics->maGraphicsData.mhDC );
+ delete maFrameData.mpGraphics;
+ }
+
+ if ( maFrameData.mhWnd )
+ {
+ // reset mouse leave data
+ if ( pSalData->mhWantLeaveMsg == maFrameData.mhWnd )
+ {
+ pSalData->mhWantLeaveMsg = 0;
+ if ( pSalData->mpMouseLeaveTimer )
+ {
+ delete pSalData->mpMouseLeaveTimer;
+ pSalData->mpMouseLeaveTimer = NULL;
+ }
+ }
+
+ // destroy system frame
+ if ( !DestroyWindow( maFrameData.mhWnd ) )
+ SetWindowPtr( maFrameData.mhWnd, 0 );
+ }
+
+ // remove frame from framelist
+ if ( this == pSalData->mpFirstFrame )
+ pSalData->mpFirstFrame = maFrameData.mpNextFrame;
+ else
+ {
+ SalFrame* pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame->maFrameData.mpNextFrame != this )
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+
+ pTempFrame->maFrameData.mpNextFrame = maFrameData.mpNextFrame;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalFrame::GetGraphics()
+{
+ if ( maFrameData.mbGraphics )
+ return NULL;
+
+ if ( !maFrameData.mpGraphics )
+ {
+ HDC hDC = GetDC( maFrameData.mhWnd );
+ if ( hDC )
+ {
+ SalData* pSalData = GetSalData();
+ maFrameData.mpGraphics = new SalGraphics;
+ maFrameData.mpGraphics->maGraphicsData.mhDC = hDC;
+ maFrameData.mpGraphics->maGraphicsData.mhWnd = maFrameData.mhWnd;
+ maFrameData.mpGraphics->maGraphicsData.mbPrinter = FALSE;
+ maFrameData.mpGraphics->maGraphicsData.mbVirDev = FALSE;
+ maFrameData.mpGraphics->maGraphicsData.mbWindow = TRUE;
+ maFrameData.mpGraphics->maGraphicsData.mbScreen = TRUE;
+ if ( pSalData->mhDitherPal )
+ {
+ maFrameData.mpGraphics->maGraphicsData.mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( hDC );
+ }
+ ImplSalInitGraphics( &(maFrameData.mpGraphics->maGraphicsData) );
+ maFrameData.mbGraphics = TRUE;
+ }
+ }
+ else
+ maFrameData.mbGraphics = TRUE;
+
+ return maFrameData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ReleaseGraphics( SalGraphics* )
+{
+ maFrameData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalFrame::PostEvent( void* pData )
+{
+ return (BOOL)ImplPostMessage( maFrameData.mhWnd, SAL_MSG_USEREVENT, 0, (LPARAM)pData );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetTitle( const XubString& rTitle )
+{
+ DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "SalFrame::SetTitle(): WCHAR != sal_Unicode" );
+
+ if ( !SetWindowTextW( maFrameData.mhWnd, rTitle.GetBuffer() ) )
+ {
+ ByteString aAnsiTitle = ImplSalGetWinAnsiString( rTitle );
+ SetWindowTextA( maFrameData.mhWnd, aAnsiTitle.GetBuffer() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetIcon( USHORT nIcon )
+{
+// ImplSendMessage( maFrameData.mhWnd, WM_SETICON, FALSE, hSmIcon );
+// ImplSendMessage( maFrameData.mhWnd, WM_SETICON, TRUE, hIcon );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalShow( HWND hWnd, BOOL bVisible )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return;
+
+ if ( bVisible )
+ {
+ pFrame->maFrameData.mbDefPos = FALSE;
+ pFrame->maFrameData.mbOverwriteState = TRUE;
+ pFrame->maFrameData.mbInShow = TRUE;
+ ShowWindow( hWnd, pFrame->maFrameData.mnShowState );
+ // Damit Taskleiste unter W98 auch gleich ausgeblendet wird
+ if ( pFrame->maFrameData.mbPresentation )
+ {
+ HWND hWndParent = ::GetParent( hWnd );
+ if ( hWndParent )
+ SetForegroundWindow( hWndParent );
+ SetForegroundWindow( hWnd );
+ }
+ pFrame->maFrameData.mnShowState = SW_SHOW;
+ pFrame->maFrameData.mbInShow = FALSE;
+ UpdateWindow( hWnd );
+ }
+ else
+ {
+ if ( pFrame->maFrameData.mbFullScreen &&
+ pFrame->maFrameData.mbPresentation &&
+ !::GetParent( hWnd ) )
+ {
+ // Damit im Impress-Player in der Taskleiste nicht durch
+ // einen Windows-Fehler hin- und wieder mal ein leerer
+ // Button stehen bleibt, muessen wir hier die Taskleiste
+ // etwas austricksen. Denn wenn wir im FullScreenMode sind
+ // und das Fenster hiden kommt Windows anscheinend etwas aus
+ // dem tritt und somit minimieren wir das Fenster damit es
+ // nicht flackert
+ ANIMATIONINFO aInfo;
+ aInfo.cbSize = sizeof( aInfo );
+ SystemParametersInfo( SPI_GETANIMATION, 0, &aInfo, 0 );
+ if ( aInfo.iMinAnimate )
+ {
+ int nOldAni = aInfo.iMinAnimate;
+ aInfo.iMinAnimate = 0;
+ SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 );
+ ShowWindow( pFrame->maFrameData.mhWnd, SW_SHOWMINNOACTIVE );
+ aInfo.iMinAnimate = nOldAni;
+ SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 );
+ }
+ else
+ ShowWindow( hWnd, SW_SHOWMINNOACTIVE );
+ ShowWindow( hWnd, SW_HIDE );
+ }
+ else
+ ShowWindow( hWnd, SW_HIDE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Show( BOOL bVisible )
+{
+ // Send this Message to the window, because this only works
+ // in the thread of the window, which has create this window
+ ImplSendMessage( maFrameData.mhWnd, SAL_MSG_SHOW, bVisible, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Enable( BOOL bEnable )
+{
+ EnableWindow( maFrameData.mhWnd, bEnable );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetMinClientSize( long nWidth, long nHeight )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetClientSize( long nWidth, long nHeight )
+{
+ BOOL bVisible = (GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( !bVisible )
+ maFrameData.mnShowState = SW_SHOWNORMAL;
+ else
+ {
+ if ( IsIconic( maFrameData.mhWnd ) || IsZoomed( maFrameData.mhWnd ) )
+ ShowWindow( maFrameData.mhWnd, SW_RESTORE );
+ }
+
+ // Fenstergroesse berechnen
+ RECT aWinRect;
+ aWinRect.left = 0;
+ aWinRect.right = (int)nWidth-1;
+ aWinRect.top = 0;
+ aWinRect.bottom = (int)nHeight-1;
+ AdjustWindowRectEx( &aWinRect,
+ GetWindowStyle( maFrameData.mhWnd ),
+ FALSE,
+ GetWindowExStyle( maFrameData.mhWnd ) );
+ nWidth = aWinRect.right - aWinRect.left + 1;
+ nHeight = aWinRect.bottom - aWinRect.top + 1;
+
+ // Position so berechnen, das Fenster zentiert auf dem Desktop
+ // angezeigt wird
+ int nX;
+ int nY;
+ int nScreenX;
+ int nScreenY;
+ int nScreenWidth;
+ int nScreenHeight;
+
+#if ( WINVER >= 0x0400 )
+ W40IF
+ {
+ RECT aRect;
+ SystemParametersInfo( SPI_GETWORKAREA, 0, &aRect, 0 );
+ nScreenX = aRect.left;
+ nScreenY = aRect.top;
+ nScreenWidth = aRect.right-aRect.left;
+ nScreenHeight = aRect.bottom-aRect.top;
+ }
+ W40ELSE
+#endif
+#ifndef W40ONLY
+ {
+ nScreenX = 0;
+ nScreenY = 0;
+ nScreenWidth = GetSystemMetrics( SM_CXSCREEN );
+ nScreenHeight = GetSystemMetrics( SM_CYSCREEN );
+ }
+#endif
+
+ if ( maFrameData.mbDefPos )
+ {
+ nX = (nScreenWidth-nWidth)/2 + nScreenX;
+ nY = (nScreenHeight-nHeight)/2 + nScreenY;
+ if ( bVisible )
+ maFrameData.mbDefPos = FALSE;
+ }
+ else
+ {
+ RECT aWinRect;
+ GetWindowRect( maFrameData.mhWnd, &aWinRect );
+ nX = aWinRect.left;
+ nY = aWinRect.top;
+ if ( nX+nWidth > nScreenX+nScreenWidth )
+ nX = (nScreenX+nScreenWidth) - nWidth;
+ if ( nY+nHeight > nScreenY+nScreenHeight )
+ nY = (nScreenY+nScreenHeight) - nHeight;
+ if ( nX < nScreenX )
+ nX = nScreenX;
+ if ( nY < nScreenY )
+ nY = nScreenY;
+ }
+
+ SetWindowPos( maFrameData.mhWnd, 0, nX, nY, (int)nWidth, (int)nHeight, SWP_NOZORDER | SWP_NOACTIVATE );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::GetClientSize( long& rWidth, long& rHeight )
+{
+ rWidth = maFrameData.mnWidth;
+ rHeight = maFrameData.mnHeight;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetWindowState( const SalFrameState* pState )
+{
+ // Wir testen, ob das Fenster ueberhaupt auf den Bildschirm passt, damit
+ // nicht wenn die Bildschirm-Aufloesung geaendert wurde, das Fenster aus
+ // diesem herausragt
+ int nX;
+ int nY;
+ int nWidth;
+ int nHeight;
+ int nScreenX;
+ int nScreenY;
+ int nScreenWidth;
+ int nScreenHeight;
+
+#if ( WINVER >= 0x0400 )
+ W40IF
+ {
+ RECT aRect;
+ SystemParametersInfo( SPI_GETWORKAREA, 0, &aRect, 0 );
+ nScreenX = aRect.left;
+ nScreenY = aRect.top;
+ nScreenWidth = aRect.right-aRect.left;
+ nScreenHeight = aRect.bottom-aRect.top;
+ }
+ W40ELSE
+#endif
+#ifndef W40ONLY
+ {
+ nScreenX = 0;
+ nScreenY = 0;
+ nScreenWidth = GetSystemMetrics( SM_CXSCREEN );
+ nScreenHeight = GetSystemMetrics( SM_CYSCREEN );
+ }
+#endif
+
+ // Fenster-Position/Groesse in den Bildschirm einpassen
+ nX = (int)pState->mnX;
+ nY = (int)pState->mnY;
+ nWidth = (int)pState->mnWidth;
+ nHeight = (int)pState->mnHeight;
+ if ( nX < nScreenX )
+ nX = nScreenX;
+ if ( nY < nScreenY )
+ nY = nScreenY;
+ if ( nScreenWidth < nWidth )
+ nWidth = nScreenWidth;
+ if ( nScreenHeight < nHeight )
+ nHeight = nScreenHeight;
+
+ // Restore-Position setzen
+ WINDOWPLACEMENT aPlacement;
+ aPlacement.length = sizeof( aPlacement );
+ GetWindowPlacement( maFrameData.mhWnd, &aPlacement );
+
+ // Status setzen
+ BOOL bVisible = (GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( !bVisible )
+ {
+ aPlacement.showCmd = SW_HIDE;
+
+ if ( maFrameData.mbOverwriteState )
+ {
+ if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
+ maFrameData.mnShowState = SW_SHOWMINIMIZED;
+ else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ else
+ maFrameData.mnShowState = SW_SHOWNORMAL;
+ }
+ }
+ else
+ {
+ if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
+ {
+ if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ aPlacement.flags |= WPF_RESTORETOMAXIMIZED;
+ aPlacement.showCmd = SW_SHOWMINIMIZED;
+ }
+ else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ aPlacement.showCmd = SW_SHOWMAXIMIZED;
+ else
+ aPlacement.showCmd = SW_RESTORE;
+ }
+
+ // Wenn Fenster nicht minimiert/maximiert ist oder nicht optisch
+ // umgesetzt werden muss, dann SetWindowPos() benutzen, da
+ // SetWindowPlacement() die TaskBar mit einrechnet
+ if ( !IsIconic( maFrameData.mhWnd ) && !IsZoomed( maFrameData.mhWnd ) &&
+ (!bVisible || (aPlacement.showCmd == SW_RESTORE)) )
+ {
+ SetWindowPos( maFrameData.mhWnd, 0,
+ nX, nY, nWidth, nHeight,
+ SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+ else
+ {
+ aPlacement.rcNormalPosition.left = nX-nScreenX;
+ aPlacement.rcNormalPosition.top = nY-nScreenY;
+ aPlacement.rcNormalPosition.right = nX+nWidth-nScreenX;
+ aPlacement.rcNormalPosition.bottom = nY+nHeight-nScreenY;
+ SetWindowPlacement( maFrameData.mhWnd, &aPlacement );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalFrame::GetWindowState( SalFrameState* pState )
+{
+ if ( maFrameData.maState.mnWidth && maFrameData.maState.mnHeight )
+ {
+ *pState = maFrameData.maState;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ShowFullScreen( BOOL bFullScreen )
+{
+ if ( maFrameData.mbFullScreen == bFullScreen )
+ return;
+
+ maFrameData.mbFullScreen = bFullScreen;
+ if ( bFullScreen )
+ {
+#if ( WINVER >= 0x0400 )
+ // Damit Taskleiste von Windows ausgeblendet wird
+ DWORD nExStyle = GetWindowExStyle( maFrameData.mhWnd );
+ if ( nExStyle & WS_EX_TOOLWINDOW )
+ {
+ maFrameData.mbFullScreenToolWin = TRUE;
+ nExStyle &= ~WS_EX_TOOLWINDOW;
+ SetWindowExStyle( maFrameData.mhWnd, nExStyle );
+ }
+#endif
+
+ // save old position
+ GetWindowRect( maFrameData.mhWnd, &maFrameData.maFullScreenRect );
+
+ // save show state
+ maFrameData.mnFullScreenShowState = maFrameData.mnShowState;
+ if ( !(GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) )
+ maFrameData.mnShowState = SW_SHOW;
+
+ // set window to screen size
+ ImplSalFrameFullScreenPos( this, TRUE );
+ }
+ else
+ {
+ // wenn ShowState wieder hergestellt werden muss, hiden wir zuerst
+ // das Fenster, damit es nicht so sehr flackert
+ BOOL bVisible = (GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( bVisible && (maFrameData.mnShowState != maFrameData.mnFullScreenShowState) )
+ ShowWindow( maFrameData.mhWnd, SW_HIDE );
+
+#if ( WINVER >= 0x0400 )
+ if ( maFrameData.mbFullScreenToolWin )
+ SetWindowExStyle( maFrameData.mhWnd, GetWindowExStyle( maFrameData.mhWnd ) | WS_EX_TOOLWINDOW );
+ maFrameData.mbFullScreenToolWin = FALSE;
+#endif
+
+ SetWindowPos( maFrameData.mhWnd, 0,
+ maFrameData.maFullScreenRect.left,
+ maFrameData.maFullScreenRect.top,
+ maFrameData.maFullScreenRect.right-maFrameData.maFullScreenRect.left,
+ maFrameData.maFullScreenRect.bottom-maFrameData.maFullScreenRect.top,
+ SWP_NOZORDER | SWP_NOACTIVATE );
+
+ // restore show state
+ if ( maFrameData.mnShowState != maFrameData.mnFullScreenShowState )
+ {
+ maFrameData.mnShowState = maFrameData.mnFullScreenShowState;
+ if ( bVisible )
+ {
+ maFrameData.mbInShow = TRUE;
+ ShowWindow( maFrameData.mhWnd, maFrameData.mnShowState );
+ maFrameData.mbInShow = FALSE;
+ UpdateWindow( maFrameData.mhWnd );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::StartPresentation( BOOL bStart )
+{
+ if ( maFrameData.mbPresentation == bStart )
+ return;
+
+ maFrameData.mbPresentation = bStart;
+
+ SalData* pSalData = GetSalData();
+ if ( bStart )
+ {
+#if ( WINVER >= 0x0400 )
+ if ( !pSalData->mpSageEnableProc )
+ {
+ if ( pSalData->mnSageStatus != DISABLE_AGENT )
+ {
+ OFSTRUCT aOS;
+ OpenFile( "SAGE.DLL", &aOS, OF_EXIST );
+
+ if ( !aOS.nErrCode )
+ {
+ pSalData->mhSageInst = LoadLibrary( aOS.szPathName );
+ pSalData->mpSageEnableProc = (SysAgt_Enable_PROC)GetProcAddress( pSalData->mhSageInst, "System_Agent_Enable" );
+ }
+ else
+ pSalData->mnSageStatus = DISABLE_AGENT;
+ }
+ }
+
+ if ( pSalData->mpSageEnableProc )
+ {
+ pSalData->mnSageStatus = pSalData->mpSageEnableProc( GET_AGENT_STATUS );
+ if ( pSalData->mnSageStatus == ENABLE_AGENT )
+ pSalData->mpSageEnableProc( DISABLE_AGENT );
+ }
+#endif
+
+ // Bildschirmschoner ausschalten, wenn Praesentation laueft
+ SystemParametersInfo( SPI_GETSCREENSAVEACTIVE, 0,
+ &(pSalData->mbScrSvrEnabled), 0 );
+ if ( pSalData->mbScrSvrEnabled )
+ SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, FALSE, 0, 0 );
+ }
+ else
+ {
+ // Bildschirmschoner wieder einschalten
+ if ( pSalData->mbScrSvrEnabled )
+ SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, pSalData->mbScrSvrEnabled, 0, 0 );
+
+#if ( WINVER >= 0x0400 )
+ // Systemagenten wieder aktivieren
+ if ( pSalData->mnSageStatus == ENABLE_AGENT )
+ pSalData->mpSageEnableProc( pSalData->mnSageStatus );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetAlwaysOnTop( BOOL bOnTop )
+{
+ HWND hWnd;
+ if ( bOnTop )
+ hWnd = HWND_TOPMOST;
+ else
+ hWnd = HWND_NOTOPMOST;
+ SetWindowPos( maFrameData.mhWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalToTop( HWND hWnd, USHORT nFlags )
+{
+ if ( nFlags & SAL_FRAME_TOTOP_FOREGROUNDTASK )
+ SetForegroundWindow( hWnd );
+ if ( !IsIconic( hWnd ) )
+ {
+ SetFocus( hWnd );
+
+ // Windows behauptet oefters mal, das man den Focus hat, obwohl
+ // man diesen nicht hat. Wenn dies der Fall ist, dann versuchen
+ // wir diesen auch ganz richtig zu bekommen.
+ if ( ::GetFocus() == hWnd )
+ SetForegroundWindow( hWnd );
+ }
+ else
+ {
+ if ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN )
+ {
+ if ( GetWindowPtr( hWnd )->maFrameData.mbRestoreMaximize )
+ ShowWindow( hWnd, SW_MAXIMIZE );
+ else
+ ShowWindow( hWnd, SW_RESTORE );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ToTop( USHORT nFlags )
+{
+ // Send this Message to the window, because SetFocus() only work
+ // in the thread of the window, which has create this window
+ ImplSendMessage( maFrameData.mhWnd, SAL_MSG_TOTOP, nFlags, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetPointer( PointerStyle ePointerStyle )
+{
+ struct ImplPtrData
+ {
+ HCURSOR mhCursor;
+ LPCSTR mnSysId;
+ UINT mnOwnId;
+ };
+
+ static ImplPtrData aImplPtrTab[POINTER_COUNT] =
+ {
+ { 0, IDC_ARROW, 0 }, // POINTER_ARROW
+ { 0, 0, SAL_RESID_POINTER_NULL }, // POINTER_NULL
+ { 0, IDC_WAIT, 0 }, // POINTER_WAIT
+ { 0, IDC_IBEAM, 0 }, // POINTER_TEXT
+#if ( WINVER >= 0x0400 )
+ { 0, IDC_HELP, 0 }, // POINTER_HELP
+#else
+ { 0, 0, SAL_RESID_POINTER_HELP }, // POINTER_HELP
+#endif
+ { 0, 0, SAL_RESID_POINTER_CROSS }, // POINTER_CROSS
+ { 0, 0, SAL_RESID_POINTER_MOVE }, // POINTER_MOVE
+ { 0, IDC_SIZENS, 0 }, // POINTER_NSIZE
+ { 0, IDC_SIZENS, 0 }, // POINTER_SSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_WSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_ESIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_NWSIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_NESIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_SWSIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_SESIZE
+ { 0, IDC_SIZENS, 0 }, // POINTER_WINDOW_NSIZE
+ { 0, IDC_SIZENS, 0 }, // POINTER_WINDOW_SSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_WINDOW_WSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_WINDOW_ESIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_WINDOW_NWSIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_WINDOW_NESIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_WINDOW_SWSIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_WINDOW_SESIZE
+ { 0, 0, SAL_RESID_POINTER_HSPLIT }, // POINTER_HSPLIT
+ { 0, 0, SAL_RESID_POINTER_VSPLIT }, // POINTER_VSPLIT
+ { 0, 0, SAL_RESID_POINTER_HSIZEBAR }, // POINTER_HSIZEBAR
+ { 0, 0, SAL_RESID_POINTER_VSIZEBAR }, // POINTER_VSIZEBAR
+ { 0, 0, SAL_RESID_POINTER_HAND }, // POINTER_HAND
+ { 0, 0, SAL_RESID_POINTER_REFHAND }, // POINTER_REFHAND
+ { 0, 0, SAL_RESID_POINTER_PEN }, // POINTER_PEN
+ { 0, 0, SAL_RESID_POINTER_MAGNIFY }, // POINTER_MAGNIFY
+ { 0, 0, SAL_RESID_POINTER_FILL }, // POINTER_FILL
+ { 0, 0, SAL_RESID_POINTER_ROTATE }, // POINTER_ROTATE
+ { 0, 0, SAL_RESID_POINTER_HSHEAR }, // POINTER_HSHEAR
+ { 0, 0, SAL_RESID_POINTER_VSHEAR }, // POINTER_VSHEAR
+ { 0, 0, SAL_RESID_POINTER_MIRROR }, // POINTER_MIRROR
+ { 0, 0, SAL_RESID_POINTER_CROOK }, // POINTER_CROOK
+ { 0, 0, SAL_RESID_POINTER_CROP }, // POINTER_CROP
+ { 0, 0, SAL_RESID_POINTER_MOVEPOINT }, // POINTER_MOVEPOINT
+ { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT }, // POINTER_MOVEBEZIERWEIGHT
+ { 0, 0, SAL_RESID_POINTER_MOVEDATA }, // POINTER_MOVEDATA
+ { 0, 0, SAL_RESID_POINTER_COPYDATA }, // POINTER_COPYDATA
+ { 0, 0, SAL_RESID_POINTER_LINKDATA }, // POINTER_LINKDATA
+ { 0, 0, SAL_RESID_POINTER_MOVEDATALINK }, // POINTER_MOVEDATALINK
+ { 0, 0, SAL_RESID_POINTER_COPYDATALINK }, // POINTER_COPYDATALINK
+ { 0, 0, SAL_RESID_POINTER_MOVEFILE }, // POINTER_MOVEFILE
+ { 0, 0, SAL_RESID_POINTER_COPYFILE }, // POINTER_COPYFILE
+ { 0, 0, SAL_RESID_POINTER_LINKFILE }, // POINTER_LINKFILE
+ { 0, 0, SAL_RESID_POINTER_MOVEFILELINK }, // POINTER_MOVEFILELINK
+ { 0, 0, SAL_RESID_POINTER_COPYFILELINK }, // POINTER_COPYFILELINK
+ { 0, 0, SAL_RESID_POINTER_MOVEFILES }, // POINTER_MOVEFILES
+ { 0, 0, SAL_RESID_POINTER_COPYFILES }, // POINTER_COPYFILES
+ { 0, 0, SAL_RESID_POINTER_NOTALLOWED }, // POINTER_NOTALLOWED
+ { 0, 0, SAL_RESID_POINTER_DRAW_LINE }, // POINTER_DRAW_LINE
+ { 0, 0, SAL_RESID_POINTER_DRAW_RECT }, // POINTER_DRAW_RECT
+ { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON }, // POINTER_DRAW_POLYGON
+ { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER }, // POINTER_DRAW_BEZIER
+ { 0, 0, SAL_RESID_POINTER_DRAW_ARC }, // POINTER_DRAW_ARC
+ { 0, 0, SAL_RESID_POINTER_DRAW_PIE }, // POINTER_DRAW_PIE
+ { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT }, // POINTER_DRAW_CIRCLECUT
+ { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE }, // POINTER_DRAW_ELLIPSE
+ { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND }, // POINTER_DRAW_FREEHAND
+ { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT }, // POINTER_DRAW_CONNECT
+ { 0, 0, SAL_RESID_POINTER_DRAW_TEXT }, // POINTER_DRAW_TEXT
+ { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION }, // POINTER_DRAW_CAPTION
+ { 0, 0, SAL_RESID_POINTER_CHART }, // POINTER_CHART
+ { 0, 0, SAL_RESID_POINTER_DETECTIVE }, // POINTER_DETECTIVE
+ { 0, 0, SAL_RESID_POINTER_PIVOT_COL }, // POINTER_PIVOT_COL
+ { 0, 0, SAL_RESID_POINTER_PIVOT_ROW }, // POINTER_PIVOT_ROW
+ { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD }, // POINTER_PIVOT_FIELD
+ { 0, 0, SAL_RESID_POINTER_CHAIN }, // POINTER_CHAIN
+ { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED }, // POINTER_CHAIN_NOTALLOWED
+ { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE }, // POINTER_TIMEEVENT_MOVE
+ { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE }, // POINTER_TIMEEVENT_SIZE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N }, // POINTER_AUTOSCROLL_N
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S }, // POINTER_AUTOSCROLL_S
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W }, // POINTER_AUTOSCROLL_W
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E }, // POINTER_AUTOSCROLL_E
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW }, // POINTER_AUTOSCROLL_NW
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE }, // POINTER_AUTOSCROLL_NE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW }, // POINTER_AUTOSCROLL_SW
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE }, // POINTER_AUTOSCROLL_SE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS }, // POINTER_AUTOSCROLL_NS
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE }, // POINTER_AUTOSCROLL_WE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE }, // POINTER_AUTOSCROLL_NSWE
+ { 0, 0, SAL_RESID_POINTER_AIRBRUSH } // POINTER_AIRBRUSH
+ };
+
+#if POINTER_COUNT != 86
+#error New Pointer must be defined!
+#endif
+
+ // Mousepointer loaded ?
+ if ( !aImplPtrTab[ePointerStyle].mhCursor )
+ {
+ if ( aImplPtrTab[ePointerStyle].mnOwnId )
+ aImplPtrTab[ePointerStyle].mhCursor = ImplLoadSalCursor( aImplPtrTab[ePointerStyle].mnOwnId );
+ else
+ aImplPtrTab[ePointerStyle].mhCursor = LoadCursor( 0, aImplPtrTab[ePointerStyle].mnSysId );
+ }
+
+ // Unterscheidet sich der Mauspointer, dann den neuen setzen
+ if ( maFrameData.mhCursor != aImplPtrTab[ePointerStyle].mhCursor )
+ {
+ maFrameData.mhCursor = aImplPtrTab[ePointerStyle].mhCursor;
+ SetCursor( maFrameData.mhCursor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::CaptureMouse( BOOL bCapture )
+{
+ // Send this Message to the window, because CaptureMouse() only work
+ // in the thread of the window, which has create this window
+ int nMsg;
+ if ( bCapture )
+ nMsg = SAL_MSG_CAPTUREMOUSE;
+ else
+ nMsg = SAL_MSG_RELEASEMOUSE;
+ ImplSendMessage( maFrameData.mhWnd, nMsg, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetPointerPos( long nX, long nY )
+{
+ POINT aPt;
+ aPt.x = (int)nX;
+ aPt.y = (int)nY;
+ ClientToScreen( maFrameData.mhWnd, &aPt );
+ SetCursorPos( aPt.x, aPt.y );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Flush()
+{
+ GdiFlush();
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Sync()
+{
+ GdiFlush();
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetInputContext( SalInputContext* pContext )
+{
+ BOOL bIME = pContext->mnOptions != 0;
+ if ( bIME == maFrameData.mbIME )
+ return;
+
+ maFrameData.mbIME = bIME;
+ if ( !bIME )
+ {
+ ImmAssociateContext( maFrameData.mhWnd, 0 );
+ maFrameData.mbHandleIME = FALSE;
+ }
+ else
+ {
+ if ( maFrameData.mhDefIMEContext )
+ {
+ ImmAssociateContext( maFrameData.mhWnd, maFrameData.mhDefIMEContext );
+ UINT nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY );
+ maFrameData.mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
+ maFrameData.mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
+ maFrameData.mbHandleIME = !maFrameData.mbSpezIME;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::UpdateExtTextInputArea()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::EndExtTextInput( USHORT nFlags )
+{
+ HWND hWnd = maFrameData.mhWnd;
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ DWORD nIndex;
+ if ( nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE )
+ nIndex = CPS_COMPLETE;
+ else
+ nIndex = CPS_CANCEL;
+
+ ImmNotifyIME( hIMC, NI_COMPOSITIONSTR, nIndex, 0 );
+ ImmReleaseContext( hWnd, hIMC );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetKeyNameText( LONG lParam, sal_Unicode* pBuf,
+ UINT& rCount, UINT nMaxSize,
+ const sal_Char* pReplace )
+{
+ DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "SalFrame::ImplGetKeyNameTextW(): WCHAR != sal_Unicode" );
+
+ WCHAR aKeyBuf[350];
+ int nKeyLen = 0;
+ if ( lParam )
+ {
+ nKeyLen = GetKeyNameTextW( lParam, aKeyBuf, sizeof( aKeyBuf ) / sizeof( sal_Unicode ) );
+ if ( nKeyLen > 0 )
+ {
+ // Convert name, so that the keyname start with an upper
+ // char and the rest of the word are in lower chars
+ CharLowerBuffW( aKeyBuf, nKeyLen );
+ CharUpperBuffW( aKeyBuf, 1 );
+ WCHAR cTempChar;
+ WCHAR* pKeyBuf = aKeyBuf;
+ while ( (cTempChar = *pKeyBuf) != 0 )
+ {
+ if ( (cTempChar == '+') || (cTempChar == '-') ||
+ (cTempChar == ' ') || (cTempChar == '.') )
+ CharUpperBuffW( pKeyBuf+1, 1 );
+ pKeyBuf++;
+ }
+ }
+ else
+ {
+ sal_Char aAnsiKeyBuf[250];
+ int nAnsiKeyLen = GetKeyNameTextA( lParam, aAnsiKeyBuf, sizeof( aAnsiKeyBuf ) / sizeof( sal_Char ) );
+ if ( nAnsiKeyLen )
+ {
+ // Convert name, so that the keyname start with an upper
+ // char and the rest of the word are in lower chars
+ CharLowerBuffA( aAnsiKeyBuf, nAnsiKeyLen );
+ CharUpperBuffA( aAnsiKeyBuf, 1 );
+ sal_Char cTempChar;
+ sal_Char* pAnsiKeyBuf = aAnsiKeyBuf;
+ while ( (cTempChar = *pAnsiKeyBuf) != 0 )
+ {
+ if ( (cTempChar == '+') || (cTempChar == '-') ||
+ (cTempChar == ' ') || (cTempChar == '.') )
+ CharUpperBuffA( pAnsiKeyBuf+1, 1 );
+ pAnsiKeyBuf++;
+ }
+
+ // Convert to Unicode and copy the data in the Unicode Buffer
+ nKeyLen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, aAnsiKeyBuf, nAnsiKeyLen, aKeyBuf, sizeof( aKeyBuf ) / sizeof( sal_Unicode ) );
+ }
+ }
+ }
+
+ if ( (nKeyLen > 0) || pReplace )
+ {
+ if ( rCount )
+ {
+ pBuf[rCount] = '+';
+ rCount++;
+ }
+
+ if ( nKeyLen )
+ {
+ memcpy( pBuf+rCount, aKeyBuf, nKeyLen*sizeof( sal_Unicode ) );
+ rCount += nKeyLen;
+ }
+ else
+ {
+ while ( *pReplace )
+ {
+ pBuf[rCount] = *pReplace;
+ rCount++;
+ pReplace++;
+ }
+ }
+ }
+ else
+ rCount = 0;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalFrame::GetKeyName( USHORT nKeyCode )
+{
+ XubString aKeyCode;
+ sal_Unicode aKeyBuf[350];
+ UINT nKeyBufLen = 0;
+ UINT nSysCode;
+
+ if ( nKeyCode & KEY_MOD2 )
+ {
+ nSysCode = MapVirtualKey( VK_MENU, 0 );
+ nSysCode = (nSysCode << 16) | (((ULONG)1) << 25);
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ "Alt" );
+ }
+
+ if ( nKeyCode & KEY_MOD1 )
+ {
+ nSysCode = MapVirtualKey( VK_CONTROL, 0 );
+ nSysCode = (nSysCode << 16) | (((ULONG)1) << 25);
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ "Ctrl" );
+ }
+
+ if ( nKeyCode & KEY_SHIFT )
+ {
+ nSysCode = MapVirtualKey( VK_SHIFT, 0 );
+ nSysCode = (nSysCode << 16) | (((ULONG)1) << 25);
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ "Shift" );
+ }
+
+ USHORT nCode = nKeyCode & 0x0FFF;
+ ULONG nSysCode2 = 0;
+ sal_Char* pReplace = NULL;
+ sal_Unicode cSVCode = 0;
+ sal_Char aFBuf[4];
+ nSysCode = 0;
+
+ if ( (nCode >= KEY_0) && (nCode <= KEY_9) )
+ cSVCode = '0' + (nCode - KEY_0);
+ else if ( (nCode >= KEY_A) && (nCode <= KEY_Z) )
+ cSVCode = 'A' + (nCode - KEY_A);
+ else if ( (nCode >= KEY_F1) && (nCode <= KEY_F26) )
+ {
+ nSysCode = VK_F1 + (nCode - KEY_F1);
+ aFBuf[0] = 'F';
+ if ( (nCode >= KEY_F1) && (nCode <= KEY_F9) )
+ {
+ aFBuf[1] = '1' + (nCode - KEY_F1);
+ aFBuf[2] = 0;
+ }
+ else if ( (nCode >= KEY_F10) && (nCode <= KEY_F19) )
+ {
+ aFBuf[1] = '1';
+ aFBuf[2] = '0' + (nCode - KEY_F10);
+ aFBuf[3] = 0;
+ }
+ else
+ {
+ aFBuf[1] = '2';
+ aFBuf[2] = '0' + (nCode - KEY_F20);
+ aFBuf[3] = 0;
+ }
+ pReplace = aFBuf;
+ }
+ else
+ {
+ switch ( nCode )
+ {
+ case KEY_DOWN:
+ nSysCode = VK_DOWN;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Down";
+ break;
+ case KEY_UP:
+ nSysCode = VK_UP;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Up";
+ break;
+ case KEY_LEFT:
+ nSysCode = VK_LEFT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Left";
+ break;
+ case KEY_RIGHT:
+ nSysCode = VK_RIGHT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Right";
+ break;
+ case KEY_HOME:
+ nSysCode = VK_HOME;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Home";
+ break;
+ case KEY_END:
+ nSysCode = VK_END;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "End";
+ break;
+ case KEY_PAGEUP:
+ nSysCode = VK_PRIOR;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Page Up";
+ break;
+ case KEY_PAGEDOWN:
+ nSysCode = VK_NEXT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Page Down";
+ break;
+ case KEY_RETURN:
+ nSysCode = VK_RETURN;
+ pReplace = "Enter";
+ break;
+ case KEY_ESCAPE:
+ nSysCode = VK_ESCAPE;
+ pReplace = "Escape";
+ break;
+ case KEY_TAB:
+ nSysCode = VK_TAB;
+ pReplace = "Tab";
+ break;
+ case KEY_BACKSPACE:
+ nSysCode = VK_BACK;
+ pReplace = "Backspace";
+ break;
+ case KEY_SPACE:
+ nSysCode = VK_SPACE;
+ pReplace = "Space";
+ break;
+ case KEY_INSERT:
+ nSysCode = VK_INSERT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Insert";
+ break;
+ case KEY_DELETE:
+ nSysCode = VK_DELETE;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Delete";
+ break;
+
+ case KEY_ADD:
+ cSVCode = '+';
+ break;
+ case KEY_SUBTRACT:
+ cSVCode = '-';
+ break;
+ case KEY_MULTIPLY:
+ cSVCode = '*';
+ break;
+ case KEY_DIVIDE:
+ cSVCode = '/';
+ break;
+ case KEY_POINT:
+ cSVCode = '.';
+ break;
+ case KEY_COMMA:
+ cSVCode = ',';
+ break;
+ case KEY_LESS:
+ cSVCode = '<';
+ break;
+ case KEY_GREATER:
+ cSVCode = '>';
+ break;
+ case KEY_EQUAL:
+ cSVCode = '=';
+ break;
+ }
+ }
+
+ if ( nSysCode )
+ {
+ nSysCode = MapVirtualKey( (UINT)nSysCode, 0 );
+ if ( nSysCode )
+ nSysCode = (nSysCode << 16) | nSysCode2;
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ pReplace );
+ }
+ else
+ {
+ if ( cSVCode )
+ {
+ if ( !nKeyBufLen )
+ {
+ aKeyBuf[0] = cSVCode;
+ nKeyBufLen = 1;
+ }
+ else
+ {
+ aKeyBuf[nKeyBufLen] = '+';
+ nKeyBufLen++;
+ aKeyBuf[nKeyBufLen] = cSVCode;
+ nKeyBufLen++;
+ }
+ }
+ }
+
+ if ( nKeyBufLen )
+ aKeyCode.Assign( (const sal_Unicode*)aKeyBuf, nKeyBufLen );
+
+ return aKeyCode;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode )
+{
+ return GetKeyName( nKeyCode );
+}
+
+// -----------------------------------------------------------------------
+
+inline Color ImplWinColorToSal( COLORREF nColor )
+{
+ return Color( GetRValue( nColor ), GetGValue( nColor ), GetBValue( nColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalUpdateStyleFontA( const LOGFONTA& rLogFont, Font& rFont,
+ BOOL bOverwriteSystemCharSet )
+{
+ ImplSalLogFontToFontA( rLogFont, rFont );
+ if ( bOverwriteSystemCharSet && (rFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL) )
+ rFont.SetCharSet( gsl_getSystemTextEncoding() );
+ // Da bei einigen Windows-Einstellungen 6 Punkt eingetragen ist,
+ // obwohl im Dialog 8 Punkt angezeigt werden (da MS Sans Serif
+ // nicht skalierbar ist) vergroessern wir hier das als Hack, da
+ // ansonsten in russisch Symbolunterschriften nicht lesbar sind
+ if ( (rFont.GetName().EqualsIgnoreCaseAscii( "MS Sans Serif" ) ) &&
+ (rFont.GetHeight() < 8) )
+ rFont.SetHeight( 8 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalUpdateStyleFontW( const LOGFONTW& rLogFont, Font& rFont,
+ BOOL bOverwriteSystemCharSet )
+{
+ ImplSalLogFontToFontW( rLogFont, rFont );
+ if ( bOverwriteSystemCharSet && (rFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL) )
+ rFont.SetCharSet( gsl_getSystemTextEncoding() );
+ // Da bei einigen Windows-Einstellungen 6 Punkt eingetragen ist,
+ // obwohl im Dialog 8 Punkt angezeigt werden (da MS Sans Serif
+ // nicht skalierbar ist) vergroessern wir hier das als Hack, da
+ // ansonsten in russisch Symbolunterschriften nicht lesbar sind
+ if ( (rFont.GetName().EqualsIgnoreCaseAscii( "MS Sans Serif" ) ) &&
+ (rFont.GetHeight() < 8) )
+ rFont.SetHeight( 8 );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplA2I( const BYTE* pStr )
+{
+ long n = 0;
+ int nSign = 1;
+
+ if ( *pStr == '-' )
+ {
+ nSign = -1;
+ pStr++;
+ }
+
+ while( (*pStr >= 48) && (*pStr <= 57) )
+ {
+ n *= 10;
+ n += ((*pStr) - 48);
+ pStr++;
+ }
+
+ n *= nSign;
+
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::UpdateSettings( AllSettings& rSettings )
+{
+ MouseSettings aMouseSettings = rSettings.GetMouseSettings();
+ aMouseSettings.SetDoubleClickTime( GetDoubleClickTime() );
+ aMouseSettings.SetDoubleClickWidth( GetSystemMetrics( SM_CXDOUBLECLK ) );
+ aMouseSettings.SetDoubleClickHeight( GetSystemMetrics( SM_CYDOUBLECLK ) );
+ long nDragWidth = GetSystemMetrics( SM_CXDRAG );
+ long nDragHeight = GetSystemMetrics( SM_CYDRAG );
+ if ( nDragWidth )
+ aMouseSettings.SetStartDragWidth( nDragWidth );
+ if ( nDragHeight )
+ aMouseSettings.SetStartDragHeight( nDragHeight );
+ HKEY hRegKey;
+ if ( RegOpenKey( HKEY_CURRENT_USER,
+ "Control Panel\\Desktop",
+ &hRegKey ) == ERROR_SUCCESS )
+ {
+ BYTE aValueBuf[10];
+ DWORD nValueSize = sizeof( aValueBuf );
+ DWORD nType;
+ if ( RegQueryValueEx( hRegKey, "MenuShowDelay", 0,
+ &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS )
+ {
+ if ( nType == REG_SZ )
+ aMouseSettings.SetMenuDelay( (ULONG)ImplA2I( aValueBuf ) );
+ }
+
+ RegCloseKey( hRegKey );
+ }
+
+ StyleSettings aStyleSettings = rSettings.GetStyleSettings();
+ BOOL bCompBorder = (aStyleSettings.GetOptions() & (STYLE_OPTION_MACSTYLE | STYLE_OPTION_UNIXSTYLE)) == 0;
+ aStyleSettings.SetScrollBarSize( GetSystemMetrics( SM_CXVSCROLL ) );
+ aStyleSettings.SetSpinSize( GetSystemMetrics( SM_CXVSCROLL ) );
+ aStyleSettings.SetCursorBlinkTime( GetCaretBlinkTime() );
+ if ( bCompBorder )
+ {
+ aStyleSettings.SetFloatTitleHeight( GetSystemMetrics( SM_CYSMCAPTION ) );
+ aStyleSettings.SetTitleHeight( GetSystemMetrics( SM_CYCAPTION ) );
+ aStyleSettings.SetActiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVEBORDER ) ) );
+ aStyleSettings.SetDeactiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVEBORDER ) ) );
+ if ( aSalShlData.mnVersion >= 410 )
+ {
+ aStyleSettings.SetActiveColor2( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTACTIVECAPTION ) ) );
+ aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTINACTIVECAPTION ) ) );
+ }
+ aStyleSettings.SetFaceColor( ImplWinColorToSal( GetSysColor( COLOR_3DFACE ) ) );
+ aStyleSettings.SetLightColor( ImplWinColorToSal( GetSysColor( COLOR_3DHILIGHT ) ) );
+ aStyleSettings.SetLightBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DLIGHT ) ) );
+ aStyleSettings.SetShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) );
+ aStyleSettings.SetDarkShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DDKSHADOW ) ) );
+ }
+ aStyleSettings.SetHelpColor( ImplWinColorToSal( GetSysColor( COLOR_INFOBK ) ) );
+ aStyleSettings.SetHelpTextColor( ImplWinColorToSal( GetSysColor( COLOR_INFOTEXT ) ) );
+ aStyleSettings.SetDialogColor( aStyleSettings.GetFaceColor() );
+ aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() );
+ aStyleSettings.SetButtonTextColor( ImplWinColorToSal( GetSysColor( COLOR_BTNTEXT ) ) );
+ aStyleSettings.SetRadioCheckTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) );
+ aStyleSettings.SetGroupTextColor( aStyleSettings.GetRadioCheckTextColor() );
+ aStyleSettings.SetLabelTextColor( aStyleSettings.GetRadioCheckTextColor() );
+ aStyleSettings.SetInfoTextColor( aStyleSettings.GetRadioCheckTextColor() );
+ aStyleSettings.SetWindowColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOW ) ) );
+ aStyleSettings.SetWindowTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) );
+ aStyleSettings.SetFieldColor( aStyleSettings.GetWindowColor() );
+ aStyleSettings.SetFieldTextColor( aStyleSettings.GetWindowTextColor() );
+ aStyleSettings.SetHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHT ) ) );
+ aStyleSettings.SetHighlightTextColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHTTEXT ) ) );
+ aStyleSettings.SetMenuHighlightColor( aStyleSettings.GetHighlightColor() );
+ aStyleSettings.SetMenuHighlightTextColor( aStyleSettings.GetHighlightTextColor() );
+ if ( bCompBorder )
+ {
+ aStyleSettings.SetMenuColor( ImplWinColorToSal( GetSysColor( COLOR_MENU ) ) );
+ aStyleSettings.SetMenuTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) );
+ aStyleSettings.SetActiveColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVECAPTION ) ) );
+ aStyleSettings.SetActiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_CAPTIONTEXT ) ) );
+ aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTION ) ) );
+ aStyleSettings.SetDeactiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ) );
+ }
+ // Bei hellgrau geben wir die Farbe vor, damit es besser aussieht
+ if ( aStyleSettings.GetFaceColor() == COL_LIGHTGRAY )
+ aStyleSettings.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) );
+ else
+ {
+ // Checked-Color berechnen
+ Color aColor1 = aStyleSettings.GetFaceColor();
+ Color aColor2 = aStyleSettings.GetLightColor();
+ BYTE nRed = (BYTE)(((USHORT)aColor1.GetRed() + (USHORT)aColor2.GetRed())/2);
+ BYTE nGreen = (BYTE)(((USHORT)aColor1.GetGreen() + (USHORT)aColor2.GetGreen())/2);
+ BYTE nBlue = (BYTE)(((USHORT)aColor1.GetBlue() + (USHORT)aColor2.GetBlue())/2);
+ aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) );
+ }
+
+ // Query Fonts
+ int bOverwriteSystemCharSet = getenv("LC_CHARSET") != 0;
+ Font aMenuFont = aStyleSettings.GetMenuFont();
+ Font aTitleFont = aStyleSettings.GetTitleFont();
+ Font aFloatTitleFont = aStyleSettings.GetFloatTitleFont();
+ Font aHelpFont = aStyleSettings.GetHelpFont();
+ Font aAppFont = aStyleSettings.GetAppFont();
+ Font aIconFont = aStyleSettings.GetIconFont();
+ if ( aSalShlData.mbWNT )
+ {
+ NONCLIENTMETRICSW aNonClientMetrics;
+ aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
+ if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
+ {
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfMenuFont, aMenuFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfCaptionFont, aTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfSmCaptionFont, aFloatTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfStatusFont, aHelpFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfMessageFont, aAppFont, bOverwriteSystemCharSet );
+
+ LOGFONTW aLogFont;
+ if ( SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &aLogFont, 0 ) )
+ ImplSalUpdateStyleFontW( aLogFont, aIconFont, bOverwriteSystemCharSet );
+ }
+ }
+ else
+ {
+ NONCLIENTMETRICSA aNonClientMetrics;
+ aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
+ if ( SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
+ {
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfMenuFont, aMenuFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfCaptionFont, aTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfSmCaptionFont, aFloatTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfStatusFont, aHelpFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfMessageFont, aAppFont, bOverwriteSystemCharSet );
+
+ LOGFONTA aLogFont;
+ if ( SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, &aLogFont, 0 ) )
+ ImplSalUpdateStyleFontA( aLogFont, aIconFont, bOverwriteSystemCharSet );
+ }
+ }
+ aStyleSettings.SetMenuFont( aMenuFont );
+ aStyleSettings.SetTitleFont( aTitleFont );
+ aStyleSettings.SetFloatTitleFont( aFloatTitleFont );
+ aStyleSettings.SetHelpFont( aHelpFont );
+ aStyleSettings.SetIconFont( aIconFont );
+ // We prefer Arial in the russian version, because MS Sans Serif
+ // is to wide for the dialogs
+ if ( rSettings.GetInternational().GetLanguage() == LANGUAGE_RUSSIAN )
+ {
+ XubString aFontName = aAppFont.GetName();
+ XubString aFirstName = aFontName.GetToken( 0, ';' );
+ if ( aFirstName.EqualsIgnoreCaseAscii( "MS Sans Serif" ) )
+ {
+ aFontName.InsertAscii( "Arial;", 0 );
+ aAppFont.SetName( aFontName );
+ }
+ }
+ aStyleSettings.SetAppFont( aAppFont );
+ aStyleSettings.SetGroupFont( aAppFont );
+ aStyleSettings.SetLabelFont( aAppFont );
+ aStyleSettings.SetRadioCheckFont( aAppFont );
+ aStyleSettings.SetPushButtonFont( aAppFont );
+ aStyleSettings.SetFieldFont( aAppFont );
+ if ( aAppFont.GetWeight() > WEIGHT_NORMAL )
+ aAppFont.SetWeight( WEIGHT_NORMAL );
+ aStyleSettings.SetInfoFont( aAppFont );
+ aStyleSettings.SetToolFont( aAppFont );
+
+ WIN_BOOL bDragFull;
+ if ( SystemParametersInfo( SPI_GETDRAGFULLWINDOWS, 0, &bDragFull, 0 ) )
+ {
+ ULONG nDragFullOptions = aStyleSettings.GetDragFullOptions();
+ if ( bDragFull )
+ nDragFullOptions |= DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT;
+ else
+ nDragFullOptions &= ~(DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT);
+ aStyleSettings.SetDragFullOptions( nDragFullOptions );
+ }
+
+ aStyleSettings.SetIconHorzSpace( GetSystemMetrics( SM_CXICONSPACING ) );
+ aStyleSettings.SetIconVertSpace( GetSystemMetrics( SM_CYICONSPACING ) );
+ if ( RegOpenKey( HKEY_CURRENT_USER,
+ "Control Panel\\International\\Calendars\\TwoDigitYearMax",
+ &hRegKey ) == ERROR_SUCCESS )
+ {
+ BYTE aValueBuf[10];
+ DWORD nValue;
+ DWORD nValueSize = sizeof( aValueBuf );
+ DWORD nType;
+ if ( RegQueryValueEx( hRegKey, "1", 0,
+ &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS )
+ {
+ if ( nType == REG_SZ )
+ {
+ nValue = (ULONG)ImplA2I( aValueBuf );
+ if ( (nValue > 1000) && (nValue < 10000) )
+ {
+ MiscSettings aMiscSettings = rSettings.GetMiscSettings();
+ aMiscSettings.SetTwoDigitYearStart( (USHORT)(nValue-99) );
+ rSettings.SetMiscSettings( aMiscSettings );
+ }
+ }
+ }
+
+ RegCloseKey( hRegKey );
+ }
+
+ rSettings.SetMouseSettings( aMouseSettings );
+ rSettings.SetStyleSettings( aStyleSettings );
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* SalFrame::GetSystemData() const
+{
+ return &maFrameData.maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Beep( SoundType eSoundType )
+{
+ static UINT aImplSoundTab[5] =
+ {
+ 0, // SOUND_DEFAULT
+ MB_ICONASTERISK, // SOUND_INFO
+ MB_ICONEXCLAMATION, // SOUND_WARNING
+ MB_ICONHAND, // SOUND_ERROR
+ MB_ICONQUESTION // SOUND_QUERY
+ };
+
+#if SOUND_COUNT != 5
+#error New Sound must be defined!
+#endif
+
+ MessageBeep( aImplSoundTab[eSoundType] );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetCallback( void* pInst, SALFRAMEPROC pProc )
+{
+ maFrameData.mpInst = pInst;
+ if ( pProc )
+ maFrameData.mpProc = pProc;
+ else
+ maFrameData.mpProc = ImplSalCallbackDummy;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleMouseMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ SalMouseEvent aMouseEvt;
+ long nRet;
+ USHORT nEvent;
+ BOOL bCall = TRUE;
+
+ aMouseEvt.mnX = (short)LOWORD( lParam );
+ aMouseEvt.mnY = (short)HIWORD( lParam );
+ aMouseEvt.mnCode = 0;
+ aMouseEvt.mnTime = GetMessageTime();
+
+ // Wegen (Logitech-)MouseTreiber ueber GetKeyState() gehen, die auf
+ // mittlerer Maustaste Doppelklick simulieren und den KeyStatus nicht
+ // beruecksichtigen
+
+ if ( GetKeyState( VK_LBUTTON ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_LEFT;
+ if ( GetKeyState( VK_MBUTTON ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_MIDDLE;
+ if ( GetKeyState( VK_RBUTTON ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_RIGHT;
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_MOD2;
+
+ switch ( nMsg )
+ {
+ case WM_MOUSEMOVE:
+ {
+ // Da bei Druecken von Modifier-Tasten die MouseEvents
+ // nicht zusammengefast werden (da diese durch KeyEvents
+ // unterbrochen werden), machen wir dieses hier selber
+ if ( aMouseEvt.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2) )
+ {
+ MSG aTempMsg;
+ if ( ImplPeekMessage( &aTempMsg, hWnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE | PM_NOYIELD ) )
+ {
+ if ( (aTempMsg.message == WM_MOUSEMOVE) &&
+ (aTempMsg.wParam == wParam) )
+ return 1;
+ }
+ }
+
+ SalData* pSalData = GetSalData();
+ // Test for MouseLeave
+ if ( pSalData->mhWantLeaveMsg && (pSalData->mhWantLeaveMsg != hWnd) )
+ ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, GetMessagePos() );
+ pSalData->mhWantLeaveMsg = hWnd;
+ // Start MouseLeave-Timer
+ if ( !pSalData->mpMouseLeaveTimer )
+ {
+ pSalData->mpMouseLeaveTimer = new AutoTimer;
+ pSalData->mpMouseLeaveTimer->SetTimeout( SAL_MOUSELEAVE_TIMEOUT );
+ pSalData->mpMouseLeaveTimer->Start();
+ // We dont need to set a timeout handler, because we test
+ // for mouseleave in the timeout callback
+ }
+ aMouseEvt.mnButton = 0;
+ nEvent = SALEVENT_MOUSEMOVE;
+ }
+ break;
+
+ case WM_NCMOUSEMOVE:
+ case SAL_MSG_MOUSELEAVE:
+ {
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mhWantLeaveMsg == hWnd )
+ {
+ pSalData->mhWantLeaveMsg = 0;
+ if ( pSalData->mpMouseLeaveTimer )
+ {
+ delete pSalData->mpMouseLeaveTimer;
+ pSalData->mpMouseLeaveTimer = NULL;
+ }
+ // Mouse-Coordinaates are relativ to the screen
+ POINT aPt;
+ aPt.x = (short)LOWORD( lParam );
+ aPt.y = (short)HIWORD( lParam );
+ ScreenToClient( hWnd, &aPt );
+ aMouseEvt.mnX = aPt.x;
+ aMouseEvt.mnY = aPt.y;
+ aMouseEvt.mnButton = 0;
+ nEvent = SALEVENT_MOUSELEAVE;
+ }
+ else
+ bCall = FALSE;
+ }
+ break;
+
+ case WM_LBUTTONDOWN:
+ aMouseEvt.mnButton = MOUSE_LEFT;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ break;
+
+ case WM_MBUTTONDOWN:
+ aMouseEvt.mnButton = MOUSE_MIDDLE;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ break;
+
+ case WM_RBUTTONDOWN:
+ aMouseEvt.mnButton = MOUSE_RIGHT;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ break;
+
+ case WM_LBUTTONUP:
+ aMouseEvt.mnButton = MOUSE_LEFT;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+
+ case WM_MBUTTONUP:
+ aMouseEvt.mnButton = MOUSE_MIDDLE;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+
+ case WM_RBUTTONUP:
+ aMouseEvt.mnButton = MOUSE_RIGHT;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+ }
+
+ if ( bCall )
+ {
+ if ( nEvent == SALEVENT_MOUSEBUTTONDOWN )
+ UpdateWindow( hWnd );
+
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aMouseEvt );
+ if ( nMsg == WM_MOUSEMOVE )
+ SetCursor( pFrame->maFrameData.mhCursor );
+ }
+ else
+ nRet = 0;
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleMouseActivateMsg( HWND hWnd )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ SalMouseActivateEvent aMouseActivateEvt;
+ POINT aPt;
+ GetCursorPos( &aPt );
+ ScreenToClient( hWnd, &aPt );
+ aMouseActivateEvt.mnX = aPt.x;
+ aMouseActivateEvt.mnY = aPt.y;
+ return pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_MOUSEACTIVATE, &aMouseActivateEvt );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleWheelMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ ImplSalYieldMutexAcquireWithWait();
+
+ long nRet = 0;
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ WORD nWinModCode = LOWORD( wParam );
+ POINT aWinPt;
+ aWinPt.x = (short)LOWORD( lParam );
+ aWinPt.y = (short)HIWORD( lParam );
+ ScreenToClient( hWnd, &aWinPt );
+
+ SalWheelMouseEvent aWheelEvt;
+ aWheelEvt.mnTime = GetMessageTime();
+ aWheelEvt.mnX = aWinPt.x;
+ aWheelEvt.mnY = aWinPt.y;
+ aWheelEvt.mnCode = 0;
+ aWheelEvt.mnDelta = (short)HIWORD( wParam );
+ aWheelEvt.mnNotchDelta = aWheelEvt.mnDelta/WHEEL_DELTA;
+ if ( aSalShlData.mnWheelScrollLines == WHEEL_PAGESCROLL )
+ aWheelEvt.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
+ else
+ aWheelEvt.mnScrollLines = aSalShlData.mnWheelScrollLines;
+ aWheelEvt.mbHorz = FALSE;
+
+ if ( nWinModCode & MK_SHIFT )
+ aWheelEvt.mnCode |= KEY_SHIFT;
+ if ( nWinModCode & MK_CONTROL )
+ aWheelEvt.mnCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ aWheelEvt.mnCode |= KEY_MOD2;
+
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_WHEELMOUSE, &aWheelEvt );
+ }
+
+ ImplSalYieldMutexRelease();
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplSalGetKeyCode( WPARAM wParam )
+{
+ USHORT nKeyCode;
+
+ // convert KeyCode
+ if ( wParam < KEY_TAB_SIZE )
+ nKeyCode = aImplTranslateKeyTab[wParam];
+ else if ( wParam == aSalShlData.mnVKAdd )
+ nKeyCode = KEY_ADD;
+ else if ( wParam == aSalShlData.mnVKSubtract )
+ nKeyCode = KEY_SUBTRACT;
+ else if ( wParam == aSalShlData.mnVKMultiply )
+ nKeyCode = KEY_MULTIPLY;
+ else if ( wParam == aSalShlData.mnVKDivide )
+ nKeyCode = KEY_DIVIDE;
+ else if ( wParam == aSalShlData.mnVKPoint )
+ nKeyCode = KEY_POINT;
+ else if ( wParam == aSalShlData.mnVKComma )
+ nKeyCode = KEY_COMMA;
+ else if ( wParam == aSalShlData.mnVKLess )
+ nKeyCode = KEY_LESS;
+ else if ( wParam == aSalShlData.mnVKGreater )
+ nKeyCode = KEY_GREATER;
+ else if ( wParam == aSalShlData.mnVKEqual )
+ nKeyCode = KEY_EQUAL;
+ else
+ nKeyCode = 0;
+
+ return nKeyCode;
+}
+
+// -----------------------------------------------------------------------
+
+static UINT ImplStrToNum( const sal_Char* pStr )
+{
+ USHORT n = 0;
+
+ // Solange es sich um eine Ziffer handelt, String umwandeln
+ while( (*pStr >= 48) && (*pStr <= 57) )
+ {
+ n *= 10;
+ n += ((*pStr) - 48);
+ pStr++;
+ }
+
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Unicode ImplGetCharCode( SalFrame* pFrame, WPARAM nCharCode )
+{
+ // If we are on Windows NT we use Unicode FrameProcs and so we
+ // get Unicode charcodes directly from Windows
+ if ( aSalShlData.mbWNT )
+ return (sal_Unicode)nCharCode;
+
+ UINT nLang = LOWORD( GetKeyboardLayout( 0 ) );
+ if ( !nLang )
+ {
+ pFrame->maFrameData.mnInputLang = 0;
+ pFrame->maFrameData.mnInputCodePage = GetACP();
+ }
+ else if ( nLang != pFrame->maFrameData.mnInputLang )
+ {
+ pFrame->maFrameData.mnInputLang = nLang;
+ sal_Char aBuf[10];
+ if ( GetLocaleInfoA( MAKELCID( nLang, SORT_DEFAULT ), LOCALE_IDEFAULTANSICODEPAGE,
+ aBuf, sizeof(aBuf) ) > 0 )
+ {
+ pFrame->maFrameData.mnInputCodePage = ImplStrToNum( aBuf );
+ if ( !pFrame->maFrameData.mnInputCodePage )
+ pFrame->maFrameData.mnInputCodePage = GetACP();
+ }
+ else
+ pFrame->maFrameData.mnInputCodePage = GetACP();
+ }
+
+ sal_Char aCharBuf[2];
+ int nCharLen;
+ WCHAR c;
+ if ( nCharCode > 0xFF )
+ {
+ aCharBuf[0] = (sal_Char)(nCharCode>>8);
+ aCharBuf[1] = (sal_Char)nCharCode;
+ nCharLen = 2;
+ }
+ else
+ {
+ aCharBuf[0] = (sal_Char)nCharCode;
+ nCharLen = 1;
+ }
+ if ( ::MultiByteToWideChar( pFrame->maFrameData.mnInputCodePage,
+ MB_PRECOMPOSED,
+ aCharBuf, nCharLen, &c, 1 ) )
+ return (sal_Unicode)c;
+ else
+ return (sal_Unicode)nCharCode;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleKeyMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+ static BOOL bIgnoreCharMsg = FALSE;
+ static WPARAM nDeadChar = 0;
+ static WPARAM nLastVKChar = 0;
+ static USHORT nLastChar = 0;
+ USHORT nRepeat = LOWORD( lParam )-1;
+ USHORT nModCode = 0;
+
+ // Key wurde evtl. durch SysChild an uns weitergeleitet und
+ // darf somit dann nicht doppelt verarbeitet werden
+ GetSalData()->mnSalObjWantKeyEvt = 0;
+
+ if ( nMsg == WM_DEADCHAR )
+ {
+ nDeadChar = wParam;
+ return 0;
+ }
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ // Wir restaurieren den Background-Modus bei jeder Texteingabe,
+ // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
+ if ( pFrame->maFrameData.mpGraphics &&
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC )
+ SetBkMode( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC, TRANSPARENT );
+
+ // determine modifiers
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ {
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) &&
+ ((nMsg == WM_SYSKEYDOWN) || (nMsg == WM_SYSKEYUP)) )
+ nModCode |= KEY_CONTROLMOD;
+ }
+
+ if ( (nMsg == WM_CHAR) || (nMsg == WM_SYSCHAR) )
+ {
+ nDeadChar = 0;
+
+ if ( bIgnoreCharMsg )
+ {
+ bIgnoreCharMsg = FALSE;
+ return 0;
+ }
+
+ // Backspace ignorieren wir als eigenstaendige Taste,
+ // damit wir keine Probleme in Kombination mit einem
+ // DeadKey bekommen
+ if ( wParam == 0x08 ) // BACKSPACE
+ return 0;
+
+ // Hier kommen nur "freifliegende" WM_CHAR Message an, die durch
+ // eintippen einer ALT-NUMPAD Kombination erzeugt wurden
+ SalKeyEvent aKeyEvt;
+
+ if ( (wParam >= '0') && (wParam <= '9') )
+ aKeyEvt.mnCode = KEYGROUP_NUM + wParam - '0';
+ else if ( (wParam >= 'A') && (wParam <= 'Z') )
+ aKeyEvt.mnCode = KEYGROUP_ALPHA + wParam - 'A';
+ else if ( (wParam >= 'a') && (wParam <= 'z') )
+ aKeyEvt.mnCode = KEYGROUP_ALPHA + wParam - 'a';
+ else if ( wParam == 0x0D ) // RETURN
+ aKeyEvt.mnCode = KEY_RETURN;
+ else if ( wParam == 0x1B ) // ESCAPE
+ aKeyEvt.mnCode = KEY_ESCAPE;
+ else if ( wParam == 0x09 ) // TAB
+ aKeyEvt.mnCode = KEY_TAB;
+ else if ( wParam == 0x20 ) // SPACE
+ aKeyEvt.mnCode = KEY_SPACE;
+ else
+ aKeyEvt.mnCode = 0;
+
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, wParam );
+ aKeyEvt.mnRepeat = nRepeat;
+ nLastChar = 0;
+ nLastVKChar = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return nRet;
+ }
+ else
+ {
+ // Bei Shift, Control und Menu schicken wir einen KeyModChange-Event
+ if ( (wParam == VK_SHIFT) || (wParam == VK_CONTROL) || (wParam == VK_MENU) )
+ {
+ SalKeyModEvent aModEvt;
+ aModEvt.mnTime = GetMessageTime();
+ aModEvt.mnCode = nModCode;
+ return pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYMODCHANGE, &aModEvt );
+ }
+ else
+ {
+ SalKeyEvent aKeyEvt;
+ USHORT nEvent;
+ MSG aCharMsg;
+ WIN_BOOL bCharPeek = FALSE;
+ UINT nCharMsg = WM_CHAR;
+ BOOL bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP);
+
+ aKeyEvt.mnCode = ImplSalGetKeyCode( wParam );
+ if ( !bKeyUp )
+ {
+ // check for charcode
+ // Mit Hilfe von PeekMessage holen wir uns jetzt die
+ // zugehoerige WM_CHAR Message, wenn vorhanden.
+ // Diese WM_CHAR Message steht immer am Anfang der
+ // Messagequeue. Ausserdem ist sichergestellt, dass immer
+ // nur eine WM_CHAR Message in der Queue steht.
+ bCharPeek = ImplPeekMessage( &aCharMsg, hWnd,
+ WM_CHAR, WM_CHAR, PM_NOREMOVE | PM_NOYIELD );
+ if ( bCharPeek && (nDeadChar == aCharMsg.wParam) )
+ {
+ bCharPeek = FALSE;
+ nDeadChar = 0;
+
+ if ( wParam == VK_BACK )
+ {
+ ImplPeekMessage( &aCharMsg, hWnd,
+ nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD );
+ return 0;
+ }
+ }
+ else
+ {
+ if ( !bCharPeek )
+ {
+ bCharPeek = ImplPeekMessage( &aCharMsg, hWnd,
+ WM_SYSCHAR, WM_SYSCHAR, PM_NOREMOVE | PM_NOYIELD );
+ nCharMsg = WM_SYSCHAR;
+ }
+ }
+ if ( bCharPeek )
+ aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, aCharMsg.wParam );
+ else
+ aKeyEvt.mnCharCode = 0;
+
+ nLastChar = aKeyEvt.mnCharCode;
+ nLastVKChar = wParam;
+ }
+ else
+ {
+ if ( wParam == nLastVKChar )
+ {
+ aKeyEvt.mnCharCode = nLastChar;
+ nLastChar = 0;
+ nLastVKChar = 0;
+ }
+ }
+
+ if ( aKeyEvt.mnCode || aKeyEvt.mnCharCode )
+ {
+ if ( bKeyUp )
+ nEvent = SALEVENT_KEYUP;
+ else
+ nEvent = SALEVENT_KEYINPUT;
+
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnRepeat = nRepeat;
+ bIgnoreCharMsg = bCharPeek;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aKeyEvt );
+ bIgnoreCharMsg = FALSE;
+
+ // char-message, than remove or ignore
+ if ( bCharPeek )
+ {
+ nDeadChar = 0;
+ if ( nRet )
+ {
+ ImplPeekMessage( &aCharMsg, hWnd,
+ nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD );
+ }
+ else
+ bIgnoreCharMsg = TRUE;
+ }
+
+ return nRet;
+ }
+ else
+ return 0;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleSalObjKeyMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+ if ( (nMsg == WM_KEYDOWN) || (nMsg == WM_KEYUP) )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ USHORT nRepeat = LOWORD( lParam )-1;
+ USHORT nModCode = 0;
+
+ // determine modifiers
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ {
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+ }
+
+ if ( (wParam != VK_SHIFT) && (wParam != VK_CONTROL) && (wParam != VK_MENU) )
+ {
+ SalKeyEvent aKeyEvt;
+ USHORT nEvent;
+ BOOL bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP);
+
+ // convert KeyCode
+ aKeyEvt.mnCode = ImplSalGetKeyCode( wParam );
+ aKeyEvt.mnCharCode = 0;
+
+ if ( aKeyEvt.mnCode )
+ {
+ if ( bKeyUp )
+ nEvent = SALEVENT_KEYUP;
+ else
+ nEvent = SALEVENT_KEYINPUT;
+
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnRepeat = nRepeat;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aKeyEvt );
+ return nRet;
+ }
+ else
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleSalObjSysCharMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ USHORT nRepeat = LOWORD( lParam )-1;
+ USHORT nModCode = 0;
+ USHORT cKeyCode = (USHORT)wParam;
+
+ // determine modifiers
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+
+ // KeyEvent zusammenbauen
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = GetMessageTime();
+ if ( (cKeyCode >= 48) && (cKeyCode <= 57) )
+ aKeyEvt.mnCode = KEY_0+(cKeyCode-48);
+ else if ( (cKeyCode >= 65) && (cKeyCode <= 90) )
+ aKeyEvt.mnCode = KEY_A+(cKeyCode-65);
+ else if ( (cKeyCode >= 97) && (cKeyCode <= 122) )
+ aKeyEvt.mnCode = KEY_A+(cKeyCode-97);
+ else
+ aKeyEvt.mnCode = 0;
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, cKeyCode );
+ aKeyEvt.mnRepeat = nRepeat;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandlePaintMsg( HWND hWnd )
+{
+ // Clip-Region muss zurueckgesetzt werden, da wir sonst kein
+ // ordentliches Bounding-Rectangle bekommen
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mpGraphics )
+ {
+ if ( pFrame->maFrameData.mpGraphics->maGraphicsData.mhRegion )
+ SelectClipRgn( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC, 0 );
+ }
+ ImplSalYieldMutexRelease();
+ }
+
+ // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine
+ // Paint-Region anliegt
+ if ( !GetUpdateRect( hWnd, NULL, FALSE ) )
+ return;
+
+ // BeginPaint
+ PAINTSTRUCT aPs;
+ BeginPaint( hWnd, &aPs );
+
+ // Paint
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ // ClipRegion wieder herstellen
+ if ( pFrame->maFrameData.mpGraphics )
+ {
+ if ( pFrame->maFrameData.mpGraphics->maGraphicsData.mhRegion )
+ {
+ SelectClipRgn( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC,
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mhRegion );
+ }
+ }
+
+ SalPaintEvent aPEvt;
+ aPEvt.mnBoundX = aPs.rcPaint.left;
+ aPEvt.mnBoundY = aPs.rcPaint.top;
+ aPEvt.mnBoundWidth = aPs.rcPaint.right-aPs.rcPaint.left;
+ aPEvt.mnBoundHeight = aPs.rcPaint.bottom-aPs.rcPaint.top;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_PAINT, &aPEvt );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ {
+ RECT* pRect = new RECT;
+ *pRect = aPs.rcPaint;
+ ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 );
+ }
+
+ // EndPaint
+ EndPaint( hWnd, &aPs );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandlePaintMsg2( HWND hWnd, RECT* pRect )
+{
+ // Paint
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ SalPaintEvent aPEvt;
+ aPEvt.mnBoundX = pRect->left;
+ aPEvt.mnBoundY = pRect->top;
+ aPEvt.mnBoundWidth = pRect->right-pRect->left;
+ aPEvt.mnBoundHeight = pRect->bottom-pRect->top;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_PAINT, &aPEvt );
+ }
+ ImplSalYieldMutexRelease();
+ delete pRect;
+ }
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleMoveMsg( HWND hWnd )
+{
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( GetWindowStyle( hWnd ) & WS_VISIBLE )
+ pFrame->maFrameData.mbDefPos = FALSE;
+
+ // Gegen moegliche Rekursionen sichern
+ if ( !pFrame->maFrameData.mbInMoveMsg )
+ {
+ // Fenster im FullScreenModus wieder einpassen
+ pFrame->maFrameData.mbInMoveMsg = TRUE;
+ if ( pFrame->maFrameData.mbFullScreen )
+ ImplSalFrameFullScreenPos( pFrame );
+ pFrame->maFrameData.mbInMoveMsg = FALSE;
+ }
+
+ // Status merken
+ ImplSaveFrameState( pFrame );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTMOVE, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCallSizeHdl( HWND hWnd )
+{
+ // Da Windows diese Messages auch senden kann, muss hier auch die
+ // Solar-Semaphore beruecksichtigt werden
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_RESIZE, 0 );
+ // Um doppelte Paints von VCL und SAL zu vermeiden
+ if ( IsWindowVisible( hWnd ) && !pFrame->maFrameData.mbInShow )
+ UpdateWindow( hWnd );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTCALLSIZE, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSizeMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ if ( (wParam != SIZE_MAXSHOW) && (wParam != SIZE_MAXHIDE) )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mnWidth = (int)LOWORD(lParam);
+ pFrame->maFrameData.mnHeight = (int)HIWORD(lParam);
+ // Status merken
+ ImplSaveFrameState( pFrame );
+ // Call Hdl
+ ImplCallSizeHdl( hWnd );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleFocusMsg( HWND hWnd )
+{
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ // Query the actual status
+ if ( ::GetFocus() == hWnd )
+ {
+ if ( IsWindowVisible( hWnd ) && !pFrame->maFrameData.mbInShow )
+ UpdateWindow( hWnd );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_GETFOCUS, 0 );
+ }
+ else
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_LOSEFOCUS, 0 );
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTFOCUS, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleCloseMsg( HWND hWnd )
+{
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_CLOSE, 0 );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, WM_CLOSE, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleShutDownMsg( HWND hWnd )
+{
+ ImplSalYieldMutexAcquireWithWait();
+ long nRet = 0;
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_SHUTDOWN, 0 );
+ }
+ ImplSalYieldMutexRelease();
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSettingsChangeMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+ USHORT nSalEvent = SALEVENT_SETTINGSCHANGED;
+
+ if ( nMsg == WM_DEVMODECHANGE )
+ nSalEvent = SALEVENT_PRINTERCHANGED;
+#ifdef WM_DISPLAYCHANGE
+ else if ( nMsg == WM_DISPLAYCHANGE )
+ nSalEvent = SALEVENT_DISPLAYCHANGED;
+#endif
+ else if ( nMsg == WM_FONTCHANGE )
+ nSalEvent = SALEVENT_FONTCHANGED;
+ else if ( nMsg == WM_TIMECHANGE )
+ nSalEvent = SALEVENT_DATETIMECHANGED;
+ else if ( nMsg == WM_WININICHANGE )
+ {
+ if ( lParam )
+ {
+ if ( aSalShlData.mbWNT )
+ {
+ if ( ImplSalWICompareAscii( (const wchar_t*)lParam, "devices" ) == 0 )
+ nSalEvent = SALEVENT_PRINTERCHANGED;
+ }
+ else
+ {
+ if ( stricmp( (const char*)lParam, "devices" ) == 0 )
+ nSalEvent = SALEVENT_PRINTERCHANGED;
+ }
+ }
+ }
+
+#ifdef WM_SETTINGCHANGE
+ if ( nMsg == WM_SETTINGCHANGE )
+ {
+ if ( wParam == SPI_SETWHEELSCROLLLINES )
+ aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines();
+ }
+#endif
+
+ if ( WM_SYSCOLORCHANGE == nMsg && GetSalData()->mhDitherPal )
+ ImplUpdateSysColorEntries();
+
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( (nMsg == WM_DISPLAYCHANGE) || (nMsg == WM_WININICHANGE) )
+ {
+ if ( pFrame->maFrameData.mbFullScreen )
+ ImplSalFrameFullScreenPos( pFrame );
+ }
+
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nSalEvent, 0 );
+ }
+
+ ImplSalYieldMutexRelease();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleUserEvent( HWND hWnd, LPARAM lParam )
+{
+ ImplSalYieldMutexAcquireWithWait();
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_USEREVENT, (void*)lParam );
+ }
+ ImplSalYieldMutexRelease();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleForcePalette( HWND hWnd )
+{
+ SalData* pSalData = GetSalData();
+ HPALETTE hPal = pSalData->mhDitherPal;
+ if ( hPal )
+ {
+ if ( !ImplSalYieldMutexTryToAcquire() )
+ {
+ ImplPostMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 );
+ return;
+ }
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mpGraphics )
+ {
+ SalGraphics* pGraphics = pFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC, hPal, FALSE );
+ if ( RealizePalette( pGraphics->maGraphicsData.mhDC ) )
+ {
+ InvalidateRect( hWnd, NULL, FALSE );
+ UpdateWindow( hWnd );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_DISPLAYCHANGED, 0 );
+ }
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static LRESULT ImplHandlePalette( BOOL bFrame, HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ SalData* pSalData = GetSalData();
+ HPALETTE hPal = pSalData->mhDitherPal;
+ if ( !hPal )
+ return 0;
+
+ rDef = FALSE;
+ if ( pSalData->mbInPalChange )
+ return 0;
+
+ if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) )
+ {
+ if ( (HWND)wParam == hWnd )
+ return 0;
+ }
+
+ BOOL bReleaseMutex = FALSE;
+ if ( (nMsg == WM_QUERYNEWPALETTE) || (nMsg == WM_PALETTECHANGED) )
+ {
+ // Da Windows diese Messages auch sendet, muss hier auch die
+ // Solar-Semaphore beruecksichtigt werden
+ if ( ImplSalYieldMutexTryToAcquire() )
+ bReleaseMutex = TRUE;
+ else if ( nMsg == WM_QUERYNEWPALETTE )
+ ImplPostMessage( hWnd, SAL_MSG_POSTQUERYNEWPAL, wParam, lParam );
+ else /* ( nMsg == WM_PALETTECHANGED ) */
+ ImplPostMessage( hWnd, SAL_MSG_POSTPALCHANGED, wParam, lParam );
+ }
+
+ SalVirtualDevice* pTempVD;
+ SalFrame* pTempFrame;
+ SalGraphics* pGraphics;
+ HDC hDC;
+ HPALETTE hOldPal;
+ UINT nCols;
+ BOOL bStdDC;
+ BOOL bUpdate;
+
+ pSalData->mbInPalChange = TRUE;
+
+ // Alle Paletten in VirDevs und Frames zuruecksetzen
+ pTempVD = pSalData->mpFirstVD;
+ while ( pTempVD )
+ {
+ pGraphics = pTempVD->maVirDevData.mpGraphics;
+ if ( pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC,
+ pGraphics->maGraphicsData.mhDefPal,
+ TRUE );
+ }
+ pTempVD = pTempVD->maVirDevData.mpNext;
+ }
+ pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame )
+ {
+ pGraphics = pTempFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC,
+ pGraphics->maGraphicsData.mhDefPal,
+ TRUE );
+ }
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+ }
+
+ // Palette neu realizen
+ SalFrame* pFrame = NULL;
+ if ( bFrame )
+ pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mpGraphics )
+ {
+ hDC = pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC;
+ bStdDC = TRUE;
+ }
+ else
+ {
+ hDC = GetDC( hWnd );
+ bStdDC = FALSE;
+ }
+ UnrealizeObject( hPal );
+ hOldPal = SelectPalette( hDC, hPal, TRUE );
+ nCols = RealizePalette( hDC );
+ bUpdate = nCols != 0;
+ if ( !bStdDC )
+ {
+ SelectPalette( hDC, hOldPal, TRUE );
+ ReleaseDC( hWnd, hDC );
+ }
+
+ // Alle Paletten in VirDevs und Frames neu setzen
+ pTempVD = pSalData->mpFirstVD;
+ while ( pTempVD )
+ {
+ pGraphics = pTempVD->maVirDevData.mpGraphics;
+ if ( pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC, hPal, TRUE );
+ RealizePalette( pGraphics->maGraphicsData.mhDC );
+ }
+ pTempVD = pTempVD->maVirDevData.mpNext;
+ }
+ pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame )
+ {
+ if ( pTempFrame != pFrame )
+ {
+ pGraphics = pTempFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC, hPal, TRUE );
+ if ( RealizePalette( pGraphics->maGraphicsData.mhDC ) )
+ bUpdate = TRUE;
+ }
+ }
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+ }
+
+ // Wenn sich Farben geaendert haben, dann die Fenster updaten
+ if ( bUpdate )
+ {
+ pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame )
+ {
+ pGraphics = pTempFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ InvalidateRect( pTempFrame->maFrameData.mhWnd, NULL, FALSE );
+ UpdateWindow( pTempFrame->maFrameData.mhWnd );
+ pTempFrame->maFrameData.mpProc( pTempFrame->maFrameData.mpInst, pTempFrame,
+ SALEVENT_DISPLAYCHANGED, 0 );
+ }
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+ }
+ }
+
+ pSalData->mbInPalChange = FALSE;
+
+ if ( bReleaseMutex )
+ ImplSalYieldMutexRelease();
+
+ if ( nMsg == WM_PALETTECHANGED )
+ return 0;
+ else
+ return nCols;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplHandleMinMax( HWND hWnd, LPARAM lParam )
+{
+ int bRet = FALSE;
+
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( pFrame->maFrameData.mbFullScreen )
+ {
+ MINMAXINFO* pMinMax = (MINMAXINFO*)lParam;
+ int nX;
+ int nY;
+ int nDX;
+ int nDY;
+ ImplSalCalcFullScreenSize( pFrame, nX, nY, nDX, nDY );
+
+ if ( pMinMax->ptMaxPosition.x > nX )
+ pMinMax->ptMaxPosition.x = nX;
+ if ( pMinMax->ptMaxPosition.y > nY )
+ pMinMax->ptMaxPosition.y = nY;
+
+ if ( pMinMax->ptMaxSize.x < nDX )
+ pMinMax->ptMaxSize.x = nDX;
+ if ( pMinMax->ptMaxSize.y < nDY )
+ pMinMax->ptMaxSize.y = nDY;
+ if ( pMinMax->ptMaxTrackSize.x < nDX )
+ pMinMax->ptMaxTrackSize.x = nDX;
+ if ( pMinMax->ptMaxTrackSize.y < nDY )
+ pMinMax->ptMaxTrackSize.y = nDY;
+
+ pMinMax->ptMinTrackSize.x = nDX;
+ pMinMax->ptMinTrackSize.y = nDY;
+
+ bRet = TRUE;
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplHandleSysCommand( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ WPARAM nCommand = wParam & 0xFFF0;
+
+ if ( pFrame->maFrameData.mbFullScreen )
+ {
+ WIN_BOOL bMaximize = IsZoomed( pFrame->maFrameData.mhWnd );
+ WIN_BOOL bMinimize = IsIconic( pFrame->maFrameData.mhWnd );
+ if ( (nCommand == SC_SIZE) ||
+ (!bMinimize && (nCommand == SC_MOVE)) ||
+ (!bMaximize && (nCommand == SC_MAXIMIZE)) ||
+ (bMaximize && (nCommand == SC_RESTORE)) )
+ {
+ MessageBeep( 0 );
+ return TRUE;
+ }
+ }
+
+ if ( nCommand == SC_KEYMENU )
+ {
+ // Hier verarbeiten wir nur KeyMenu-Events fuer Alt um
+ // den MenuBar zu aktivieren, oder wenn ein SysChild-Fenster
+ // den Focus hat, da diese Alt+Tasten-Kombinationen nur
+ // ueber diesen Event verarbeitet werden
+ if ( !LOWORD( lParam ) )
+ {
+ // Nur ausloesen, wenn keine weitere Taste gedrueckt ist. Im
+ // Gegensatz zur Doku wird in der X-Koordinaate der CharCode
+ // geliefert, der zusaetzlich gedrueckt ist
+ // Also 32 fuer Space, 99 fuer c, 100 fuer d, ...
+ // Da dies nicht dokumentiert ist, fragen wir vorsichtshalber
+ // auch den Status der Space-Taste ab
+ if ( GetKeyState( VK_SPACE ) & 0x8000 )
+ return 0;
+
+ // Damit nicht bei Alt+Maustaste auch der MenuBar aktiviert wird
+ if ( (GetKeyState( VK_LBUTTON ) & 0x8000) ||
+ (GetKeyState( VK_RBUTTON ) & 0x8000) ||
+ (GetKeyState( VK_MBUTTON ) & 0x8000) )
+ return 1;
+
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode = KEY_MENU;
+ aKeyEvt.mnCharCode = 0;
+ aKeyEvt.mnRepeat = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return (nRet != 0);
+ }
+ else
+ {
+ // Testen, ob ein SysChild den Focus hat
+ HWND hFocusWnd = ::GetFocus();
+ if ( hFocusWnd && ImplFindSalObject( hFocusWnd ) )
+ {
+ char cKeyCode = (char)(unsigned char)LOWORD( lParam );
+ // LowerCase
+ if ( (cKeyCode >= 65) && (cKeyCode <= 90) )
+ cKeyCode += 32;
+ // Wir nehmen nur 0-9 und A-Z, alle anderen Tasten muessen durch
+ // den Hook vom SalObj verarbeitet werden
+ if ( ((cKeyCode >= 48) && (cKeyCode <= 57)) ||
+ ((cKeyCode >= 97) && (cKeyCode <= 122)) )
+ {
+ USHORT nModCode = 0;
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = GetMessageTime();
+ if ( (cKeyCode >= 48) && (cKeyCode <= 57) )
+ aKeyEvt.mnCode = KEY_0+(cKeyCode-48);
+ else
+ aKeyEvt.mnCode = KEY_A+(cKeyCode-97);
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = cKeyCode;
+ aKeyEvt.mnRepeat = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return (nRet != 0);
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleInputLangChange( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ ImplSalYieldMutexAcquireWithWait();
+
+ // Feststellen, ob wir IME unterstuetzen
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbIME && pFrame->maFrameData.mhDefIMEContext )
+ {
+ HWND hWnd = pFrame->maFrameData.mhWnd;
+ HKL hKL = (HKL)lParam;
+ UINT nImeProps = ImmGetProperty( hKL, IGP_PROPERTY );
+
+ pFrame->maFrameData.mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
+ pFrame->maFrameData.mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
+ pFrame->maFrameData.mbHandleIME = !pFrame->maFrameData.mbSpezIME;
+ }
+
+ ImplSalYieldMutexRelease();
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplHandleIMEStartComposition( HWND hWnd )
+{
+ BOOL bDef = TRUE;
+
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( pFrame->maFrameData.mbHandleIME )
+ {
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ // Cursor-Position ermitteln und aus der die Default-Position fuer
+ // das Composition-Fenster berechnen
+ SalCursorPosEvent aCursorPosEvt;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_CURSORPOS, (void*)&aCursorPosEvt );
+ COMPOSITIONFORM aForm;
+ memset( &aForm, 0, sizeof( aForm ) );
+ if ( !aCursorPosEvt.mnWidth || !aCursorPosEvt.mnHeight )
+ aForm.dwStyle |= CFS_DEFAULT;
+ else
+ {
+ aForm.dwStyle |= CFS_POINT;
+ aForm.ptCurrentPos.x = aCursorPosEvt.mnX;
+ aForm.ptCurrentPos.y = aCursorPosEvt.mnY;
+ }
+ ImmSetCompositionWindow( hIMC, &aForm );
+
+ // Den InputContect-Font ermitteln und diesem dem Composition-Fenster
+ // bekannt machen
+
+ ImmReleaseContext( hWnd, hIMC );
+ }
+
+ pFrame->maFrameData.mbCompositionMode = TRUE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_STARTEXTTEXTINPUT, (void*)NULL );
+ if ( pFrame->maFrameData.mbAtCursorIME )
+ bDef = FALSE;
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+
+ return bDef;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplHandleIMEComposition( HWND hWnd, LPARAM lParam )
+{
+ BOOL bDef = TRUE;
+ if ( lParam & (GCS_RESULTSTR | GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS) )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbHandleIME &&
+ (pFrame->maFrameData.mbCompositionMode || !(lParam & GCS_RESULTSTR)) )
+ {
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ SalExtTextInputEvent aEvt;
+ aEvt.mnTime = GetMessageTime();
+ aEvt.mpTextAttr = NULL;
+ aEvt.mnCursorPos = 0;
+ aEvt.mnDeltaStart = 0;
+ aEvt.mbOnlyCursor = FALSE;
+ aEvt.mbCursorVisible = !pFrame->maFrameData.mbCandidateMode;
+
+ LONG nTextLen;
+ xub_Unicode* pTextBuf = NULL;
+ LONG nAttrLen;
+ WIN_BYTE* pAttrBuf = NULL;
+ BOOL bLastCursor = FALSE;
+ if ( lParam & GCS_RESULTSTR )
+ {
+ nTextLen = ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, 0, 0 ) / sizeof( WCHAR );
+ if ( nTextLen >= 0 )
+ {
+ pTextBuf = new xub_Unicode[nTextLen];
+ ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, pTextBuf, nTextLen*sizeof( WCHAR ) );
+ }
+
+ bLastCursor = TRUE;
+ aEvt.mbCursorVisible = TRUE;
+ bDef = FALSE;
+ }
+ else if ( pFrame->maFrameData.mbAtCursorIME )
+ {
+ bDef = FALSE;
+ if ( lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS) )
+ {
+ nTextLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 ) / sizeof( WCHAR );
+ if ( nTextLen >= 0 )
+ {
+ pTextBuf = new xub_Unicode[nTextLen];
+ ImmGetCompositionStringW( hIMC, GCS_COMPSTR, pTextBuf, nTextLen*sizeof( WCHAR ) );
+ }
+
+ nAttrLen = ImmGetCompositionStringW( hIMC, GCS_COMPATTR, 0, 0 );
+ if ( nAttrLen >= 0 )
+ {
+ pAttrBuf = new WIN_BYTE[nAttrLen];
+ ImmGetCompositionStringW( hIMC, GCS_COMPATTR, pAttrBuf, nAttrLen );
+ }
+
+ aEvt.mnCursorPos = LOWORD( ImmGetCompositionStringW( hIMC, GCS_CURSORPOS, 0, 0 ) );
+ aEvt.mnDeltaStart = LOWORD( ImmGetCompositionStringW( hIMC, GCS_DELTASTART, 0, 0 ) );
+
+ if ( lParam == GCS_CURSORPOS )
+ aEvt.mbOnlyCursor = TRUE;
+ }
+ }
+
+ USHORT* pSalAttrAry = NULL;
+ if ( pTextBuf )
+ {
+ aEvt.maText = XubString( pTextBuf, (USHORT)nTextLen );
+ delete pTextBuf;
+ if ( pAttrBuf )
+ {
+ xub_StrLen nTextLen = aEvt.maText.Len();
+ if ( nTextLen )
+ {
+ pSalAttrAry = new USHORT[nTextLen];
+ memset( pSalAttrAry, 0, nTextLen*sizeof( USHORT ) );
+ for ( xub_StrLen i = 0; (i < nTextLen) && (i < nAttrLen); i++ )
+ {
+ WIN_BYTE nWinAttr = pAttrBuf[i];
+ USHORT nSalAttr;
+ if ( nWinAttr == ATTR_TARGET_CONVERTED )
+ {
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETCONVERTED | SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
+ aEvt.mbCursorVisible = FALSE;
+ }
+ else if ( nWinAttr == ATTR_CONVERTED )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_CONVERTED | SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE;
+ else if ( nWinAttr == ATTR_TARGET_NOTCONVERTED )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETNOTCONVERTED | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ else if ( nWinAttr == ATTR_INPUT_ERROR )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUTERROR | SAL_EXTTEXTINPUT_ATTR_REDTEXT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ else /* ( nWinAttr == ATTR_INPUT ) */
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ pSalAttrAry[i] = nSalAttr;
+ }
+ aEvt.mpTextAttr = pSalAttrAry;
+ }
+ delete pAttrBuf;
+ }
+ if ( bLastCursor )
+ aEvt.mnCursorPos = aEvt.maText.Len();
+ }
+
+ ImmReleaseContext( hWnd, hIMC );
+
+ // Handler rufen und wenn wir ein Attribute-Array haben, danach
+ // wieder zerstoeren
+ if ( !bDef )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_EXTTEXTINPUT, (void*)&aEvt );
+ }
+ if ( pSalAttrAry )
+ delete pSalAttrAry;
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ }
+
+ return bDef;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplHandleIMEEndComposition( HWND hWnd )
+{
+ BOOL bDef = TRUE;
+
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbHandleIME )
+ {
+ // Wir restaurieren den Background-Modus bei jeder Texteingabe,
+ // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
+ if ( pFrame->maFrameData.mpGraphics &&
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC )
+ SetBkMode( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC, TRANSPARENT );
+
+ pFrame->maFrameData.mbCompositionMode = FALSE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_ENDEXTTEXTINPUT, (void*)NULL );
+ if ( pFrame->maFrameData.mbAtCursorIME )
+ bDef = FALSE;
+ }
+
+ ImplSalYieldMutexRelease();
+
+ return bDef;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleIMENotify( HWND hWnd, WPARAM wParam )
+{
+ if ( wParam == (WPARAM)IMN_OPENCANDIDATE )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbHandleIME &&
+ pFrame->maFrameData.mbAtCursorIME )
+ {
+ // Wir wollen den Cursor hiden
+ pFrame->maFrameData.mbCandidateMode = TRUE;
+ ImplHandleIMEComposition( hWnd, GCS_CURSORPOS );
+
+ HWND hWnd = pFrame->maFrameData.mhWnd;
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ LONG nBufLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 );
+ if ( nBufLen >= 1 )
+ {
+ USHORT nCursorPos = LOWORD( ImmGetCompositionStringW( hIMC, GCS_CURSORPOS, 0, 0 ) );
+ SalExtTextInputPosEvent aEvt;
+ aEvt.mnTime = GetMessageTime();
+ aEvt.mnFirstPos = nCursorPos;
+ aEvt.mnChars = nBufLen/sizeof(sal_Unicode) - nCursorPos;
+ aEvt.mpPosAry = new SalExtCharPos[aEvt.mnChars];
+ memset( aEvt.mpPosAry, 0, aEvt.mnChars*sizeof(SalExtCharPos) );
+
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_EXTTEXTINPUTPOS, (void*)&aEvt );
+
+ long nMinLeft = aEvt.mpPosAry[0].mnX;
+ long nMinTop = aEvt.mpPosAry[0].mnY;
+ long nMaxBottom = aEvt.mpPosAry[0].mnY+aEvt.mpPosAry[0].mnHeight;
+ long nMaxRight = nMinLeft;
+ USHORT i = 0;
+ while ( i < aEvt.mnChars )
+ {
+ // Solange wir uns auf der gleichen Zeile bewegen,
+ // ermitteln wir die Rechteck-Grenzen
+ if ( !aEvt.mpPosAry[i].mnHeight ||
+ (aEvt.mpPosAry[i].mnY < nMaxBottom-1) )
+ {
+ if ( aEvt.mpPosAry[i].mnX < nMinLeft )
+ nMinLeft = aEvt.mpPosAry[i].mnX;
+ if ( aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth > nMaxRight )
+ nMaxRight = aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth;
+ if ( aEvt.mpPosAry[i].mnY < nMinTop )
+ nMinTop = aEvt.mpPosAry[i].mnY;
+ i++;
+ }
+ else
+ break;
+ }
+
+ CANDIDATEFORM aForm;
+ aForm.dwIndex = 0;
+ aForm.dwStyle = CFS_EXCLUDE;
+ aForm.ptCurrentPos.x = aEvt.mpPosAry[0].mnX;
+ aForm.ptCurrentPos.y = nMaxBottom+1;
+ aForm.rcArea.left = nMinLeft;
+ aForm.rcArea.top = nMinTop;
+ aForm.rcArea.right = nMaxRight+1;
+ aForm.rcArea.bottom = nMaxBottom+1;
+ ImmSetCandidateWindow( hIMC, &aForm );
+
+ delete aEvt.mpPosAry;
+ }
+
+ ImmReleaseContext( hWnd, hIMC );
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else if ( wParam == (WPARAM)IMN_CLOSECANDIDATE )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ pFrame->maFrameData.mbCandidateMode = FALSE;
+ ImplSalYieldMutexRelease();
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+void SalTestMouseLeave()
+{
+ SalData* pSalData = GetSalData();
+
+ if ( pSalData->mhWantLeaveMsg && !::GetCapture() )
+ {
+ POINT aPt;
+ GetCursorPos( &aPt );
+ if ( pSalData->mhWantLeaveMsg != WindowFromPoint( aPt ) )
+ ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MAKELPARAM( aPt.x, aPt.y ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplSalWheelMousePos( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ,
+ LRESULT& rResult )
+{
+ POINT aPt;
+ POINT aScreenPt;
+ aScreenPt.x = (short)LOWORD( lParam );
+ aScreenPt.y = (short)HIWORD( lParam );
+ // Child-Fenster suchen, welches an der entsprechenden
+ // Position liegt
+ HWND hChildWnd;
+ HWND hWheelWnd = hWnd;
+ do
+ {
+ hChildWnd = hWheelWnd;
+ aPt = aScreenPt;
+ ScreenToClient( hChildWnd, &aPt );
+ hWheelWnd = ChildWindowFromPointEx( hChildWnd, aPt, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT );
+ }
+ while ( hWheelWnd && (hWheelWnd != hChildWnd) );
+ if ( hWheelWnd && (hWheelWnd != hWnd) &&
+ (hWheelWnd != ::GetFocus()) && IsWindowEnabled( hWheelWnd ) )
+ {
+ rResult = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ LRESULT nRet = 0;
+ static int bInWheelMsg = FALSE;
+
+ // By WM_CRETAE we connect the frame with the window handle
+ if ( nMsg == WM_CREATE )
+ {
+ // Window-Instanz am Windowhandle speichern
+ // Can also be used for the W-Version, because the struct
+ // to access lpCreateParams is the same structure
+ CREATESTRUCTA* pStruct = (CREATESTRUCTA*)lParam;
+ SalFrame* pFrame = (SalFrame*)pStruct->lpCreateParams;
+ SetWindowPtr( hWnd, pFrame );
+ // HWND schon hier setzen, da schon auf den Instanzdaten
+ // gearbeitet werden kann, wenn Messages waehrend
+ // CreateWindow() gesendet werden
+ pFrame->maFrameData.mhWnd = hWnd;
+ pFrame->maFrameData.maSysData.hWnd = hWnd;
+ return 0;
+ }
+
+ switch( nMsg )
+ {
+ case WM_MOUSEMOVE:
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_MBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_NCMOUSEMOVE:
+ case SAL_MSG_MOUSELEAVE:
+ ImplSalYieldMutexAcquireWithWait();
+ rDef = !ImplHandleMouseMsg( hWnd, nMsg, wParam, lParam );
+ ImplSalYieldMutexRelease();
+ break;
+
+ case WM_MOUSEACTIVATE:
+ if ( LOWORD( lParam ) == HTCLIENT )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ nRet = ImplHandleMouseActivateMsg( hWnd );
+ ImplSalYieldMutexRelease();
+ if ( nRet )
+ {
+ nRet = MA_NOACTIVATE;
+ rDef = FALSE;
+ }
+ }
+ break;
+
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_DEADCHAR:
+ case WM_CHAR:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_SYSCHAR:
+ ImplSalYieldMutexAcquireWithWait();
+ rDef = !ImplHandleKeyMsg( hWnd, nMsg, wParam, lParam );
+ ImplSalYieldMutexRelease();
+ break;
+
+ case WM_MOUSEWHEEL:
+ // Gegen Rekursion absichern, falls wir vom IE oder dem externen
+ // Fenster die Message wieder zurueckbekommen
+ if ( !bInWheelMsg )
+ {
+ bInWheelMsg++;
+ rDef = !ImplHandleWheelMsg( hWnd, wParam, lParam );
+ // Wenn wir die Message nicht ausgewertet haben, schauen wir
+ // noch einmal nach, ob dort ein geplugtes Fenster steht,
+ // welches wir dann benachrichtigen
+ if ( rDef )
+ rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet );
+ bInWheelMsg--;
+ }
+ break;
+
+ case WM_SYSCOMMAND:
+ ImplSalYieldMutexAcquireWithWait();
+ nRet = ImplHandleSysCommand( hWnd, wParam, lParam );
+ ImplSalYieldMutexRelease();
+ if ( nRet )
+ rDef = FALSE;
+ break;
+
+ case WM_MOVE:
+ case SAL_MSG_POSTMOVE:
+ ImplHandleMoveMsg( hWnd );
+ rDef = FALSE;
+ break;
+ case WM_SIZE:
+ ImplHandleSizeMsg( hWnd, wParam, lParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_POSTCALLSIZE:
+ ImplCallSizeHdl( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_GETMINMAXINFO:
+ if ( ImplHandleMinMax( hWnd, lParam ) )
+ rDef = FALSE;
+ break;
+
+ case WM_ERASEBKGND:
+ nRet = 1;
+ rDef = FALSE;
+ break;
+ case WM_PAINT:
+ ImplHandlePaintMsg( hWnd );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_POSTPAINT:
+ ImplHandlePaintMsg2( hWnd, (RECT*)wParam );
+ rDef = FALSE;
+ break;
+
+ case SAL_MSG_FORCEPALETTE:
+ ImplHandleForcePalette( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_QUERYNEWPALETTE:
+ case SAL_MSG_POSTQUERYNEWPAL:
+ nRet = ImplHandlePalette( TRUE, hWnd, nMsg, wParam, lParam, rDef );
+ break;
+
+ case WM_ACTIVATE:
+ // Wenn wir aktiviert werden, dann wollen wir auch unsere
+ // Palette setzen. Wir machen dieses in Activate,
+ // damit andere externe Child-Fenster auch unsere Palette
+ // ueberschreiben koennen. So wird unsere jedenfalls nur einmal
+ // gesetzt und nicht immer rekursiv, da an allen anderen Stellen
+ // diese nur als Background-Palette gesetzt wird
+ if ( LOWORD( wParam ) != WA_INACTIVE )
+ ImplSendMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 );
+ break;
+
+ case WM_SETFOCUS:
+ case WM_KILLFOCUS:
+ case SAL_MSG_POSTFOCUS:
+ ImplHandleFocusMsg( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_CLOSE:
+ ImplHandleCloseMsg( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_QUERYENDSESSION:
+ nRet = !ImplHandleShutDownMsg( hWnd );
+ rDef = FALSE;
+ break;
+
+#ifdef WM_DISPLAYCHANGE
+ case WM_DISPLAYCHANGE:
+#endif
+#ifdef WM_SETTINGCHANGE
+ case WM_SETTINGCHANGE:
+#else
+ case WM_WININICHANGE:
+#endif
+ case WM_DEVMODECHANGE:
+ case WM_FONTCHANGE:
+ case WM_SYSCOLORCHANGE:
+ case WM_TIMECHANGE:
+ ImplHandleSettingsChangeMsg( hWnd, nMsg, wParam, lParam );
+ break;
+
+ case SAL_MSG_USEREVENT:
+ ImplHandleUserEvent( hWnd, lParam );
+ rDef = FALSE;
+ break;
+
+ case SAL_MSG_CAPTUREMOUSE:
+ SetCapture( hWnd );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_RELEASEMOUSE:
+ if ( ::GetCapture() == hWnd )
+ ReleaseCapture();
+ rDef = FALSE;
+ break;
+ case SAL_MSG_TOTOP:
+ ImplSalToTop( hWnd, (USHORT)wParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_SHOW:
+ ImplSalShow( hWnd, (BOOL)wParam );
+ rDef = FALSE;
+ break;
+
+ case WM_INPUTLANGCHANGE:
+ ImplHandleInputLangChange( hWnd, wParam, lParam );
+ break;
+
+ case WM_IME_STARTCOMPOSITION:
+ rDef = ImplHandleIMEStartComposition( hWnd );
+ break;
+
+ case WM_IME_COMPOSITION:
+ rDef = ImplHandleIMEComposition( hWnd, lParam );
+ break;
+
+ case WM_IME_ENDCOMPOSITION:
+ rDef = ImplHandleIMEEndComposition( hWnd );
+ break;
+
+ case WM_IME_NOTIFY:
+ ImplHandleIMENotify( hWnd, wParam );
+ break;
+ }
+
+ // WheelMouse-Message abfangen
+ if ( rDef && (nMsg == aSalShlData.mnWheelMsgId) && aSalShlData.mnWheelMsgId )
+ {
+ // Gegen Rekursion absichern, falls wir vom IE oder dem externen
+ // Fenster die Message wieder zurueckbekommen
+ if ( !bInWheelMsg )
+ {
+ bInWheelMsg++;
+ // Zuerst wollen wir die Message dispatchen und dann darf auch
+ // das SystemWindow drankommen
+ WORD nKeyState = 0;
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nKeyState |= MK_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nKeyState |= MK_CONTROL;
+ // Mutex handling is inside from this call
+ rDef = !ImplHandleWheelMsg( hWnd, MAKEWPARAM( nKeyState, (WORD)wParam ), lParam );
+ if ( rDef )
+ {
+ HWND hWheelWnd = ::GetFocus();
+ if ( hWheelWnd && (hWheelWnd != hWnd) )
+ {
+ nRet = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam );
+ rDef = FALSE;
+ }
+ else
+ rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet );
+ }
+ bInWheelMsg--;
+ }
+ }
+
+ return nRet;
+}
+
+LRESULT CALLBACK SalFrameWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+LRESULT CALLBACK SalFrameWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplHandleGlobalMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT& rlResult )
+{
+ // Hier verarbeiten wir alle Messages, die fuer alle Frame-Fenster gelten,
+ // damit diese nur einmal verarbeitet werden
+ // Must work for Unicode and none Unicode
+ if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) )
+ {
+ int bDef = TRUE;
+ rlResult = ImplHandlePalette( FALSE, hWnd, nMsg, wParam, lParam, bDef );
+ return (bDef != 0);
+ }
+ else
+ return FALSE;
+}
diff --git a/vcl/win/source/window/salobj.cxx b/vcl/win/source/window/salobj.cxx
new file mode 100644
index 000000000000..39b233de05e6
--- /dev/null
+++ b/vcl/win/source/window/salobj.cxx
@@ -0,0 +1,873 @@
+/*************************************************************************
+ *
+ * $RCSfile: salobj.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:50 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#ifndef _SVWIN_HXX
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALOBJ_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// =======================================================================
+
+static BOOL ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild )
+{
+ if ( hWndParent == hWndChild )
+ return TRUE;
+
+ HWND hTempWnd = ::GetParent( hWndChild );
+ while ( hTempWnd )
+ {
+ // Ab nicht Child-Fenstern hoeren wir auf zu suchen
+ if ( !(GetWindowStyle( hTempWnd ) & WS_CHILD) )
+ return FALSE;
+ if ( hTempWnd == hWndParent )
+ return TRUE;
+ hTempWnd = ::GetParent( hTempWnd );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SalObject* ImplFindSalObject( HWND hWndChild )
+{
+ SalData* pSalData = GetSalData();
+ SalObject* pObject = pSalData->mpFirstObject;
+ while ( pObject )
+ {
+ if ( ImplIsSysWindowOrChild( pObject->maObjectData.mhWndChild, hWndChild ) )
+ return pObject;
+
+ pObject = pObject->maObjectData.mpNextObject;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* ImplFindSalObjectFrame( HWND hWnd )
+{
+ SalFrame* pFrame = NULL;
+ SalObject* pObject = ImplFindSalObject( hWnd );
+ if ( pObject )
+ {
+ // Dazugehoerenden Frame suchen
+ HWND hWnd = ::GetParent( pObject->maObjectData.mhWnd );
+ pFrame = GetSalData()->mpFirstFrame;
+ while ( pFrame )
+ {
+ if ( pFrame->maFrameData.mhWnd == hWnd )
+ break;
+
+ pFrame = pFrame->maFrameData.mpNextFrame;
+ }
+ }
+
+ return pFrame;
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalSysMsgProc( int nCode, WPARAM wParam, LPARAM lParam )
+{
+ // Used for Unicode and none Unicode
+ SalData* pSalData = GetSalData();
+
+ if ( (nCode >= 0) && lParam )
+ {
+ CWPSTRUCT* pData = (CWPSTRUCT*)lParam;
+ if ( (pData->message != WM_KEYDOWN) &&
+ (pData->message != WM_KEYUP) )
+ pSalData->mnSalObjWantKeyEvt = 0;
+
+ // Testen, ob wir Daten fuer ein SalObject-Fenster behandeln
+ // muessen
+ SalObject* pObject;
+ if ( pData->message == WM_SETFOCUS )
+ {
+ pObject = ImplFindSalObject( pData->hwnd );
+ if ( pObject )
+ {
+ pObject->maObjectData.mhLastFocusWnd = pData->hwnd;
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pObject->maObjectData.mpProc( pObject->maObjectData.mpInst, pObject,
+ SALOBJ_EVENT_GETFOCUS, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( pObject->maObjectData.mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
+ }
+ }
+ else if ( pData->message == WM_KILLFOCUS )
+ {
+ pObject = ImplFindSalObject( pData->hwnd );
+ if ( pObject && !ImplFindSalObject( (HWND)pData->wParam ) )
+ {
+ // LoseFocus nur rufen, wenn wirklich kein ChildFenster
+ // den Focus bekommt
+ if ( !pData->wParam || !ImplFindSalObject( (HWND)pData->wParam ) )
+ {
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pObject->maObjectData.mpProc( pObject->maObjectData.mpInst, pObject,
+ SALOBJ_EVENT_LOSEFOCUS, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( pObject->maObjectData.mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
+ }
+ else
+ pObject->maObjectData.mhLastFocusWnd = (HWND)pData->wParam;
+ }
+ }
+ }
+
+ return CallNextHookEx( pSalData->mhSalObjMsgHook, nCode, wParam, lParam );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplSalPreDispatchMsg( MSG* pMsg )
+{
+ // Used for Unicode and none Unicode
+ SalData* pSalData = GetSalData();
+ SalObject* pObject;
+
+ if ( (pMsg->message == WM_LBUTTONDOWN) ||
+ (pMsg->message == WM_RBUTTONDOWN) ||
+ (pMsg->message == WM_MBUTTONDOWN) )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ ImplPostMessage( pObject->maObjectData.mhWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ ImplSalYieldMutexRelease();
+ }
+
+ if ( (pMsg->message == WM_KEYDOWN) ||
+ (pMsg->message == WM_KEYUP) )
+ {
+ // KeyEvents wollen wir nach Moeglichkeit auch abarbeiten,
+ // wenn das Control diese nicht selber auswertet
+ // SysKeys werden als WM_SYSCOMMAND verarbeitet
+ // Char-Events verarbeiten wir nicht, da wir nur
+ // Accelerator relevante Keys verarbeiten wollen
+ BOOL bWantedKeyCode = FALSE;
+ // A-Z, 0-9 nur in Verbindung mit Control-Taste
+ if ( ((pMsg->wParam >= 65) && (pMsg->wParam <= 90)) ||
+ ((pMsg->wParam >= 48) && (pMsg->wParam <= 57)) )
+ {
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ bWantedKeyCode = TRUE;
+ }
+ else if ( ((pMsg->wParam >= VK_F1) && (pMsg->wParam <= VK_F24)) ||
+ ((pMsg->wParam >= VK_SPACE) && (pMsg->wParam <= VK_HELP)) ||
+ (pMsg->wParam == VK_BACK) || (pMsg->wParam == VK_TAB) ||
+ (pMsg->wParam == VK_CLEAR) || (pMsg->wParam == VK_RETURN) ||
+ (pMsg->wParam == VK_ESCAPE) )
+ bWantedKeyCode = TRUE;
+ if ( bWantedKeyCode )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ pSalData->mnSalObjWantKeyEvt = pMsg->wParam;
+ ImplSalYieldMutexRelease();
+ }
+ }
+ // Hier WM_SYSCHAR abfangen, um mit Alt+Taste evtl. Menu zu aktivieren
+ else if ( pMsg->message == WM_SYSCHAR )
+ {
+ pSalData->mnSalObjWantKeyEvt = 0;
+
+ USHORT nKeyCode = LOWORD( pMsg->wParam );
+ // Nur 0-9 und A-Z
+ if ( ((nKeyCode >= 48) && (nKeyCode <= 57)) ||
+ ((nKeyCode >= 65) && (nKeyCode <= 90)) ||
+ ((nKeyCode >= 97) && (nKeyCode <= 122)) )
+ {
+ BOOL bRet = FALSE;
+ ImplSalYieldMutexAcquireWithWait();
+ pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ {
+ if ( pMsg->hwnd == ::GetFocus() )
+ {
+ SalFrame* pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
+ if ( pFrame )
+ {
+ if ( ImplHandleSalObjSysCharMsg( pFrame->maFrameData.mhWnd, pMsg->wParam, pMsg->lParam ) )
+ bRet = TRUE;
+ }
+ }
+ }
+ ImplSalYieldMutexRelease();
+ if ( bRet )
+ return TRUE;
+ }
+ }
+ else
+ pSalData->mnSalObjWantKeyEvt = 0;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalPostDispatchMsg( MSG* pMsg, LRESULT /* nDispatchResult */ )
+{
+ // Used for Unicode and none Unicode
+ SalData* pSalData = GetSalData();
+ SalFrame* pFrame;
+
+ if ( (pMsg->message == WM_KEYDOWN) || (pMsg->message == WM_KEYUP) )
+ {
+ if ( pSalData->mnSalObjWantKeyEvt == pMsg->wParam )
+ {
+ pSalData->mnSalObjWantKeyEvt = 0;
+ if ( pMsg->hwnd == ::GetFocus() )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
+ if ( pFrame )
+ ImplHandleSalObjKeyMsg( pFrame->maFrameData.mhWnd, pMsg->message, pMsg->wParam, pMsg->lParam );
+ ImplSalYieldMutexRelease();
+ }
+ }
+ }
+
+ pSalData->mnSalObjWantKeyEvt = 0;
+}
+
+// =======================================================================
+
+LRESULT CALLBACK SalSysObjWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ SalObject* pSysObj;
+ LRESULT nRet = 0;
+
+ switch( nMsg )
+ {
+ case WM_ERASEBKGND:
+ nRet = 1;
+ rDef = FALSE;
+ break;
+ case WM_PAINT:
+ {
+ PAINTSTRUCT aPs;
+ BeginPaint( hWnd, &aPs );
+ EndPaint( hWnd, &aPs );
+ rDef = FALSE;
+ }
+ break;
+
+ case WM_PARENTNOTIFY:
+ {
+ UINT nNotifyMsg = LOWORD( wParam );
+ if ( (nNotifyMsg == WM_LBUTTONDOWN) ||
+ (nNotifyMsg == WM_RBUTTONDOWN) ||
+ (nNotifyMsg == WM_MBUTTONDOWN) )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ if ( pSysObj )
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj, SALOBJ_EVENT_TOTOP, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ }
+ break;
+
+ case WM_MOUSEACTIVATE:
+ ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ break;
+
+ case SALOBJ_MSG_TOTOP:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj,
+ SALOBJ_EVENT_TOTOP, 0 );
+ ImplSalYieldMutexRelease();
+ rDef = FALSE;
+ }
+ else
+ ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ break;
+
+ case SALOBJ_MSG_POSTFOCUS:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ HWND hFocusWnd = ::GetFocus();
+ USHORT nEvent;
+ if ( hFocusWnd && ImplIsSysWindowOrChild( hWnd, hFocusWnd ) )
+ nEvent = SALOBJ_EVENT_GETFOCUS;
+ else
+ nEvent = SALOBJ_EVENT_LOSEFOCUS;
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj,
+ nEvent, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
+ rDef = FALSE;
+ break;
+
+ case WM_SIZE:
+ {
+ HWND hWndChild = GetWindow( hWnd, GW_CHILD );
+ if ( hWndChild )
+ {
+ SetWindowPos( hWndChild,
+ 0, 0, 0, (int)LOWORD( lParam ), (int)HIWORD( lParam ),
+ SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+ }
+ rDef = FALSE;
+ break;
+
+ case WM_CREATE:
+ {
+ // Window-Instanz am Windowhandle speichern
+ // Can also be used for the W-Version, because the struct
+ // to access lpCreateParams is the same structure
+ CREATESTRUCTA* pStruct = (CREATESTRUCTA*)lParam;
+ pSysObj = (SalObject*)pStruct->lpCreateParams;
+ SetSalObjWindowPtr( hWnd, pSysObj );
+ // HWND schon hier setzen, da schon auf den Instanzdaten
+ // gearbeitet werden kann, wenn Messages waehrend
+ // CreateWindow() gesendet werden
+ pSysObj->maObjectData.mhWnd = hWnd;
+ rDef = FALSE;
+ }
+ break;
+ }
+
+ return nRet;
+}
+
+LRESULT CALLBACK SalSysObjWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+LRESULT CALLBACK SalSysObjWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalSysObjChildWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ LRESULT nRet = 0;
+
+ switch( nMsg )
+ {
+ // Wegen PlugIn's loeschen wir erstmal den Hintergrund
+/*
+ case WM_ERASEBKGND:
+ nRet = 1;
+ rDef = FALSE;
+ break;
+*/
+ case WM_PAINT:
+ {
+ PAINTSTRUCT aPs;
+ BeginPaint( hWnd, &aPs );
+ EndPaint( hWnd, &aPs );
+ rDef = FALSE;
+ }
+ break;
+ }
+
+ return nRet;
+}
+
+LRESULT CALLBACK SalSysObjChildWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjChildWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+LRESULT CALLBACK SalSysObjChildWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjChildWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+// =======================================================================
+
+SalObject* ImplSalCreateObject( SalInstance* pInst, SalFrame* pParent )
+{
+ SalData* pSalData = GetSalData();
+
+ // Hook installieren, wenn es das erste SalObject ist
+ if ( !pSalData->mpFirstObject )
+ {
+ if ( aSalShlData.mbWNT )
+ {
+ pSalData->mhSalObjMsgHook = SetWindowsHookExW( WH_CALLWNDPROC,
+ SalSysMsgProc,
+ pSalData->mhInst,
+ pSalData->mnAppThreadId );
+ }
+ else
+ {
+ pSalData->mhSalObjMsgHook = SetWindowsHookExA( WH_CALLWNDPROC,
+ SalSysMsgProc,
+ pSalData->mhInst,
+ pSalData->mnAppThreadId );
+ }
+ }
+
+ if ( !pSalData->mbObjClassInit )
+ {
+ if ( aSalShlData.mbWNT )
+ {
+ WNDCLASSEXW aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalSysObjWndProcW;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_OBJECT_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.hCursor = LoadCursor( 0, IDC_ARROW );
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CLASSNAMEW;
+ if ( RegisterClassExW( &aWndClassEx ) )
+ {
+ // Wegen PlugIn's loeschen wir erstmal den Hintergrund
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ aWndClassEx.lpfnWndProc = SalSysObjChildWndProcW;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CHILDCLASSNAMEW;
+ if ( RegisterClassExW( &aWndClassEx ) )
+ pSalData->mbObjClassInit = TRUE;
+ }
+ }
+ else
+ {
+ WNDCLASSEXA aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalSysObjWndProcA;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_OBJECT_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.hCursor = LoadCursor( 0, IDC_ARROW );
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CLASSNAMEA;
+ if ( RegisterClassExA( &aWndClassEx ) )
+ {
+ // Wegen PlugIn's loeschen wir erstmal den Hintergrund
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ aWndClassEx.lpfnWndProc = SalSysObjChildWndProcA;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CHILDCLASSNAMEA;
+ if ( RegisterClassExA( &aWndClassEx ) )
+ pSalData->mbObjClassInit = TRUE;
+ }
+ }
+ }
+
+ if ( pSalData->mbObjClassInit )
+ {
+ SalObject* pObject = new SalObject;
+ HWND hWnd;
+ HWND hWndChild = 0;
+ if ( aSalShlData.mbWNT )
+ {
+ hWnd = CreateWindowExW( 0, SAL_OBJECT_CLASSNAMEW, L"",
+ WS_CHILD, 0, 0, 0, 0,
+ pParent->maFrameData.mhWnd, 0,
+ pInst->maInstData.mhInst, (void*)pObject );
+ if ( hWnd )
+ {
+ hWndChild = CreateWindowExW( 0, SAL_OBJECT_CHILDCLASSNAMEW, L"",
+ WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
+ 0, 0, 0, 0,
+ hWnd, 0,
+ pInst->maInstData.mhInst, NULL );
+ }
+ }
+ else
+ {
+ hWnd = CreateWindowExA( 0, SAL_OBJECT_CLASSNAMEA, "",
+ WS_CHILD, 0, 0, 0, 0,
+ pParent->maFrameData.mhWnd, 0,
+ pInst->maInstData.mhInst, (void*)pObject );
+ if ( hWnd )
+ {
+ hWndChild = CreateWindowExA( 0, SAL_OBJECT_CHILDCLASSNAMEA, "",
+ WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
+ 0, 0, 0, 0,
+ hWnd, 0,
+ pInst->maInstData.mhInst, NULL );
+ }
+ }
+ if ( !hWndChild )
+ {
+ delete pObject;
+ return NULL;
+ }
+
+ if ( hWnd )
+ {
+ pObject->maObjectData.mhWnd = hWnd;
+ pObject->maObjectData.mhWndChild = hWndChild;
+ pObject->maObjectData.maSysData.hWnd = hWndChild;
+ return pObject;
+ }
+ }
+
+ return NULL;
+}
+
+// =======================================================================
+
+long ImplSalObjCallbackDummy( void*, SalObject*, USHORT, const void* )
+{
+ return 0;
+}
+
+// =======================================================================
+
+SalObject::SalObject()
+{
+ SalData* pSalData = GetSalData();
+
+ maObjectData.mhWnd = 0;
+ maObjectData.mhWndChild = 0;
+ maObjectData.mhLastFocusWnd = 0;
+ maObjectData.maSysData.nSize = sizeof( SystemEnvData );
+ maObjectData.mpInst = NULL;
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+ maObjectData.mpStdClipRgnData = NULL;
+
+ // Insert object in objectlist
+ maObjectData.mpNextObject = pSalData->mpFirstObject;
+ pSalData->mpFirstObject = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalObject::~SalObject()
+{
+ SalData* pSalData = GetSalData();
+
+ // remove frame from framelist
+ if ( this == pSalData->mpFirstObject )
+ {
+ pSalData->mpFirstObject = maObjectData.mpNextObject;
+
+ // Wenn letztes SalObject, dann Hook wieder entfernen
+ if ( !pSalData->mpFirstObject )
+ UnhookWindowsHookEx( pSalData->mhSalObjMsgHook );
+ }
+ else
+ {
+ SalObject* pTempObject = pSalData->mpFirstObject;
+ while ( pTempObject->maObjectData.mpNextObject != this )
+ pTempObject = pTempObject->maObjectData.mpNextObject;
+
+ pTempObject->maObjectData.mpNextObject = maObjectData.mpNextObject;
+ }
+
+ // Cache-Daten zerstoeren
+ if ( maObjectData.mpStdClipRgnData )
+ delete maObjectData.mpStdClipRgnData;
+
+ HWND hWndParent = ::GetParent( maObjectData.mhWnd );
+
+ if ( maObjectData.mhWndChild )
+ DestroyWindow( maObjectData.mhWndChild );
+ if ( maObjectData.mhWnd )
+ DestroyWindow( maObjectData.mhWnd );
+
+ // Palette wieder zuruecksetzen, wenn kein externes Child-Fenster
+ // mehr vorhanden ist, da diese unsere Palette ueberschrieben haben
+ // koennen
+ if ( hWndParent &&
+ ::GetActiveWindow() == hWndParent &&
+ !GetWindow( hWndParent, GW_CHILD ) )
+ ImplSendMessage( hWndParent, SAL_MSG_FORCEPALETTE, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::ResetClipRegion()
+{
+ SetWindowRgn( maObjectData.mhWnd, 0, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalObject::GetClipRegionType()
+{
+ return SAL_OBJECT_CLIP_INCLUDERECTS;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::BeginSetClipRegion( ULONG nRectCount )
+{
+ ULONG nRectBufSize = sizeof(RECT)*nRectCount;
+ if ( nRectCount < SAL_CLIPRECT_COUNT )
+ {
+ if ( !maObjectData.mpStdClipRgnData )
+ maObjectData.mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
+ maObjectData.mpClipRgnData = maObjectData.mpStdClipRgnData;
+ }
+ else
+ maObjectData.mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
+ maObjectData.mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
+ maObjectData.mpClipRgnData->rdh.iType = RDH_RECTANGLES;
+ maObjectData.mpClipRgnData->rdh.nCount = nRectCount;
+ maObjectData.mpClipRgnData->rdh.nRgnSize = nRectBufSize;
+ SetRectEmpty( &(maObjectData.mpClipRgnData->rdh.rcBound) );
+ maObjectData.mpNextClipRect = (RECT*)(&(maObjectData.mpClipRgnData->Buffer));
+ maObjectData.mbFirstClipRect = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ RECT* pRect = maObjectData.mpNextClipRect;
+ RECT* pBoundRect = &(maObjectData.mpClipRgnData->rdh.rcBound);
+ long nRight = nX + nWidth;
+ long nBottom = nY + nHeight;
+
+ if ( maObjectData.mbFirstClipRect )
+ {
+ pBoundRect->left = nX;
+ pBoundRect->top = nY;
+ pBoundRect->right = nRight;
+ pBoundRect->bottom = nBottom;
+ maObjectData.mbFirstClipRect = FALSE;
+ }
+ else
+ {
+ if ( nX < pBoundRect->left )
+ pBoundRect->left = (int)nX;
+
+ if ( nY < pBoundRect->top )
+ pBoundRect->top = (int)nY;
+
+ if ( nRight > pBoundRect->right )
+ pBoundRect->right = (int)nRight;
+
+ if ( nBottom > pBoundRect->bottom )
+ pBoundRect->bottom = (int)nBottom;
+ }
+
+ pRect->left = (int)nX;
+ pRect->top = (int)nY;
+ pRect->right = (int)nRight;
+ pRect->bottom = (int)nBottom;
+ maObjectData.mpNextClipRect++;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::EndSetClipRegion()
+{
+ HRGN hRegion;
+
+ // Aus den Region-Daten muessen wir jetzt eine ClipRegion erzeugen
+ if ( maObjectData.mpClipRgnData->rdh.nCount == 1 )
+ {
+ RECT* pRect = &(maObjectData.mpClipRgnData->rdh.rcBound);
+ hRegion = CreateRectRgn( pRect->left, pRect->top,
+ pRect->right, pRect->bottom );
+ }
+ else
+ {
+ ULONG nSize = maObjectData.mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
+ hRegion = ExtCreateRegion( NULL, nSize, maObjectData.mpClipRgnData );
+ if ( maObjectData.mpClipRgnData != maObjectData.mpStdClipRgnData )
+ delete maObjectData.mpClipRgnData;
+ }
+
+ DBG_ASSERT( hRegion, "SalObject::EndSetClipRegion() - Can't create ClipRegion" );
+ SetWindowRgn( maObjectData.mhWnd, hRegion, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
+{
+ ULONG nStyle = 0;
+ BOOL bVisible = (GetWindowStyle( maObjectData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( bVisible )
+ {
+ ShowWindow( maObjectData.mhWnd, SW_HIDE );
+ nStyle |= SWP_SHOWWINDOW;
+ }
+ SetWindowPos( maObjectData.mhWnd, 0,
+ (int)nX, (int)nY, (int)nWidth, (int)nHeight,
+ SWP_NOZORDER | SWP_NOACTIVATE | nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::Show( BOOL bVisible )
+{
+ if ( bVisible )
+ ShowWindow( maObjectData.mhWnd, SW_SHOWNORMAL );
+ else
+ ShowWindow( maObjectData.mhWnd, SW_HIDE );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::Enable( BOOL bEnable )
+{
+ EnableWindow( maObjectData.mhWnd, bEnable );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::GrabFocus()
+{
+ if ( maObjectData.mhLastFocusWnd &&
+ IsWindow( maObjectData.mhLastFocusWnd ) &&
+ ImplIsSysWindowOrChild( maObjectData.mhWndChild, maObjectData.mhLastFocusWnd ) )
+ ::SetFocus( maObjectData.mhLastFocusWnd );
+ else
+ ::SetFocus( maObjectData.mhWndChild );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground( SalColor nSalColor )
+{
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* SalObject::GetSystemData() const
+{
+ return &maObjectData.maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc )
+{
+ maObjectData.mpInst = pInst;
+ if ( pProc )
+ maObjectData.mpProc = pProc;
+ else
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+}
diff --git a/vcl/workben/makefile.mk b/vcl/workben/makefile.mk
new file mode 100644
index 000000000000..a12a98182174
--- /dev/null
+++ b/vcl/workben/makefile.mk
@@ -0,0 +1,151 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:05:50 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=SV
+TARGET=svdem
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= svdem.cxx
+
+OBJFILES= $(OBJ)$/svdem.obj
+
+APP1NOSAL= TRUE
+APP1TARGET= $(TARGET)
+APP1OBJS= $(OBJFILES) \
+ $(OBJ)$/salmain.obj
+
+APP1STDLIBS= $(CPPULIB) \
+ $(TOOLSLIB) \
+ $(SALLIB) \
+ $(VOSLIB) \
+ $(SOTLIB) \
+ $(SVLIB)
+
+APP1DEPN= $(L)$/itools.lib \
+ $(L)$/sot.lib
+
+.IF "$(GUI)"=="WIN" || "$(GUI)"=="OS2"
+APP1DEF= $(MISC)$/$(TARGET).def
+.ENDIF
+
+.IF "$(remote)"!=""
+EXCEPTIONSFILES=$(OBJ)$/svdem.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+#svdem.cxx: $(I)tools.hxx $(I)svgen.hxx $(I)svwindow.hxx \
+# $(I)sv.hxx
+
+# ------------------------------------------------------------------
+# Windows
+# ------------------------------------------------------------------
+
+.IF "$(GUI)" == "WIN"
+
+$(MISC)$/$(TARGET).def: makefile
+ echo NAME $(TARGET) >$@
+ echo DESCRIPTION 'StarView - Testprogramm' >>$@
+ echo EXETYPE WINDOWS >>$@
+ echo STUB 'winSTUB.EXE' >>$@
+ echo PROTMODE >>$@
+ echo CODE PRELOAD MOVEABLE DISCARDABLE >>$@
+ echo DATA PRELOAD MOVEABLE MULTIPLE >>$@
+ echo HEAPSIZE 8192 >>$@
+ echo STACKSIZE 32768 >>$@
+
+.ENDIF
+
+# ------------------------------------------------------------------
+# OS2
+# ------------------------------------------------------------------
+
+.IF "$(GUI)" == "OS2"
+
+$(MISC)$/$(TARGET).def: makefile
+ echo NAME $(TARGET) WINDOWAPI >$@
+ echo DESCRIPTION 'StarView - Testprogramm' >>$@
+.IF "$(COM)" != "BLC"
+ echo STUB 'os2STUB.EXE' >>$@
+.ENDIF
+.IF "$(COM)"!="MTW"
+ echo EXETYPE OS2 >>$@
+.ENDIF
+ echo PROTMODE >>$@
+ echo CODE LOADONCALL >>$@
+ echo DATA PRELOAD MULTIPLE >>$@
+ echo HEAPSIZE 16384 >>$@
+ echo STACKSIZE 32768 >>$@
+
+.ENDIF
diff --git a/vcl/workben/svdem.cxx b/vcl/workben/svdem.cxx
new file mode 100644
index 000000000000..db5666d21bbb
--- /dev/null
+++ b/vcl/workben/svdem.cxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * $RCSfile: svdem.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:50 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include <event.hxx>
+#include <svapp.hxx>
+#include <wrkwin.hxx>
+#include <msgbox.hxx>
+
+// -----------------------------------------------------------------------
+
+class MyApp : public Application
+{
+public:
+ void Main();
+};
+
+MyApp aMyApp;
+
+// -----------------------------------------------------------------------
+
+class MyWin : public WorkWindow
+{
+public:
+ MyWin( Window* pParent, WinBits nWinStyle );
+
+ void MouseMove( const MouseEvent& rMEvt );
+ void MouseButtonDown( const MouseEvent& rMEvt );
+ void MouseButtonUp( const MouseEvent& rMEvt );
+ void KeyInput( const KeyEvent& rKEvt );
+ void KeyUp( const KeyEvent& rKEvt );
+ void Paint( const Rectangle& rRect );
+ void Resize();
+};
+
+// -----------------------------------------------------------------------
+
+void MyApp::Main()
+{
+ MyWin aMainWin( NULL, WB_APP | WB_STDWORK );
+ aMainWin.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "VCL - Workbench" ) ) );
+ aMainWin.Show();
+
+ Execute();
+}
+
+// -----------------------------------------------------------------------
+
+MyWin::MyWin( Window* pParent, WinBits nWinStyle ) :
+ WorkWindow( pParent, nWinStyle )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void MyWin::MouseMove( const MouseEvent& rMEvt )
+{
+ WorkWindow::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MyWin::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ WorkWindow::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MyWin::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ WorkWindow::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MyWin::KeyInput( const KeyEvent& rKEvt )
+{
+ WorkWindow::KeyInput( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MyWin::KeyUp( const KeyEvent& rKEvt )
+{
+ WorkWindow::KeyUp( rKEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MyWin::Paint( const Rectangle& rRect )
+{
+ WorkWindow::Paint( rRect );
+}
+
+// -----------------------------------------------------------------------
+
+void MyWin::Resize()
+{
+ WorkWindow::Resize();
+}